Search Unity

Question ARFoundation - Dragging GameObject but keep it fixed on vertical plane & within plane boundary

Discussion in 'AR/VR (XR) Discussion' started by dstckln, May 25, 2020.

  1. dstckln

    dstckln

    Joined:
    Apr 3, 2020
    Posts:
    4
    I am new to Unity/AR and im currently working on an app to augment pictures on a vertical plane. On app start a placement indicator is shown to the user and on tap my vertical plane object will be placed. In Unity it looks like this:


    Once the vertical plane is placed, the user is able to put an object on the plane. The placed object can be selected and dragged on touch - so far everything works fine.

    However, i want the object to 'sit' on top of the plane & keep it within the plane boundary, while dragging. As of right now, the object will move behind the plane when dragging.

    This is a screenshot from the running app - vertical plane & object are placed:


    After the object has been moved:


    This is my ObjectManipulator.cs class which is a component of AR Camera in Unity. My approach on this was basically to raycast on my ExamplePicture prefab, select it and then be able to move it around.
    Code (CSharp):
    1. public class ObjectManipulator : MonoBehaviour
    2. {
    3.     private float initialFingersDistance;
    4.     private Vector3 initialScale;
    5.     private Camera cam;
    6.     private GameObject curSelected;
    7.     private List<GameObject> objectList = new List<GameObject>();
    8.  
    9.     void Start()
    10.     {
    11.         cam = Camera.main;
    12.     }
    13.  
    14.     void Update()
    15.     {
    16.         if (Input.touchCount > 0 && Input.touches[0].phase == TouchPhase.Began)
    17.         {
    18.             Ray ray = cam.ScreenPointToRay(Input.touches[0].position);
    19.             RaycastHit hit;
    20.  
    21.             if (Physics.Raycast(ray, out hit))
    22.             {
    23.                 if (hit.collider.gameObject != null && hit.transform.name.Contains("ExamplePicture"))
    24.                 {
    25.                     if (curSelected != null && hit.collider.gameObject != curSelected)
    26.                     {
    27.                         Select(hit.collider.gameObject);
    28.                     }
    29.                     else if (curSelected == null)
    30.                     {
    31.                         Select(hit.collider.gameObject);
    32.                     }
    33.                 }
    34.                 else
    35.                 {
    36.                     Deselect();
    37.                 }
    38.             }
    39.         }
    40.  
    41.         if (curSelected != null && Input.touchCount > 0 && Input.touches[0].phase == TouchPhase.Moved)
    42.         {
    43.             Ray ray = cam.ScreenPointToRay(Input.touches[0].position);
    44.             RaycastHit hit;
    45.             if (Physics.Raycast(ray, out hit))
    46.             {
    47.                 if (hit.collider.gameObject != null && hit.transform.name.Contains("ExamplePicture"))
    48.                 {
    49.                     MoveSelected();
    50.                 }
    51.             }
    52.         }
    53.     }
    54.  
    55.     ///Activate 'Selected' Material
    56.     void Select(GameObject selected)
    57.     {
    58.         Debug.Log(selected.name);
    59.         if (curSelected != null)
    60.         {
    61.             ToggleSelectionVisual(curSelected, false);
    62.         }
    63.         curSelected = selected;
    64.         ToggleSelectionVisual(curSelected, true);
    65.     }
    66.  
    67.     void Deselect()
    68.     {
    69.         if (curSelected != null)
    70.         {
    71.             ToggleSelectionVisual(curSelected, false);
    72.         }
    73.         curSelected = null;
    74.     }
    75.  
    76.     void ToggleSelectionVisual(GameObject obj, bool toggle)
    77.     {
    78.         obj.transform.Find("Selected").gameObject.SetActive(toggle);
    79.     }
    80. }
    Once the ExamplePicture is selected, my MoveSelected Method will be called to move objects. As of right now, the object will only move up & down and left & right:

    Code (CSharp):
    1. void MoveSelected()
    2.     {
    3.         Vector3 curPos = cam.ScreenToViewportPoint(Input.touches[0].position);
    4.         Vector3 lastPos = cam.ScreenToViewportPoint(Input.touches[0].position - Input.touches[0].deltaPosition);
    5.         Vector3 touchDir = curPos - lastPos;
    6.  
    7.         Vector3 camRight = cam.transform.right;
    8.         camRight.z = 0;
    9.         camRight.Normalize();
    10.  
    11.         Vector3 camUp = cam.transform.up;
    12.         camUp.z = 0;
    13.         camUp.Normalize();
    14.  
    15.         curSelected.transform.position += (camRight * touchDir.x + camUp * touchDir.y);
    16.     }
    I tried to get the rotation information from the vertical plane and apply it on the object when moving:

    Code (CSharp):
    1. private GameObject verticalPlane;
    2.  
    3.     void Start()
    4.     {
    5.         verticalPlane = GameObject.Find("VerticalPlane");
    6.         cam = Camera.main;
    7.     }
    8.  
    9.     void MoveSelected()
    10.     {
    11.         ...
    12.         curSelected.transform.position += (camRight * touchDir.x + camUp * touchDir.y);
    13.         curSelected.transform.rotation = verticalPlane.transform.rotation;
    14.     }
    That did not work - the object will still move behind the plane. I feel like I am missing/misunderstanding some fundamental concept or something.

    I hope i could explain my problem in an understandable way and im looking forward for replies.

    Thanks
     
  2. dstckln

    dstckln

    Joined:
    Apr 3, 2020
    Posts:
    4
    no one?
     
  3. arfish

    arfish

    Joined:
    Jan 28, 2017
    Posts:
    782
    Hi,

    Have you tried to make the draggable object a child of the plane?
    Then it could be moved relative to the plane by just changing the local position, or rotation.
     
  4. dstckln

    dstckln

    Joined:
    Apr 3, 2020
    Posts:
    4
    @arfish Thank you, yea i actually figured that out - i was thinking about this way to complicated.
    However, the dragging is not very intuitive and i would like to make it more smooth.
    Thats my method for dragging:
    Code (CSharp):
    1.    
    2. void MoveSelected()
    3.     {
    4.         Vector3 curPos = cam.ScreenToViewportPoint(Input.touches[0].position);
    5.         Vector3 lastPos = cam.ScreenToViewportPoint(Input.touches[0].position - Input.touches[0].deltaPosition);
    6.         Vector3 touchDir = curPos - lastPos;
    7.  
    8.         touchDir.z = 0;
    9.  
    10.         curSelected.transform.position += verticalPlane.transform.TransformDirection(touchDir);
    11.     }
    12.  
    Any suggestions?
     
  5. arfish

    arfish

    Joined:
    Jan 28, 2017
    Posts:
    782
  6. dstckln

    dstckln

    Joined:
    Apr 3, 2020
    Posts:
    4
    @arfish Thank you again! :)
    I was trying to get the touch position from the screen touch to world point. Then lerp and set the position of the current object to that of the touch, but smoothly over time. But i couldnt quite manage to make it work as i want it to be. On Touch the picture occupied the whole - maybe you can go into more detail on how to use ScreenToWorldPoint, i would greatly appreciate it!
     
  7. arfish

    arfish

    Joined:
    Jan 28, 2017
    Posts:
    782
    I guess it's all about applying some just enough thinking. ;)
    What was you aiming at, and how did the result differ from what you want it to be.
    Sometimes it's just about fine tuning to get to the sweet spot, and sometimes it's better to find another approach.
     
  8. Sakuwwz

    Sakuwwz

    Joined:
    Nov 5, 2018
    Posts:
    50
    Hi @dtsckln, would you mind explaining to me how do you create your own custom plane to detect an AR plane and instantiate objects in there?
     
  9. Sakuwwz

    Sakuwwz

    Joined:
    Nov 5, 2018
    Posts:
    50
    ANYBODY???