using System.Collections.Generic; using UnityEngine; using UnityEngine.XR.ARFoundation; using UnityEngine.XR.ARSubsystems; namespace UnityEngine.XR.ARFoundation.Samples { [RequireComponent(typeof(ARAnchorManager))] [RequireComponent(typeof(ARRaycastManager))] public class AnchorCreator : MonoBehaviour { public void RemoveAllAnchors() { Logger.Log($"Removing all anchors ({m_Anchors.Count})"); foreach (var anchor in m_Anchors) { m_AnchorManager.RemoveAnchor(anchor); } m_Anchors.Clear(); } void Awake() { m_RaycastManager = GetComponent(); m_AnchorManager = GetComponent(); } ARAnchor CreateAnchor(in ARRaycastHit hit) { // If we hit a plane, try to "attach" the anchor to the plane if (hit.trackable is ARPlane plane) { var planeManager = GetComponent(); if (planeManager) { Logger.Log("Creating anchor attachment."); return m_AnchorManager.AttachAnchor(plane, hit.pose); } } // Otherwise, just create a regular anchor at the hit pose Logger.Log("Creating regular anchor."); return m_AnchorManager.AddAnchor(hit.pose); } void Update() { if (Input.touchCount == 0) return; var touch = Input.GetTouch(0); if (touch.phase != TouchPhase.Began) return; // Raycast against planes and feature points const TrackableType trackableTypes = TrackableType.FeaturePoint | TrackableType.PlaneWithinPolygon; // Perform the raycast if (m_RaycastManager.Raycast(touch.position, s_Hits, trackableTypes)) { // Raycast hits are sorted by distance, so the first one will be the closest hit. var hit = s_Hits[0]; // Create a new anchor var anchor = CreateAnchor(hit); if (anchor) { // Remember the anchor so we can remove it later. m_Anchors.Add(anchor); } else { Logger.Log("Error creating anchor"); } } } static List s_Hits = new List(); List m_Anchors = new List(); ARRaycastManager m_RaycastManager; ARAnchorManager m_AnchorManager; } }