using System.Collections.Generic; using UnityEngine; using UnityEngine.XR.ARFoundation; using UnityEngine.XR.ARSubsystems; namespace UnityEngine.XR.ARFoundation.Samples { /// /// Listens for touch events and performs an AR raycast from the screen touch point. /// AR raycasts will only hit detected trackables like feature points and planes. /// /// If a raycast hits a trackable, the is instantiated /// and moved to the hit position. /// [RequireComponent(typeof(ARRaycastManager))] public class PlaceOnPlane : MonoBehaviour { [SerializeField] [Tooltip("Instantiates this prefab on a plane at the touch location.")] GameObject m_PlacedPrefab; /// /// The prefab to instantiate on touch. /// public GameObject placedPrefab { get { return m_PlacedPrefab; } set { m_PlacedPrefab = value; } } /// /// The object instantiated as a result of a successful raycast intersection with a plane. /// public GameObject spawnedObject { get; private set; } void Awake() { m_RaycastManager = GetComponent(); } bool TryGetTouchPosition(out Vector2 touchPosition) { if (Input.touchCount > 0) { touchPosition = Input.GetTouch(0).position; return true; } touchPosition = default; return false; } void Update() { if (!TryGetTouchPosition(out Vector2 touchPosition)) return; if (m_RaycastManager.Raycast(touchPosition, 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; if (spawnedObject == null) { spawnedObject = Instantiate(m_PlacedPrefab, hitPose.position, hitPose.rotation); } else { spawnedObject.transform.position = hitPose.position; } } } static List s_Hits = new List(); ARRaycastManager m_RaycastManager; } }