Hello,
I’ve followed this tutorial to create a collaborative session in iOS:
So far so good, everything works.
Now that I’ve tried to do the same in my project, everything works normally except for the anchor placement. The master places anchors, the client receives the data as bytes, but the anchor manager doesn’t spawn the anchor as it should.
protected override void OnEnable()
{
base.OnEnable();
_arAnchorManager.anchorsChanged += UpdateAnchors;
}
private void UpdateAnchors(ARAnchorsChangedEventArgs args)
{
if (args.added != null && args.added.Count > 0)
{
Debug.Log("Anchor added!");
if (!_receivedAnchor)
{
NetworkManager.Instance.SetLocalPlayerReady(true);
_infinitePlaneManager.SetARPlanesVisibility(false);
}
_receivedAnchor = true;
}
if (args.updated != null && args.updated.Count > 0)
{
Debug.Log("Anchor updated!");
if (!_receivedAnchor)
{
NetworkManager.Instance.SetLocalPlayerReady(true);
_infinitePlaneManager.SetARPlanesVisibility(false);
}
_receivedAnchor = true;
}
}
I’m using ARFoundation with ARKit 4.2.7 and Unity 2021.3.6f1, the same versions as the working example that I’ve got.
Has anyone stumbled upon something like this?
Regards and thank you!
Issue solved, but it took me some long hours to figure out.
I wanted to only use planes as the Raycast targets. In the previous sample, it used both planes and point cloud raycasts.
In the AnchorCreator from that example, there are 2 wait to place anchors: from a detected plane and from a point cloud point:
ARAnchor CreateAnchor(in ARRaycastHit hit)
{
ARAnchor anchor = null;
var pose = hit.pose;
pose.rotation = Quaternion.Euler(Vector3.up * Camera.main.transform.eulerAngles.y);
// If we hit a plane, try to "attach" the anchor to the plane
if (hit.trackable is ARPlane plane)
{
var planeManager = GetComponent<ARPlaneManager>();
if (planeManager != null)
{
Debug.Log("Creating anchor attachment.");
if (m_Prefab != null)
{
var oldPrefab = m_AnchorManager.anchorPrefab;
m_AnchorManager.anchorPrefab = m_Prefab;
anchor = m_AnchorManager.AttachAnchor(plane, pose);
m_AnchorManager.anchorPrefab = oldPrefab;
}
else
{
anchor = m_AnchorManager.AttachAnchor(plane, pose);
}
//SetAnchorText(anchor, $"Attached to plane {plane.trackableId}");
return anchor;
}
}
#if !UNITY_EDITOR
else
{
Debug.Log("Must hit an ARPlane");
return null;
}
#endif
// Otherwise, just create a regular anchor at the hit pose
Debug.Log("Creating regular anchor.");
if (m_Prefab != null)
{
// Note: the anchor can be anywhere in the scene hierarchy
var gameObject = Instantiate(m_Prefab, pose.position, pose.rotation);
// Make sure the new GameObject has an ARAnchor component
anchor = gameObject.AddComponent<ARAnchor>();
}
else
{
var gameObject = new GameObject("Anchor");
gameObject.transform.SetPositionAndRotation(pose.position, pose.rotation);
anchor = gameObject.AddComponent<ARAnchor>();
}
return anchor;
}
These are NOT the same thing:
anchor = m_AnchorManager.AttachAnchor(plane, pose);
anchor = gameObject.AddComponent();
The first line creates an anchor, but it doens’t share it on a collaborative session. Maybe it’s a Unity bug?
In any case, I’m just leaving the solution here in case someone else stumbles upon the same problem. Just remove the AR Plane check section.
ARAnchor CreateAnchor(in ARRaycastHit hit)
{
ARAnchor anchor = null;
var pose = hit.pose;
pose.rotation = Quaternion.Euler(Vector3.up * Camera.main.transform.eulerAngles.y);
Debug.Log("Creating regular anchor.");
if (m_Prefab != null)
{
// Note: the anchor can be anywhere in the scene hierarchy
var gameObject = Instantiate(m_Prefab, pose.position, pose.rotation);
// Make sure the new GameObject has an ARAnchor component
anchor = gameObject.AddComponent<ARAnchor>();
}
else
{
var gameObject = new GameObject("Anchor");
gameObject.transform.SetPositionAndRotation(pose.position, pose.rotation);
anchor = gameObject.AddComponent<ARAnchor>();
}
return anchor;
}
1 Like