x


Moving an object onto exact mouse position using transform.position, including drag area restrictions?

Hello there,

my situation: I get the mouse position in 3D space while dragging the object, and it should move to this position. The script works very well so far, but it doesn't include collisions with my 4 walls. ( The scene is a small room ) I like the result I get with this script, so rigidbodys and physics do not come into question. Besides, I already tried that with the help of user Tylo. Old question here

Complete Drag script:

var planeNormal : Vector3 = Vector3( 0, 1, 0 );
var currentProjectedOnPlaneNormal : float;
var cameraProjectedOnPlaneNormal : float;
var wantedDistanceFromCamera : float;
var pOnPlaneNormal : float;
private var rememberedYPos: float;

function OnMouseDown ()
{
// An extra hack: If Up is (0,1,0), then we remember the y-coordinate, so we don't change it
rememberedYPos = transform.position.y;
}

function OnMouseDrag () 
{
  Drag();
}

function FindCamera ()
{
  if (camera)
  return camera;
  else
  return Camera.main;
}

function Drag()
{
var p: Vector3;

var mainCamera = FindCamera();   
// Position on the near clipping plane of the camera in world space
p = mainCamera.ScreenToWorldPoint(Vector3(Input.mousePosition.x,Input.mousePosition.y, mainCamera.nearClipPlane));
// Position relative to the eye-point of the camera
p -= mainCamera.transform.position;

currentProjectedOnPlaneNormal = Vector3.Dot( planeNormal, transform.position );
cameraProjectedOnPlaneNormal = Vector3.Dot( planeNormal, mainCamera.transform.position );
wantedDistanceFromCamera = cameraProjectedOnPlaneNormal - currentProjectedOnPlaneNormal;        
pOnPlaneNormal = Vector3.Dot( planeNormal, p );

p *= wantedDistanceFromCamera / -pOnPlaneNormal;
p += mainCamera.transform.position;
transform.position = p;

// If we know that the object should only move in its x,z coordinates, we can
// make sure we don't drift slowly off the plane by doing this:
transform.position.y = rememberedYPos; 
}

Is it possible to set a "drag area" so I can't drag out of the room? I thought of something like this: Room picture

Because the object will later be rotated, it would be great if the individual vertices could be read... so no vertice could get out of the room area. Is there a way to get this working? Thanks in advance for your time

Edit

I calculate a distance from each of the object corners to the room walls. Is the object been dragged out of the room, I substract the distance, to get it back to the desired drag area. This isn't working with rotation so far. For example, with a cube:

private var PointUpperLeft : Vector3;
private var calculatepoints : boolean = false;
private var NorthWall : float;

function Awake ()
{
  NorthWall = GameObject.Find("Room").transform.localScale.z / 2;
  //this gives me the max z position at the north side of my ground
}

function Update ()
{
    if ( calculatepoints == true )
    {
        PointUpperLeft = Vector3( transform.position.x - (transform.localScale.x / 2), rememberedYPos, transform.position.z + (transform.localScale.z / 2) );
    //this gives me the upper left corner of my object, calculated from the middle (square)
}

    if ( ( PointUpperLeft.z > NorthWall )
    {
        var dist = PointUpperLeft.z - NorthWall;
        print ("Distance exceeded to NorthWall " + dist);
    //substract excess position
        transform.position.z = transform.position.z - dist;
    //new position of the Point
        PointUpperLeft = Vector3( transform.position.x - (transform.localScale.x / 2), rememberedYPos, transform.position.z + (transform.localScale.z / 2) );
}

function OnMouseDrag () 
{
  Drag();
  calculatepoints = true;
}

function OnMouseUp ()
{
  calculatepoints = false;
}
more ▼

asked Aug 28 '10 at 12:48 PM

Baroni gravatar image

Baroni
15 3 3 10

(comments are locked)
10|3000 characters needed characters left

1 answer: sort voted first

I typically do this with Triggers or Colliders, but you mentioned you wanted to keep rigidbodies out of the picture, yes? I believe even triggers require a rigidbody component.

If your room is perfectly square, then it is simple to limit your drag area. You simply store the values you want to limit, and continually limit them like you do your y-value (but only when you have gone past their limit).

if(transform.x > xLimit)
    transform.x = xLimit;

if(transform.z > zLimit)
    transform.z = zLimit;

However, that won't stop things like the square from sticking out into the wall, etc. As the object's transform.position is the center of the object.

I would recommend you still use a rigidbody & invisible colliders to deal with these complex collisions. You can limit how the rigidbody works. You can shut off gravity, make it kinematic, and prevent rotations through physics.

See if that gives you the best of both worlds. If you'd like a run-through on the anatomy of a rigidbody, you can visit a tutorial I wrote here: Rigidbodies Revisited

Also, here is the Docs on Rigidbodies from Unity. Worth a read: Rigidbody Component

more ▼

answered Aug 28 '10 at 04:19 PM

tylo gravatar image

tylo
297 5 9 18

Thanks Tylo, I read your rigidbody section! I am using a distance variable to limit the area if I drag a part of the object out of the room. I've updated my question with an example code. You deserve your check for pointing me the right direction

Aug 30 '10 at 02:26 AM Baroni
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x5049
x2070
x286
x138

asked: Aug 28 '10 at 12:48 PM

Seen: 3973 times

Last Updated: Aug 30 '10 at 11:00 AM