210 lines
7.0 KiB
C#
210 lines
7.0 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
public class SpatialAnchorManager : MonoBehaviour
|
|
{
|
|
private ApplicationManager _applicationManager;
|
|
|
|
// This reusable buffer helps reduce pressure on the garbage collector
|
|
private readonly List<OVRSpatialAnchor.UnboundAnchor> _unboundAnchors = new();
|
|
private const string NumUuidsPlayerPref = "NumUuids";
|
|
|
|
private void Awake()
|
|
{
|
|
_applicationManager = GetComponent<ApplicationManager>();
|
|
if (_applicationManager == null)
|
|
{
|
|
Debug.LogError("[DCDC] ApplicationManager component not found on the GameObject.");
|
|
}
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
_applicationManager.SetInProgress(true);
|
|
LoadSavedAnchors();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
// spatial anchor options are only available to the host
|
|
if (_applicationManager.InProgress || _applicationManager.IsHost == false) return;
|
|
|
|
if (OVRInput.GetDown(OVRInput.Button.PrimaryIndexTrigger, OVRInput.Controller.RTouch))
|
|
{
|
|
CreateSpatialAnchor();
|
|
}
|
|
|
|
if (OVRInput.GetDown(OVRInput.Button.PrimaryThumbstick, OVRInput.Controller.RTouch))
|
|
{
|
|
UnsaveAllAnchors();
|
|
}
|
|
}
|
|
|
|
private async void LoadSavedAnchors()
|
|
{
|
|
try
|
|
{
|
|
if (!PlayerPrefs.HasKey(NumUuidsPlayerPref)) PlayerPrefs.SetInt(NumUuidsPlayerPref, 0);
|
|
|
|
var playerUuidCount = PlayerPrefs.GetInt(NumUuidsPlayerPref);
|
|
if (playerUuidCount == 0)
|
|
{
|
|
_applicationManager.SetInProgress(false);
|
|
return;
|
|
}
|
|
|
|
Debug.Log($"[DCDC] Loading {playerUuidCount} anchors from PlayerPrefs.");
|
|
|
|
var uuids = new Guid[playerUuidCount];
|
|
for (var i = 0; i < playerUuidCount; i++)
|
|
{
|
|
var uuidKey = "uuid" + i;
|
|
var currentUuid = PlayerPrefs.GetString(uuidKey);
|
|
uuids[i] = new Guid(currentUuid);
|
|
}
|
|
|
|
// Load
|
|
var result = await OVRSpatialAnchor.LoadUnboundAnchorsAsync(uuids, _unboundAnchors);
|
|
|
|
if (result.Success)
|
|
{
|
|
Debug.Log("[DCDC] Anchors loaded successfully.");
|
|
|
|
// Note result.Value is the same as _unboundAnchors
|
|
foreach (var unboundAnchor in result.Value)
|
|
{
|
|
unboundAnchor.LocalizeAsync().ContinueWith((success, _) =>
|
|
{
|
|
if (success)
|
|
{
|
|
unboundAnchor.TryGetPose(out var pose);
|
|
var spatialAnchor = Instantiate(_applicationManager.hostPlaceholderMarker, pose.position,
|
|
pose.rotation);
|
|
var button = spatialAnchor.gameObject.GetComponentInChildren<Button>();
|
|
if (button != null) button.onClick.AddListener(_applicationManager.AnchorSubmitted);
|
|
else Debug.LogError("[DCDC] Submit button not found on host placeholder marker.");
|
|
|
|
unboundAnchor.BindTo(spatialAnchor);
|
|
_applicationManager.SetAnchor(spatialAnchor);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"[DCDC] Localization failed for anchor {unboundAnchor.Uuid}");
|
|
}
|
|
}, unboundAnchor);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"[DCDC] Load failed with error {result.Status}.");
|
|
}
|
|
|
|
_applicationManager.SetInProgress(false);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError($"[DCDC] Exception while loading anchors: {e}");
|
|
_applicationManager.SetInProgress(false);
|
|
}
|
|
}
|
|
|
|
private void CreateSpatialAnchor()
|
|
{
|
|
// one anchor only
|
|
if (_applicationManager.PlacedAnchor != null) return;
|
|
|
|
var workingAnchor = Instantiate(
|
|
_applicationManager.hostPlaceholderMarker,
|
|
// place the anchor .5 meters in z axis from the right controller's current position and rotation
|
|
OVRInput.GetLocalControllerPosition(OVRInput.Controller.RTouch) +
|
|
OVRInput.GetLocalControllerRotation(OVRInput.Controller.RTouch) * Vector3.forward * 0.5f,
|
|
OVRInput.GetLocalControllerRotation(OVRInput.Controller.RTouch)
|
|
);
|
|
var button = workingAnchor.gameObject.GetComponentInChildren<Button>();
|
|
if (button != null) button.onClick.AddListener(_applicationManager.AnchorSubmitted);
|
|
else Debug.LogError("[DCDC] Submit button not found on host placeholder marker.");
|
|
|
|
_applicationManager.SetAnchor(workingAnchor);
|
|
|
|
StartCoroutine(AnchorCreated(workingAnchor));
|
|
}
|
|
|
|
private static IEnumerator AnchorCreated(OVRSpatialAnchor anchor)
|
|
{
|
|
while (!anchor.Created && !anchor.Localized)
|
|
{
|
|
yield return new WaitForEndOfFrame();
|
|
}
|
|
|
|
SaveLastCreatedAnchor(anchor);
|
|
}
|
|
|
|
private static async void SaveLastCreatedAnchor(OVRSpatialAnchor anchor)
|
|
{
|
|
try
|
|
{
|
|
var saved = await anchor.SaveAnchorAsync();
|
|
if (!saved.Success)
|
|
{
|
|
Debug.LogError($"[DCDC] Anchor Save failed with error: {saved.Status}");
|
|
return;
|
|
}
|
|
|
|
SaveUuidToPlayerPrefs(anchor.Uuid);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError($"[DCDC] Exception while saving anchor: {e}");
|
|
}
|
|
}
|
|
|
|
private static void SaveUuidToPlayerPrefs(Guid uuid)
|
|
{
|
|
if (!PlayerPrefs.HasKey(NumUuidsPlayerPref))
|
|
{
|
|
PlayerPrefs.SetInt(NumUuidsPlayerPref, 0);
|
|
}
|
|
|
|
var numUuids = PlayerPrefs.GetInt(NumUuidsPlayerPref);
|
|
var strId = $"uuid{numUuids}";
|
|
PlayerPrefs.SetString(strId, uuid.ToString());
|
|
PlayerPrefs.SetInt(NumUuidsPlayerPref, ++numUuids);
|
|
|
|
Debug.Log($"[DCDC] PlayerPrefs saved: {strId} : {uuid}");
|
|
}
|
|
|
|
private void UnsaveAllAnchors()
|
|
{
|
|
var unsaved = _applicationManager.PlacedAnchor.EraseAnchorAsync();
|
|
if (unsaved.IsFaulted)
|
|
{
|
|
Debug.LogError($"[DCDC] Anchor Unsave failed with error: {unsaved.GetException()}");
|
|
return;
|
|
}
|
|
|
|
// remove the UI game object
|
|
Destroy(_applicationManager.PlacedAnchor.gameObject);
|
|
|
|
_applicationManager.SetAnchor(null);
|
|
ClearAllUuidsFromPlayerPrefs();
|
|
}
|
|
|
|
private static void ClearAllUuidsFromPlayerPrefs()
|
|
{
|
|
if (!PlayerPrefs.HasKey(NumUuidsPlayerPref)) return;
|
|
|
|
var numUuids = PlayerPrefs.GetInt(NumUuidsPlayerPref);
|
|
for (var i = 0; i < numUuids; i++)
|
|
{
|
|
PlayerPrefs.DeleteKey($"AnchorUuid_{i}");
|
|
}
|
|
|
|
PlayerPrefs.DeleteKey(NumUuidsPlayerPref);
|
|
PlayerPrefs.Save();
|
|
|
|
Debug.Log("[DCDC] All anchor UUIDs cleared from PlayerPrefs.");
|
|
}
|
|
} |