DCDC25-PlantPulse/Assets/Scripts/Shared/PlaceAnchorScript.cs
2025-06-10 23:17:59 +02:00

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);
// }
// }
}
}