9 #if UNITY_WSA && !UNITY_EDITOR 10 using System.Collections.Generic;
11 #if UNITY_2017_2_OR_NEWER 32 private enum ImportExportState
42 AnchorStore_Initializing,
44 InitialAnchorRequired,
45 CreatingInitialAnchor,
46 ReadyToExportInitialAnchor,
47 UploadingInitialAnchor,
54 private ImportExportState currentState = ImportExportState.Start;
56 public string StateName
60 return currentState.ToString();
64 public bool AnchorEstablished
68 return currentState == ImportExportState.AnchorEstablished;
84 if (currentRoom == null)
91 private static bool ShouldLocalUserCreateRoom
103 localUserId = localUser.
GetID();
123 #if UNITY_WSA && !UNITY_EDITOR 128 public event Action AnchorLoaded;
134 private WorldAnchorTransferBatch sharedAnchorInterface;
140 private WorldAnchorStore anchorStore;
145 private string exportingAnchorName;
150 private List<byte> exportingAnchorBytes =
new List<byte>();
156 private const uint MinTrustworthySerializedAnchorDataSize = 100000;
163 private byte[] rawAnchorData;
170 private bool sharingServiceReady;
181 private Room currentRoom;
186 private long roomID = 8675309;
196 public string RoomName =
"DefaultRoom";
214 #if UNITY_WSA && !UNITY_EDITOR 216 currentState = ImportExportState.AnchorStore_Initializing;
217 WorldAnchorStore.GetAsync(AnchorStoreReady);
219 currentState = ImportExportState.Ready;
236 private void Update()
238 switch (currentState)
241 case ImportExportState.Ready:
242 if (sharingServiceReady)
244 StartCoroutine(InitRoomApi());
247 case ImportExportState.RoomApiInitialized:
248 StartAnchorProcess();
250 #if UNITY_WSA && !UNITY_EDITOR 251 case ImportExportState.DataReady:
253 currentState = ImportExportState.Importing;
254 WorldAnchorTransferBatch.ImportAsync(rawAnchorData, ImportComplete);
256 case ImportExportState.InitialAnchorRequired:
257 currentState = ImportExportState.CreatingInitialAnchor;
258 CreateAnchorLocally();
260 case ImportExportState.ReadyToExportInitialAnchor:
262 currentState = ImportExportState.UploadingInitialAnchor;
280 if (roomManagerListener != null)
286 if (roomManager != null)
292 roomManagerListener = null;
295 if (roomManager != null)
306 #region Event Callbacks 313 private void Connected(
object sender = null, EventArgs e = null)
319 Debug.Log(
"Anchor Manager: Starting...");
322 if (AnchorDebugText != null)
324 AnchorDebugText.text +=
"\nConnected to Server";
346 private void RoomManagerListener_AnchorUploaded(
bool successful,
XString failureReason)
353 Debug.Log(
"Anchor Manager: Successfully uploaded anchor");
356 if (AnchorDebugText != null)
358 AnchorDebugText.text +=
"\nSuccessfully uploaded anchor";
361 currentState = ImportExportState.AnchorEstablished;
365 if (AnchorDebugText != null)
367 AnchorDebugText.text +=
string.Format(
"\n Upload failed " + failureReason);
370 Debug.LogError(
"Anchor Manager: Upload failed " + failureReason);
371 currentState = ImportExportState.Failed;
374 if (AnchorUploaded != null)
376 AnchorUploaded(successful);
392 Debug.LogFormat(
"Anchor Manager: Anchor size: {0} bytes.", dataSize.ToString());
395 if (AnchorDebugText != null)
397 AnchorDebugText.text +=
string.Format(
"\nAnchor size: {0} bytes.", dataSize.ToString());
400 rawAnchorData =
new byte[dataSize];
402 request.
GetData(rawAnchorData, dataSize);
403 currentState = ImportExportState.DataReady;
407 if (AnchorDebugText != null)
409 AnchorDebugText.text +=
string.Format(
"\nAnchor DL failed " + failureReason);
413 Debug.LogWarning(
"Anchor Manager: Anchor DL failed " + failureReason);
414 #if UNITY_WSA && !UNITY_EDITOR 415 MakeAnchorDataRequest();
424 private void RoomManagerCallbacks_AnchorsChanged(
Room room)
428 Debug.LogFormat(
"Anchor Manager: Anchors in room {0} changed", room.
GetName());
431 if (AnchorDebugText != null)
433 AnchorDebugText.text +=
string.Format(
"\nAnchors in room {0} changed", room.
GetName());
437 if (currentRoom == room)
448 private void CurrentUserJoinedSession(
Session session)
452 sharingServiceReady =
true;
456 Debug.LogWarning(
"Unable to get local user on session joined");
465 private void CurrentUserLeftSession(
Session session)
467 sharingServiceReady =
false;
478 private void ResetState()
480 #if UNITY_WSA && !UNITY_EDITOR 481 if (anchorStore != null)
483 currentState = ImportExportState.Ready;
487 currentState = ImportExportState.AnchorStore_Initializing;
490 currentState = ImportExportState.Ready;
497 private IEnumerator InitRoomApi()
499 currentState = ImportExportState.RoomApiInitializing;
503 while (currentRoom == null)
508 yield
return new WaitForEndOfFrame();
511 if (ShouldLocalUserCreateRoom)
515 Debug.Log(
"Anchor Manager: Creating room " + RoomName);
518 if (AnchorDebugText != null)
520 AnchorDebugText.text +=
string.Format(
"\nCreating room " + RoomName);
525 currentRoom = roomManager.
CreateRoom(
new XString(RoomName), roomID, KeepRoomAlive);
532 for (
int i = 0; i < roomCount; i++)
535 if (room.
GetName().
GetString().Equals(RoomName, StringComparison.OrdinalIgnoreCase))
545 if (AnchorDebugText != null)
547 AnchorDebugText.text +=
string.Format(
"\nJoining room " + room.
GetName().
GetString());
554 if (currentRoom == null)
557 currentRoom = roomManager.
GetRoom(0);
562 currentState = ImportExportState.RoomApiInitialized;
565 yield
return new WaitForEndOfFrame();
570 #if UNITY_WSA && !UNITY_EDITOR 572 currentState = ImportExportState.InitialAnchorRequired;
574 currentState = ImportExportState.RoomApiInitialized;
580 currentState = ImportExportState.RoomApiInitialized;
585 Debug.LogFormat(
"Anchor Manager: In room {0} with ID {1}",
590 if (AnchorDebugText != null)
592 AnchorDebugText.text +=
string.Format(
"\nIn room {0} with ID {1}",
603 private void StartAnchorProcess()
610 Debug.LogFormat(
"Anchor Manager: {0} anchors found.", anchorCount.ToString());
613 if (AnchorDebugText != null)
615 AnchorDebugText.text +=
string.Format(
"\n{0} anchors found.", anchorCount.ToString());
618 #if UNITY_WSA && !UNITY_EDITOR 625 string storedAnchorName = storedAnchorString.
GetString();
628 if (AttachToCachedAnchor(storedAnchorName) ==
false)
632 Debug.Log(
"Anchor Manager: Starting room anchor download of " + storedAnchorString);
635 if (AnchorDebugText != null)
637 AnchorDebugText.text +=
string.Format(
"\nStarting room anchor download of " + storedAnchorString);
641 MakeAnchorDataRequest();
647 currentState = ImportExportState.AnchorEstablished;
649 if (AnchorDebugText != null)
651 AnchorDebugText.text += anchorCount > 0 ?
"\n" + currentRoom.
GetAnchorName(0).
ToString() :
"\nNo Anchors Found";
657 #region WSA Specific Methods 659 #if UNITY_WSA && !UNITY_EDITOR 665 private void MakeAnchorDataRequest()
669 currentState = ImportExportState.DataRequested;
673 Debug.LogError(
"Anchor Manager: Couldn't make the download request.");
675 if (AnchorDebugText != null)
677 AnchorDebugText.text +=
string.Format(
"\nCouldn't make the download request.");
680 currentState = ImportExportState.Failed;
688 private void AnchorStoreReady(WorldAnchorStore store)
697 currentState = ImportExportState.Ready;
703 private void CreateAnchorLocally()
705 WorldAnchor anchor = this.EnsureComponent<WorldAnchor>();
706 if (anchor.isLocated)
708 currentState = ImportExportState.ReadyToExportInitialAnchor;
712 anchor.OnTrackingChanged += Anchor_OnTrackingChanged_InitialAnchor;
719 private void Anchor_OnTrackingChanged_InitialAnchor(WorldAnchor
self,
bool located)
725 Debug.Log(
"Anchor Manager: Found anchor, ready to export");
728 if (AnchorDebugText != null)
730 AnchorDebugText.text +=
string.Format(
"\nFound anchor, ready to export");
733 currentState = ImportExportState.ReadyToExportInitialAnchor;
737 Debug.LogError(
"Anchor Manager: Failed to locate local anchor!");
739 if (AnchorDebugText != null)
741 AnchorDebugText.text +=
string.Format(
"\nFailed to locate local anchor!");
744 currentState = ImportExportState.Failed;
747 self.OnTrackingChanged -= Anchor_OnTrackingChanged_InitialAnchor;
754 private bool AttachToCachedAnchor(
string anchorName)
758 Debug.LogFormat(
"Anchor Manager: Looking for cached anchor {0}...", anchorName);
761 if (AnchorDebugText != null)
763 AnchorDebugText.text +=
string.Format(
"\nLooking for cached anchor {0}...", anchorName);
766 string[] ids = anchorStore.GetAllIds();
767 for (
int index = 0; index < ids.Length; index++)
769 if (ids[index] == anchorName)
773 Debug.LogFormat(
"Anchor Manager: Attempting to load cached anchor {0}...", anchorName);
776 if (AnchorDebugText != null)
778 AnchorDebugText.text +=
string.Format(
"\nAttempting to load cached anchor {0}...", anchorName);
781 WorldAnchor anchor = anchorStore.Load(ids[index], gameObject);
783 if (anchor.isLocated)
785 AnchorLoadComplete();
789 if (AnchorDebugText != null)
791 AnchorDebugText.text +=
"\n"+anchorName;
794 anchor.OnTrackingChanged += ImportExportAnchorManager_OnTrackingChanged_Attaching;
795 currentState = ImportExportState.AnchorEstablished;
810 private void ImportExportAnchorManager_OnTrackingChanged_Attaching(WorldAnchor
self,
bool located)
814 AnchorLoadComplete();
818 Debug.LogWarning(
"Anchor Manager: Failed to find local anchor from cache.");
820 if (AnchorDebugText != null)
822 AnchorDebugText.text +=
string.Format(
"\nFailed to find local anchor from cache.");
825 MakeAnchorDataRequest();
828 self.OnTrackingChanged -= ImportExportAnchorManager_OnTrackingChanged_Attaching;
836 private void ImportComplete(SerializationCompletionReason status, WorldAnchorTransferBatch anchorBatch)
838 if (status == SerializationCompletionReason.Succeeded)
840 if (anchorBatch.GetAllIds().Length > 0)
842 string first = anchorBatch.GetAllIds()[0];
846 Debug.Log(
"Anchor Manager: Successfully imported anchor " + first);
849 if (AnchorDebugText != null)
851 AnchorDebugText.text +=
string.Format(
"\nSuccessfully imported anchor " + first);
854 WorldAnchor anchor = anchorBatch.LockObject(first, gameObject);
855 anchorStore.Save(first, anchor);
858 AnchorLoadComplete();
862 Debug.LogError(
"Anchor Manager: Import failed");
864 if (AnchorDebugText != null)
866 AnchorDebugText.text +=
string.Format(
"\nImport failed");
869 currentState = ImportExportState.DataReady;
873 private void AnchorLoadComplete()
875 if (AnchorLoaded != null)
880 currentState = ImportExportState.AnchorEstablished;
886 private void Export()
888 WorldAnchor anchor = this.GetComponent<WorldAnchor>();
889 string guidString = Guid.NewGuid().ToString();
890 exportingAnchorName = guidString;
893 if (anchor != null && anchorStore.Save(exportingAnchorName, anchor))
897 Debug.Log(
"Anchor Manager: Exporting anchor " + exportingAnchorName);
900 if (AnchorDebugText != null)
902 AnchorDebugText.text +=
string.Format(
"\nExporting anchor {0}", exportingAnchorName);
905 sharedAnchorInterface =
new WorldAnchorTransferBatch();
906 sharedAnchorInterface.AddWorldAnchor(guidString, anchor);
907 WorldAnchorTransferBatch.ExportAsync(sharedAnchorInterface, WriteBuffer, ExportComplete);
911 Debug.LogWarning(
"Anchor Manager: Failed to export anchor, trying again...");
913 if (AnchorDebugText != null)
915 AnchorDebugText.text +=
string.Format(
"\nFailed to export anchor, trying again...");
918 currentState = ImportExportState.InitialAnchorRequired;
926 private void WriteBuffer(byte[] data)
928 exportingAnchorBytes.AddRange(data);
935 private void ExportComplete(SerializationCompletionReason status)
937 if (status == SerializationCompletionReason.Succeeded && exportingAnchorBytes.Count > MinTrustworthySerializedAnchorDataSize)
941 Debug.Log(
"Anchor Manager: Uploading anchor: " + exportingAnchorName);
944 if (AnchorDebugText != null)
946 AnchorDebugText.text +=
string.Format(
"\nUploading anchor: " + exportingAnchorName);
951 new XString(exportingAnchorName),
952 exportingAnchorBytes.ToArray(),
953 exportingAnchorBytes.Count);
957 Debug.LogWarning(
"Anchor Manager: Failed to upload anchor, trying again...");
959 if (AnchorDebugText != null)
961 AnchorDebugText.text +=
string.Format(
"\nFailed to upload anchor, trying again...");
964 currentState = ImportExportState.InitialAnchorRequired;
969 #endregion // WSA Specific Methods