Created
July 13, 2023 20:34
-
-
Save dilmerv/03b4921907922e3333b33864667863b4 to your computer and use it in GitHub Desktop.
AnchorCreatorV2.cs - For AR Foundation With Meta OpenXR Support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using Unity.XR.CoreUtils; | |
using UnityEngine.InputSystem; | |
using UnityEngine.XR.ARSubsystems; | |
namespace UnityEngine.XR.ARFoundation.Samples | |
{ | |
[RequireComponent(typeof(ARAnchorManager))] | |
[RequireComponent(typeof(ARRaycastManager))] | |
public class AnchorCreatorV2 : MonoBehaviour | |
{ | |
[SerializeField] | |
[Tooltip("The Input Action References to use. You can create this by right clicking in the Project Window " + | |
"and going to <b>XR</b> > AR Foundation > Input Action References.")] | |
InputActionReferences m_InputActionReferences; | |
[SerializeField] | |
[Tooltip("The type of trackable the raycast will hit.")] | |
TrackableType m_TrackableType = TrackableType.PlaneWithinPolygon; | |
static Ray s_RaycastRay; | |
static readonly List<ARRaycastHit> s_Hits = new(); | |
readonly List<ARAnchor> m_Anchors = new(); | |
ARRaycastManager m_RaycastManager; | |
ARAnchorManager m_AnchorManager; | |
[SerializeField] | |
GameObject m_Prefab; | |
public GameObject prefab | |
{ | |
get => m_Prefab; | |
set => m_Prefab = value; | |
} | |
public void RemoveAllAnchors() | |
{ | |
Logger.Log($"Removing all anchors ({m_Anchors.Count})"); | |
foreach (var anchor in m_Anchors) | |
{ | |
// It's possible for ARSession.Reset() to invalidate anchors outside of this, | |
// so the additional checks will skip deleted anchors/anchor GOs. | |
if (anchor != null && anchor.gameObject != null) | |
Destroy(anchor.gameObject); | |
} | |
m_Anchors.Clear(); | |
} | |
void OnEnable() | |
{ | |
if (m_InputActionReferences == null) | |
return; | |
if (m_InputActionReferences.rightTriggerPressed.action != null) | |
m_InputActionReferences.rightTriggerPressed.action.performed += RightTriggerPressed; | |
if (m_InputActionReferences.leftTriggerPressed.action != null) | |
m_InputActionReferences.leftTriggerPressed.action.performed += LeftTriggerPressed; | |
} | |
void OnDisable() | |
{ | |
if (m_InputActionReferences == null) | |
return; | |
if (m_InputActionReferences.rightTriggerPressed.action != null) | |
m_InputActionReferences.rightTriggerPressed.action.performed -= RightTriggerPressed; | |
if (m_InputActionReferences.leftTriggerPressed.action != null) | |
m_InputActionReferences.leftTriggerPressed.action.performed -= LeftTriggerPressed; | |
} | |
void Awake() | |
{ | |
m_RaycastManager = GetComponent<ARRaycastManager>(); | |
m_AnchorManager = GetComponent<ARAnchorManager>(); | |
if (m_AnchorManager.subsystem != null) | |
return; | |
enabled = false; | |
Debug.LogWarning($"No active XRAnchorSubsystem is available, so {typeof(AnchorCreator).FullName} will not be enabled."); | |
} | |
static void SetAnchorText(ARAnchor anchor, string text) | |
{ | |
var canvasTextManager = anchor.GetComponent<CanvasTextManager>(); | |
if (canvasTextManager) | |
{ | |
canvasTextManager.text = text; | |
} | |
} | |
void RightTriggerPressed(InputAction.CallbackContext context) | |
{ | |
RaycastFromHandPose(new Pose( | |
m_InputActionReferences.rightHandPosition.action.ReadValue<Vector3>(), | |
m_InputActionReferences.rightHandRotation.action.ReadValue<Quaternion>())); | |
} | |
void LeftTriggerPressed(InputAction.CallbackContext context) | |
{ | |
RaycastFromHandPose(new Pose( | |
m_InputActionReferences.leftHandPosition.action.ReadValue<Vector3>(), | |
m_InputActionReferences.leftHandRotation.action.ReadValue<Quaternion>())); | |
} | |
void RaycastFromHandPose(Pose handPose) | |
{ | |
s_RaycastRay = new Ray(handPose.position, handPose.forward); | |
if (m_RaycastManager.Raycast(s_RaycastRay, s_Hits, m_TrackableType)) | |
{ | |
CreateAnchor(s_Hits[0]); | |
} | |
} | |
void CreateAnchor(in ARRaycastHit hit) | |
{ | |
ARAnchor anchor; | |
Logger.Log("Creating regular anchor."); | |
if (m_Prefab != null) | |
{ | |
// Note: the anchor can be anywhere in the scene hierarchy | |
var anchorGameObject = Instantiate(m_Prefab, hit.pose.position, hit.pose.rotation); | |
// Make sure the new GameObject has an ARAnchor component | |
anchor = ComponentUtils.GetOrAddIf<ARAnchor>(anchorGameObject, true); | |
} | |
else | |
{ | |
var anchorGameObject = new GameObject("Anchor"); | |
anchorGameObject.transform.SetPositionAndRotation(hit.pose.position, hit.pose.rotation); | |
anchor = anchorGameObject.AddComponent<ARAnchor>(); | |
} | |
SetAnchorText(anchor, $"Anchor (from {hit.hitType})"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment