Search Unity

Problems with WorldAnchors between Unity Player and deployed app

Discussion in 'VR' started by francescoStrada, Feb 2, 2017.

  1. francescoStrada

    francescoStrada

    Joined:
    Oct 27, 2014
    Posts:
    5
    Hi,
    we are trying to design our hololens application contents from the editor in remote mode, in order to fine-place holograms into the room and then attach world anchors to them when done. Everything works fine within the editor (we place our objects, we change their position, we restart everything after days and all our holograms are there in the the correct place).

    But when we deploy our app on the device all our anchors cannot be loaded from the anchor store. We start again from the editor, the store includes our anchors.

    The question is: when working with the editor in remote mode, where are the anchor stored? Apparently, not on the device (hololens) but locally. If this supposition is correct, how can we access them and possibly use them in the deployed version?

    Here's a short script that can reproduce the problem. Simply create an empty object, name it and attach the script. You can save the anchor pressing the 's' key. At startup, the sript tries to load the anchor from the store. The sphere color tells you its state (white: sphere unlocked, green: anchor saved or loaded from store, red: anchor loading from store did not succeed, blue: saving anchor on store did not succeed). Start in editor remote mode, save your anchor (anchor should be green and in the same position the next execution) and then deploy the application (you should see a red sphere in front of the camera, wherever you viewing direction is at startup).

    Thanks in advance for any possible help

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.VR.WSA;
    3. using UnityEngine.VR.WSA.Persistence;
    4.  
    5. public class AnchorPlacer : MonoBehaviour
    6. {
    7.     private bool loadAnchorAtStartup = true;
    8.     protected WorldAnchorStore store = null;
    9.     protected GameObject sphere = null;
    10.  
    11.  
    12.     protected void StoreLoaded(WorldAnchorStore store)
    13.     {
    14.         this.store = store;
    15.         if(loadAnchorAtStartup)
    16.         LoadAnchor();
    17.     }
    18.  
    19.     protected void Update()
    20.     {
    21.         // s key to save object anchor
    22.         if(Input.GetKeyDown("s"))
    23.         SaveAnchor();
    24.  
    25.  
    26.         // c key to clear object anchor, thus allowing to change its position from the Unity editor
    27.         if(Input.GetKeyDown("c"))
    28.         {
    29.         WorldAnchor anchor = gameObject.GetComponent<WorldAnchor>();
    30.         if(anchor != null)
    31.             DestroyImmediate(anchor);
    32.  
    33.         SetColor(sphere, Color.white);
    34.         }
    35.     }
    36.  
    37.  
    38.     protected void SetColor(GameObject obj,Color color)
    39.     {
    40.         Renderer renderer = obj.GetComponent<Renderer>();
    41.         if(renderer == null)
    42.         return;
    43.  
    44.         renderer.material.color = color;
    45.     }
    46.  
    47.     protected void Start()
    48.     {
    49.         sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
    50.         sphere.transform.parent = transform;
    51.         SetColor(sphere, Color.white);
    52.         WorldAnchorStore.GetAsync(StoreLoaded);
    53.     }
    54.  
    55.     public bool SaveAnchor()
    56.     {
    57.         //do the cleanup: if an anchor already exists, destroy it (from the gameobject and the store)
    58.         WorldAnchor anchor = gameObject.GetComponent<WorldAnchor>();
    59.  
    60.         if(anchor != null)
    61.         DestroyImmediate(anchor);
    62.  
    63.         if(store != null)
    64.         {        
    65.         store.Delete(gameObject.name);
    66.  
    67.         //add a game anchor to current object
    68.         anchor = gameObject.AddComponent<WorldAnchor>();
    69.  
    70.         //save the anchor to the store
    71.         if(!store.Save(gameObject.name, anchor))
    72.         {
    73.             Debug.LogWarning(string.Format("Anchor {0} NOT saved", gameObject.name));
    74.             SetColor(sphere, Color.blue);
    75.         }
    76.         else
    77.         {
    78.             Debug.Log(string.Format("Anchor {0} successfully saved", gameObject.name));
    79.             SetColor(sphere, Color.green);
    80.             return true; //return true, because everything went all right
    81.         }
    82.         }
    83.         else
    84.         Debug.LogWarning(string.Format("Anchor {0} NOT saved because there's no access to the store", gameObject.name));
    85.  
    86.         //if we're here, we failed somehow
    87.         return false;
    88.     }
    89.  
    90.     public bool LoadAnchor()
    91.     {
    92.         //load the anchor of this object if available
    93.  
    94.         if(store != null)
    95.         {        
    96.         //get current world anchor (if it doesn't exist, add it)
    97.         WorldAnchor anchor = gameObject.GetComponent<WorldAnchor>();
    98.  
    99.         if(anchor != null)
    100.             DestroyImmediate(anchor);
    101.  
    102.         //load the anchor from the store
    103.         if(!store.Load(gameObject.name, gameObject))
    104.         {
    105.             Debug.LogWarning(string.Format("Anchor {0} NOT loaded", gameObject.name));
    106.             SetColor(sphere, Color.red);
    107.         }
    108.         else
    109.         {
    110.             Debug.Log(string.Format("Anchor {0} successfully loaded", gameObject.name));
    111.             SetColor(sphere, Color.green);
    112.             return true; //return true, because everything went all right
    113.         }
    114.         }
    115.         else
    116.         {
    117.         Debug.LogWarning(string.Format("Anchor {0} NOT loaded because there's no access to the store", gameObject.name));
    118.         SetColor(sphere, Color.yellow);
    119.         }
    120.  
    121.         //if we're here, we failed somehow
    122.         return false;
    123.     }
    124. }
     

    Attached Files:

  2. Unity_Wesley

    Unity_Wesley

    Unity Technologies

    Joined:
    Sep 17, 2015
    Posts:
    558
    Hello,

    I believe your going to have to do the setup on the Hololens with a deployed app. In remoting you are only streaming data back and forth from the hololens to the editor, I'm unsure how you would try grab the store from the editor and move it to the hololens.

    I can ask a few questions with the team, but I think they will give a similar answer.

    This might help be able to transfer the world anchors to the hololens.
    https://docs.unity3d.com/ScriptReference/VR.WSA.Sharing.WorldAnchorTransferBatch.html
    https://forums.hololens.com/discussion/3445/world-anchor-sharing-unity

    Let us know if you have questions.
     
  3. francescoStrada

    francescoStrada

    Joined:
    Oct 27, 2014
    Posts:
    5
    first of all, thank you for the prompt reply. To comment your reply, we already tried as a workaround to save locally in the editor the worldanchors with transfer batch, and then load them at startup in the deployed version. However, apparently it is not possible to use WorldAnchorTransferBatch from within the editor, as we always get the following error: "SpatialAnchorTransferManager denied access to WorldAnchor serialization". (see attached code)

    Another option could be to send a message to the hololens asking to store locally (on the hololens) the world anchors (again with transfer batch), but, honestly, we have no idea how to do that. Do you have any suggestion?

    Currently, our best option is to make a stub, deployed on the hololens, which communicates with unity editor: you place an anchor in the hololens, the stub send a message to the editor which creates the anchor you can modify. When done, you send from the editor a message to the stub to ask it to serialize the worldanchors, which are then loaded at startup by the deployed app that has to use them.

    As you can see, the process is far from straighforward and we were hoping to find a simpler workaround...
     

    Attached Files:

  4. Unity_Wesley

    Unity_Wesley

    Unity Technologies

    Joined:
    Sep 17, 2015
    Posts:
    558
    I'm not sure what the best way to handle this use case would be, I will see if anyone the team could provide more information.
     
  5. Stracx

    Stracx

    Joined:
    May 5, 2017
    Posts:
    1
    Hello,

    Have you found any good solutions yet? I'm currently having the same problem.

    Thanks in advance
     
  6. unity_andrewc

    unity_andrewc

    Unity Technologies

    Joined:
    Dec 14, 2015
    Posts:
    220
    I got word back from some Microsoft that this simply isn't supported. It's a problem in the APIs they provide and not a problem with Unity.