Skip to content

Instantly share code, notes, and snippets.

@dilmerv
Created July 13, 2023 20:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dilmerv/03b4921907922e3333b33864667863b4 to your computer and use it in GitHub Desktop.
Save dilmerv/03b4921907922e3333b33864667863b4 to your computer and use it in GitHub Desktop.
AnchorCreatorV2.cs - For AR Foundation With Meta OpenXR Support
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