203 lines
6.9 KiB
C#
203 lines
6.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Serialization;
|
|
|
|
namespace Shared
|
|
{
|
|
public class PlaceAnchorScript : MonoBehaviour
|
|
{
|
|
[SerializeField] private GameObject saveableAnchorPrefab;
|
|
|
|
[SerializeField] private GameObject saveablePreview;
|
|
|
|
[SerializeField] private Transform saveableTransform;
|
|
|
|
[SerializeField] private GameObject nonSaveableAnchorPrefab;
|
|
|
|
[SerializeField] private GameObject nonSaveablePreview;
|
|
|
|
[SerializeField] private Transform nonSaveableTransform;
|
|
|
|
private List<OVRSpatialAnchor> _anchorInstances = new(); // Active instances (red and green)
|
|
|
|
private HashSet<Guid> _anchorUuids = new(); // Simulated external location, like PlayerPrefs
|
|
|
|
private Action<bool, OVRSpatialAnchor.UnboundAnchor> _onLocalized;
|
|
|
|
// public GameObject anchorPrefab;
|
|
// private ulong _requestedId;
|
|
|
|
// private void Awake()
|
|
// {
|
|
// if (Instance == null)
|
|
// {
|
|
// Instance = this;
|
|
// _onLocalized = OnLocalized;
|
|
// }
|
|
// else
|
|
// {
|
|
// Destroy(this);
|
|
// }
|
|
// }
|
|
|
|
// Update is called once per frame
|
|
private void Update()
|
|
{
|
|
// if (OVRInput.GetDown(OVRInput.Button.PrimaryIndexTrigger, OVRInput.Controller.RTouch))
|
|
// {
|
|
// }
|
|
CreateSpatialAnchors();
|
|
|
|
// Destroy displayed anchors
|
|
if (OVRInput.GetDown(OVRInput.Button.Three)) // x button
|
|
{
|
|
// Destroy all anchors from the scene, but don't erase them from storage
|
|
foreach (var anchor in _anchorInstances)
|
|
{
|
|
Destroy(anchor.gameObject);
|
|
}
|
|
|
|
// Clear the list of running anchors
|
|
_anchorInstances.Clear();
|
|
}
|
|
|
|
// load anchors
|
|
if (OVRInput.GetDown(OVRInput.Button.One)) // a button
|
|
{
|
|
LoadAllAnchors(); // Load saved anchors
|
|
}
|
|
|
|
// Erase all saved (green) anchors
|
|
if (OVRInput.GetDown(OVRInput.Button.Four)) // y button
|
|
{
|
|
EraseAllAnchors();
|
|
}
|
|
}
|
|
|
|
private void CreateSpatialAnchors()
|
|
{
|
|
if (OVRInput.GetDown(OVRInput.Button.PrimaryIndexTrigger)) // Create a green capsule
|
|
{
|
|
// Create a green (savable) spatial anchor
|
|
var go = Instantiate(saveableAnchorPrefab, saveableTransform.position,
|
|
saveableTransform.rotation); // Anchor A
|
|
SetupAnchorAsync(go.AddComponent<OVRSpatialAnchor>(), saveAnchor: true);
|
|
}
|
|
else if (OVRInput.GetDown(OVRInput.Button.SecondaryIndexTrigger)) // Create a red capsule
|
|
{
|
|
// Create a red (non-savable) spatial anchor.
|
|
var go = Instantiate(nonSaveableAnchorPrefab, nonSaveableTransform.position,
|
|
nonSaveableTransform.rotation); // Anchor b
|
|
SetupAnchorAsync(go.AddComponent<OVRSpatialAnchor>(), saveAnchor: false);
|
|
}
|
|
}
|
|
|
|
private async void SetupAnchorAsync(OVRSpatialAnchor anchor, bool saveAnchor)
|
|
{
|
|
// Keep checking for a valid and localized anchor state
|
|
if (!await anchor.WhenLocalizedAsync())
|
|
{
|
|
Debug.LogError($"Unable to create anchor.");
|
|
Destroy(anchor.gameObject);
|
|
return;
|
|
}
|
|
|
|
// Add the anchor to the list of all instances
|
|
_anchorInstances.Add(anchor);
|
|
|
|
// save the savable (green) anchors only
|
|
if (saveAnchor && (await anchor.SaveAnchorAsync()).Success)
|
|
{
|
|
// Remember UUID so you can load the anchor later
|
|
_anchorUuids.Add(anchor.Uuid);
|
|
}
|
|
}
|
|
|
|
public async void LoadAllAnchors()
|
|
{
|
|
// Load and localize
|
|
var unboundAnchors = new List<OVRSpatialAnchor.UnboundAnchor>();
|
|
var result = await OVRSpatialAnchor.LoadUnboundAnchorsAsync(_anchorUuids, unboundAnchors);
|
|
|
|
if (result.Success)
|
|
{
|
|
foreach (var anchor in unboundAnchors)
|
|
{
|
|
anchor.LocalizeAsync().ContinueWith(_onLocalized, anchor);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"Load anchors failed with {result.Status}.");
|
|
}
|
|
}
|
|
|
|
private void OnLocalized(bool success, OVRSpatialAnchor.UnboundAnchor unboundAnchor)
|
|
{
|
|
var pose = unboundAnchor.Pose;
|
|
var go = Instantiate(saveableAnchorPrefab, pose.position, pose.rotation);
|
|
var anchor = go.AddComponent<OVRSpatialAnchor>();
|
|
|
|
unboundAnchor.BindTo(anchor);
|
|
|
|
// Add the anchor to the running total
|
|
_anchorInstances.Add(anchor);
|
|
}
|
|
|
|
public async void EraseAllAnchors()
|
|
{
|
|
var result = await OVRSpatialAnchor.EraseAnchorsAsync(anchors: null, uuids: _anchorUuids);
|
|
if (result.Success)
|
|
{
|
|
// Erase our reference lists
|
|
_anchorUuids.Clear();
|
|
|
|
Debug.Log($"Anchors erased.");
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"Anchors NOT erased {result.Status}");
|
|
}
|
|
}
|
|
|
|
// private void CreateSpatialAnchor()
|
|
// {
|
|
// var prefab = Instantiate(anchorPrefab, OVRInput.GetLocalControllerPosition(OVRInput.Controller.RTouch),
|
|
// OVRInput.GetLocalControllerRotation(OVRInput.Controller.RTouch));
|
|
// prefab.AddComponent<OVRSpatialAnchor>();
|
|
// }
|
|
|
|
// private OVRPose GetTrackingSpacePose()
|
|
// {
|
|
// var mainCamera = Camera.main;
|
|
//
|
|
// if (mainCamera) return transform.ToTrackingSpacePose(mainCamera);
|
|
//
|
|
//
|
|
// Debug.LogError("Main camera not found. Using world-space pose.");
|
|
// return transform.ToOVRPose(isLocal: false);
|
|
// }
|
|
//
|
|
// private void CreateSpatialAnchor()
|
|
// {
|
|
// var created = OVRPlugin.CreateSpatialAnchor(new OVRPlugin.SpatialAnchorCreateInfo
|
|
// {
|
|
// BaseTracking = OVRPlugin.GetTrackingOriginType(),
|
|
// PoseInSpace = GetTrackingSpacePose().ToPosef(),
|
|
// Time = OVRPlugin.GetTimeInSeconds()
|
|
// }, out _requestedId);
|
|
//
|
|
// if (created)
|
|
// {
|
|
// Debug.Log($"Spatial anchor created with ID: {_requestedId}");
|
|
// // CreationRequests[_requestedId] = this;
|
|
// }
|
|
// else
|
|
// {
|
|
// Debug.LogError($"Failed to create spatial anchor with ID: {_requestedId}");
|
|
// Destroy(this);
|
|
// }
|
|
// }
|
|
}
|
|
} |