03-18-2024 05:35 AM
I have a net code project where i try to use spatial anchors to achieve co-location type of game.
I managed to synchronize the anchor location, both players see the anchor in the same real life physical location. What I'm struggling with is aligning the joining players to the anchor so their characters overlap with their real life bodies.
The flow of logic so far.
1. I spawn the anchor at 0,0,0 for the host
2. Save it, and Share it with players in the lobby
3. Re-Share with joining players.
4. bind unbound anchor for client players, and wait for it to be created and localized
(to this point everything is fine, both players see the anchor, but are not align to it yet.)
:exclamation_mark:5. Align the client player to the anchor (this is where everything aligns wrongly)
The alignment code is basically the same as the one found in sample packages, i take in a OVRSpatialAnchor, then set the "OVRCameraRig" position to 0,0, then setting the "OVRCameraRig" position to the "anchorTransform.InverseTransformPoint(Vector3.zero)"
The problem is that after running the alignment code the "zero zero" is put far away outside the playable space about exactly 5 meters wrong on x and z. And if i try to manually correct for this using "camerarigwhatevr += new vector(-5,0,-5)" it just becomes more wrong.
Bellow you find my alignment code. I know its something about this code, cause the anchor itself is always physically in the same spot for all players, its only the aligning that is wrong. I constantly compare to both the sample projects, and i cannot find any differences that should affect this.
Based on these Samples
My alignment code (with debugging stuff) (i manually trigger the align with a button bind so i can see what happens more easily):
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// A Script to bind local player positions to the networked player.
public class LocalPlayer : MonoBehaviour
{
public static LocalPlayer Instance;
[Header("Colocation Alignment")]
[SerializeField] Transform _cameraRigTransform;
[SerializeField] Transform _playerHandsTransform;
private void Awake()
{
Instance = this;
}
private void Update()
{
if (OVRInput.GetDown(OVRInput.RawButton.A)) AlignPlayerToColocation();
}
private Coroutine _alignmentCoroutine;
public static void AlignPlayerToColocation()
{
if (CoLocationAnchorManager.Singleton.LoadedAnchor == null)
{
Logger.Log("No colocation anchor");
return;
}
Instance?.AlignPlayerToAnchor(CoLocationAnchorManager.Singleton.LoadedAnchor);
}
public void AlignPlayerToAnchor(OVRSpatialAnchor anchor)
{
Debug.Log("AlignmentAnchorManager: Called AlignPlayerToAnchor");
if (_alignmentCoroutine != null)
{
StopCoroutine(_alignmentCoroutine);
_alignmentCoroutine = null;
}
_alignmentCoroutine = StartCoroutine(AlignmentCoroutine(anchor, 2));
}
OVRSpatialAnchor _currentAlignement;
private IEnumerator AlignmentCoroutine(OVRSpatialAnchor anchor, int alignmentCount)
{
Debug.Log("PlayerAlignment: called AlignmentCoroutine");
while (!anchor.Created)
{
yield return null;
}
while (!anchor.Localized)
{
yield return null;
}
Logger.Log("BEFORE ALIGN [" + alignmentCount + "]: Player Transform : " + _cameraRigTransform.position);
Logger.Log("BEFORE ALIGN [" + alignmentCount + "]: Anchor Transform : " + anchor.transform.position);
while (alignmentCount > 0)
{
if (_currentAlignement != null)
{
// Reset the position to zero
_cameraRigTransform.position = Vector3.zero;
_cameraRigTransform.eulerAngles = Vector3.zero;
Logger.Log("ALIGN [" + alignmentCount + "]: Player Transform : " + _cameraRigTransform.position);
Logger.Log("ALIGN [" + alignmentCount + "]: Anchor Transform : " + anchor.transform.position);
// wait one frame for anchor to move
yield return null;
}
var anchorTransform = anchor.transform;
if (_cameraRigTransform != null)
{
// set the position to be the inverse of the Ancor Transform Position (Relative to its new position)
// this kinda gets the anchors releative position to the world origin.
_cameraRigTransform.position = anchorTransform.InverseTransformPoint(Vector3.zero);
Logger.Log("ALIGN Inverse [" + alignmentCount + "]: Player Transform : " + _cameraRigTransform.position);
Logger.Log("ALIGN Inverse [" + alignmentCount + "]: Anchor Transform : " + anchor.transform.position);
_cameraRigTransform.eulerAngles = new Vector3(0, -anchorTransform.eulerAngles.y, 0);
}
else
{
Logger.Log("ALIGN: CameraRigTransform is invalid");
}
if (_playerHandsTransform != null)
{
_playerHandsTransform.localPosition = -_cameraRigTransform.position;
_playerHandsTransform.localEulerAngles = -_cameraRigTransform.eulerAngles;
}
_currentAlignement = anchor;
alignmentCount--;
yield return new WaitForEndOfFrame();
}
Logger.Log("ALIGN FINAL [" + alignmentCount + "]: Player Transform : " + _cameraRigTransform.position);
Logger.Log("ALIGN FINAL [" + alignmentCount + "]: Anchor Transform : " + anchor.transform.position);
Debug.Log("PlayerAlignment: Finished Alignment!");
Logger.Log("Alignment Finished?");
OnAfterAlignment.Invoke();
}
public Action OnAfterAlignment;
}
04-16-2024 07:50 AM
I am trying to do the same. Such a bad thing that Meta does not answer or provide any package or tutorial regarding multiplayer co-located experiences.
04-16-2024 07:59 AM