using System.Collections.Generic; using UnityEngine; using UnityEngine.XR.ARFoundation; using UnityEngine.XR.ARSubsystems; /// /// Moves the ARSessionOrigin in such a way that it makes the given content appear to be /// at a given location acquired via a raycast. /// [RequireComponent(typeof(ARSessionOrigin))] [RequireComponent(typeof(ARRaycastManager))] public class MakeAppearOnPlane : MonoBehaviour { [SerializeField] [Tooltip("A transform which should be made to appear to be at the touch point.")] Transform m_Content; /// /// A transform which should be made to appear to be at the touch point. /// public Transform content { get { return m_Content; } set { m_Content = value; } } [SerializeField] [Tooltip("The rotation the content should appear to have.")] Quaternion m_Rotation; /// /// The rotation the content should appear to have. /// public Quaternion rotation { get { return m_Rotation; } set { m_Rotation = value; if (m_SessionOrigin != null) m_SessionOrigin.MakeContentAppearAt(content, content.transform.position, m_Rotation); } } void Awake() { m_SessionOrigin = GetComponent(); m_RaycastManager = GetComponent(); } void Update() { if (Input.touchCount == 0 || m_Content == null) return; var touch = Input.GetTouch(0); if (m_RaycastManager.Raycast(touch.position, s_Hits, TrackableType.PlaneWithinPolygon)) { // Raycast hits are sorted by distance, so the first one // will be the closest hit. var hitPose = s_Hits[0].pose; // This does not move the content; instead, it moves and orients the ARSessionOrigin // such that the content appears to be at the raycast hit position. m_SessionOrigin.MakeContentAppearAt(content, hitPose.position, m_Rotation); } } static List s_Hits = new List(); ARSessionOrigin m_SessionOrigin; ARRaycastManager m_RaycastManager; }