Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Dragging Objects on a plane

Discussion in 'Scripting' started by yangmeng, Jul 2, 2007.

  1. yangmeng

    yangmeng

    Joined:
    Dec 5, 2006
    Posts:
    573
    I am having trouble getting good results doing something that seems as though it should be pretty simple - use the mouse drag an object across a plane.
    I am using OnMouseDrag but the object is not keeping up with the mouse. Is there a sample script somewhere on how to do this right?
    Thanks
     
  2. pete

    pete

    Joined:
    Jul 21, 2005
    Posts:
    1,647
    are you slerping the objects position? setting it simply to equals instead might do it.
     
  3. Willem

    Willem

    Joined:
    Mar 9, 2007
    Posts:
    184
    Well, depending on what screen res you're using and what your viewing angle is the odds are very good that a unit of mouse drag isn't going to equal a single unit in the game world. I don't think it's ever going to be possible to get a 1-to-1 match unless you use screen traces from the mouse into the world or something like that.
     
  4. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,777
    You could try putting the code in LateUpdate instead of Update.
     
  5. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Intuitively it seems simple, but programatically it's actually not that simple. I've used raycasting to a plane to get the distance, but a more "correct" solution can be found in Carsten's code here.

    --Eric
     
  6. yangmeng

    yangmeng

    Joined:
    Dec 5, 2006
    Posts:
    573
    Thanks for all of your responses. I am trying Carsten's script and have been convinced by it that dragging an object with the mouse is not so simple as I thought it should be.
    Two problems I am having:
    1. I need the object's "Z distance from camera" to be decided by gravity so that the object stays on the plane and
    2. I need the object to still interact with other objects so that it doesn't just go right through things but stops when it meets and obstacle

    I have messed with the script some to try to do this, but my mind is having trouble with just understanding that one variable - "p" - can hold the x, y and z axis the way it does.
    Is there a way to do the above (1 2) with Carsten's script?
    Here it is for easy reference:
    Code (csharp):
    1. var wantedZDistanceFromCamera = 5.0;
    2.  
    3. function OnMouseDrag () {
    4.  
    5.    var mainCamera = FindCamera();    
    6.    // Position on the near clipping plane of the camera in world space
    7.    var p = mainCamera.ScreenToWorldPoint(Vector3(Input.mousePosition.x, Input.mousePosition.y, 0));
    8.    // Position relative to the eye-point of the camera
    9.    p -= mainCamera.transform.position;
    10.    // A relative position at the wanted z distance from the camera
    11.    var currentZDistanceFromCamera : float = Vector3.Dot(mainCamera.transform.forward, p );
    12.    p *= wantedZDistanceFromCamera / currentZDistanceFromCamera;
    13.    // The position in world space
    14.    p += mainCamera.transform.position;
    15.    
    16.    transform.position = p;    
    17.    
    18. }
    19.  
    20. function FindCamera ()
    21. {
    22.    if (camera)
    23.       return camera;
    24.    else
    25.       return Camera.main;
    26. }
     
  7. cblarsen

    cblarsen

    Joined:
    Mar 10, 2007
    Posts:
    266
    I have made a new version of the script. It makes some assumptions about what you are trying to do.

    - The direction you don't want things to move, is the y-axis
    - You are more or less "looking down" on the plane. It doesn't have to be straight down. Just more down than up.

    This should solve your first problem. About the collision stuff, I hope someone less sleepy than me can help you do that. It has to do with attaching colliders to objects, and finding the proper way to reach to collisions. For example the hook functions OnCollisionEnter/OnCollisionStay

    Hope the script works for you. It works on my machine :)


    Code (csharp):
    1.  
    2. // Which way is "Up" ? We don't want to be moving "up" or "down"
    3. var planeNormal : Vector3 = Vector3( 0, 1, 0 );
    4.  
    5. var currentProjectedOnPlaneNormal : float;
    6. var cameraProjectedOnPlaneNormal : float;
    7. var wantedDistanceFromCamera : float;
    8.  
    9. var pOnPlaneNormal : float;
    10.  
    11. private var rememberedYPos: float;
    12.  
    13. function OnMouseDown () {
    14.     // An extra hack: If Up is (0,1,0), then we remember the y-coordinate, so we don't change it
    15.     rememberedYPos = transform.position.y;
    16. }
    17.  
    18. function OnMouseDrag () {
    19.     var p: Vector3;
    20.  
    21.    var mainCamera = FindCamera();  
    22.    // Position on the near clipping plane of the camera in world space
    23.    p = mainCamera.ScreenToWorldPoint(Vector3(Input.mousePosition.x, Input.mousePosition.y, 0));
    24.    // Position relative to the eye-point of the camera
    25.    p -= mainCamera.transform.position;
    26.  
    27.    
    28.    currentProjectedOnPlaneNormal = Vector3.Dot( planeNormal, transform.position );
    29.    cameraProjectedOnPlaneNormal = Vector3.Dot( planeNormal, mainCamera.transform.position );
    30.    wantedDistanceFromCamera = cameraProjectedOnPlaneNormal - currentProjectedOnPlaneNormal;
    31.  
    32.    pOnPlaneNormal = Vector3.Dot( planeNormal, p );
    33.    
    34.    p *= wantedDistanceFromCamera / -pOnPlaneNormal;
    35.    p += mainCamera.transform.position;
    36.    transform.position = p;
    37.    // If we know that the object should only move in its x,z coordinates, we can
    38.    // make sure we don't drift slowly off the plane by doing this:
    39.  
    40.    transform.position.y = rememberedYPos;  
    41.    
    42. }
    43.  
    44. function FindCamera ()
    45. {
    46.    if (camera)
    47.       return camera;
    48.    else
    49.       return Camera.main;
    50. }
     
  8. yangmeng

    yangmeng

    Joined:
    Dec 5, 2006
    Posts:
    573
    Thank you, Carsten! Will this make my game start growing trees, too? :) You know, it wasn't so long ago, I was impressed with just making an object move across a surface using scripting in Unity. I've come a little bit beyond that but there's still a whole other world out there well beyond my ken. Thanks for a glimpse of it...
    I'll try this script out soon.
     
  9. cblarsen

    cblarsen

    Joined:
    Mar 10, 2007
    Posts:
    266
    Nah, you would just use them for shooting arrows at, anyway. :wink:
     
  10. yangmeng

    yangmeng

    Joined:
    Dec 5, 2006
    Posts:
    573
    Yep, as far as dragging it on a plane it works perfect now. I'll see what I can come up with for adding collsion reactions. Thanks again!
     
  11. JayadevHaddadi

    JayadevHaddadi

    Joined:
    Nov 9, 2020
    Posts:
    12
    In 2023 for those who are still searching:


    Code (CSharp):
    1.  
    2.                 private void OnMouseDrag()
    3.                 {
    4.  
    5.                 var dragPlane = new Plane(dragPlaneTransform.up, dragPlaneTransform.position);
    6.                 Ray ray = playerCamera.ScreenPointToRay(Input.mousePosition);
    7.                 float enter;
    8.  
    9.                 if (dragPlane.Raycast(ray, out enter))
    10.                 {
    11.                     //Get the point that is clicked
    12.                     Vector3 hitPoint = ray.GetPoint(enter);
    13.  
    14.                     //Move your cube GameObject to the point where you clicked
    15.                     transform.position = hitPoint;
    16.                 }
     
    OmicronPerseiB likes this.
  12. OmicronPerseiB

    OmicronPerseiB

    Joined:
    Dec 9, 2021
    Posts:
    1
    This worked perfectly for me, thank you
     
    AFDFDF and JayadevHaddadi like this.