Unity-Technologies / arfoundation-samples

Example content for Unity projects based on AR Foundation
Other
3.03k stars 1.13k forks source link

Find the ARAnchor attached to specific ARPlane? #649

Closed RyanJVR closed 3 years ago

RyanJVR commented 3 years ago

Im using public ARAnchor AttachAnchor(ARPlane plane, Pose pose); to attach an ARAnchor to a ARPlane that is touched.

How do I retrieve that ARAnchor if I touch the same plane a second time? Tried if (hit.trackable is ARPlane plane) { var p_anchor = plane.gameObject.GetComponent<ARAnchor>(); } but p_anchor always ends null for me.

Regards Ryan

tdmowrer commented 3 years ago

How do I retrieve that ARAnchor if I touch the same plane a second time?

There is no way to ask "to what plane is this anchor attached?".

Tried if (hit.trackable is ARPlane plane) { var p_anchor = plane.gameObject.GetComponent<ARAnchor>(); } but p_anchor always ends null for me.

Planes and anchors have different transforms (on different GameObjects), so plane.GetComponent<ARAnchor>() should always return null.

When you "attach" an anchor to a plane, you get back a regular anchor; the only difference is in the way that it is updated internally. From https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@4.0/manual/anchor-manager.html#attaching-anchors:

Attaching an anchor to a plane affects the anchor update semantics. This type of anchor will only change its position along the normal of the plane to which it is attached, thus maintaining a constant distance from the plane.

If this relationship is important to you, you can keep a Dictionary of anchors to planes in order to look up the plane to which an anchor is attached.

RyanJVR commented 3 years ago

Thank you for your response tdmowrer. I was using this example and hoping attachAnchor() worked a similar way.

void AnchorContent(Vector3 position, GameObject prefab)
{
    // Create an instance of the prefab
    var instance = Instantiate(prefab, position, Quaternion.identity);

    // Add an ARAnchor component if it doesn't have one already.
    if (instance.GetComponent<ARAnchor>() == null)
    {
        instance.AddComponent<ARAnchor>();
    }
}

Will look into the Dictionary route. Thanks again. Ryan

tdmowrer commented 3 years ago

Attaching an anchor to a plane requires a method call on the ARAnchorManager because it has to know what ARPlane to attach to at the time it is created. "Regular" anchors only need a transform, so simply calling AddComponent is enough.

Will look into the Dictionary route.

For inspiration:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

public class SomeBehaviour : MonoBehaviour
{
    [SerializeField]
    ARRaycastManager m_RaycastManager;

    [SerializeField]
    ARAnchorManager m_AnchorManager;

    Dictionary<ARPlane, ARAnchor> m_Anchors = new Dictionary<ARPlane, ARAnchor>();

    List<ARRaycastHit> m_RaycastHits = new List<ARRaycastHit>();

    void Update()
    {
        var screenTapped = Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Ended;
        if (screenTapped && m_RaycastManager.Raycast(Input.GetTouch(0).position, m_RaycastHits, TrackableType.PlaneWithinPolygon))
        {
            var hit = m_RaycastHits[0];
            if (hit.trackable is ARPlane plane)
            {
                // Get the existing anchor attachment if it exists
                if (!m_Anchors.TryGetValue(plane, out var anchor))
                {
                    // We don't already have one. Create a new one?
                    anchor = m_AnchorManager.AttachAnchor(plane, hit.pose);

                    // Add it to the map for next time
                    m_Anchors.Add(plane, anchor);
                }

                // Do something with the attached anchor...
            }
        }
    }
}
RyanJVR commented 3 years ago

Thank you so much

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.