#if AR_FOUNDATION_PRESENT using UnityEngine.XR.ARSubsystems; using UnityEngine.XR.ARFoundation; using UnityEngine.XR.Interaction.Toolkit.Samples.StarterAssets; namespace UnityEngine.XR.Interaction.Toolkit.Samples.ARStarterAssets { /// /// Spawns an object on physics trigger enter with an , at the point of contact on the plane. /// [RequireComponent(typeof(Rigidbody))] public class ARContactSpawnTrigger : MonoBehaviour { [SerializeField] [Tooltip("The behavior to use to spawn objects.")] ObjectSpawner m_ObjectSpawner; /// /// The behavior to use to spawn objects. /// public ObjectSpawner objectSpawner { get => m_ObjectSpawner; set => m_ObjectSpawner = value; } [SerializeField] [Tooltip("Whether to require that the AR Plane has an alignment of horizontal up to spawn on it.")] bool m_RequireHorizontalUpSurface; /// /// Whether to require that the has an alignment of to spawn on it. /// public bool requireHorizontalUpSurface { get => m_RequireHorizontalUpSurface; set => m_RequireHorizontalUpSurface = value; } /// /// See . /// void Start() { if (m_ObjectSpawner == null) #if UNITY_2023_1_OR_NEWER m_ObjectSpawner = FindAnyObjectByType(); #else m_ObjectSpawner = FindObjectOfType(); #endif } /// /// See . /// void OnTriggerEnter(Collider other) { if (!TryGetSpawnSurfaceData(other, out var surfacePosition, out var surfaceNormal)) return; var infinitePlane = new Plane(surfaceNormal, surfacePosition); var contactPoint = infinitePlane.ClosestPointOnPlane(transform.position); m_ObjectSpawner.TrySpawnObject(contactPoint, surfaceNormal); } /// /// Tries to get the surface position and normal from an object to potentially spawn on. /// /// The collider of the object to potentially spawn on. /// The potential world position of the spawn surface. /// The potential normal of the spawn surface. /// Returns if is a valid spawn surface, /// otherwise returns . public bool TryGetSpawnSurfaceData(Collider objectCollider, out Vector3 surfacePosition, out Vector3 surfaceNormal) { surfacePosition = default; surfaceNormal = default; var arPlane = objectCollider.GetComponent(); if (arPlane == null) return false; if (m_RequireHorizontalUpSurface && arPlane.alignment != PlaneAlignment.HorizontalUp) return false; surfaceNormal = arPlane.normal; surfacePosition = arPlane.center; return true; } } } #endif