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.
public class ObjectManipulator : MonoBehaviour
{
private float initialFingersDistance;
private Vector3 initialScale;
private Camera cam;
private GameObject curSelected;
private List<GameObject> objectList = new List<GameObject>();
void Start()
{
cam = Camera.main;
}
void Update()
{
if (Input.touchCount > 0 && Input.touches[0].phase == TouchPhase.Began)
{
Ray ray = cam.ScreenPointToRay(Input.touches[0].position);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.gameObject != null && hit.transform.name.Contains("ExamplePicture"))
{
if (curSelected != null && hit.collider.gameObject != curSelected)
{
Select(hit.collider.gameObject);
}
else if (curSelected == null)
{
Select(hit.collider.gameObject);
}
}
else
{
Deselect();
}
}
}
if (curSelected != null && Input.touchCount > 0 && Input.touches[0].phase == TouchPhase.Moved)
{
Ray ray = cam.ScreenPointToRay(Input.touches[0].position);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.gameObject != null && hit.transform.name.Contains("ExamplePicture"))
{
MoveSelected();
}
}
}
}
///Activate 'Selected' Material
void Select(GameObject selected)
{
Debug.Log(selected.name);
if (curSelected != null)
{
ToggleSelectionVisual(curSelected, false);
}
curSelected = selected;
ToggleSelectionVisual(curSelected, true);
}
void Deselect()
{
if (curSelected != null)
{
ToggleSelectionVisual(curSelected, false);
}
curSelected = null;
}
void ToggleSelectionVisual(GameObject obj, bool toggle)
{
obj.transform.Find("Selected").gameObject.SetActive(toggle);
}
}
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:
void MoveSelected()
{
Vector3 curPos = cam.ScreenToViewportPoint(Input.touches[0].position);
Vector3 lastPos = cam.ScreenToViewportPoint(Input.touches[0].position - Input.touches[0].deltaPosition);
Vector3 touchDir = curPos - lastPos;
Vector3 camRight = cam.transform.right;
camRight.z = 0;
camRight.Normalize();
Vector3 camUp = cam.transform.up;
camUp.z = 0;
camUp.Normalize();
curSelected.transform.position += (camRight * touchDir.x + camUp * touchDir.y);
}
I tried to get the rotation information from the vertical plane and apply it on the object when moving:
private GameObject verticalPlane;
void Start()
{
verticalPlane = GameObject.Find("VerticalPlane");
cam = Camera.main;
}
void MoveSelected()
{
...
curSelected.transform.position += (camRight * touchDir.x + camUp * touchDir.y);
curSelected.transform.rotation = verticalPlane.transform.rotation;
}
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