Hello everyone.

The Mixed Reality Forums here are no longer being used or maintained.

There are a few other places we would like to direct you to for support, both from Microsoft and from the community.

The first way we want to connect with you is our mixed reality developer program, which you can sign up for at https://aka.ms/IWantMR.

For technical questions, please use Stack Overflow, and tag your questions using either hololens or windows-mixed-reality.

If you want to join in discussions, please do so in the HoloDevelopers Slack, which you can join by going to https://aka.ms/holodevelopers, or in our Microsoft Tech Communities forums at https://techcommunity.microsoft.com/t5/mixed-reality/ct-p/MicrosoftMixedReality.

And always feel free to hit us up on Twitter @MxdRealityDev.

Share anchors across scenes and holograms

nashnash ✭✭
edited June 2016 in Questions And Answers

I have a use case where I'm switching between scenes. In scene 1 the user places a menu hologram. we want to create an anchor at the location they place that menu and use it in the next scenes as the starting point for each scene. There is a 'main' hologram that we would place at that point that everything would build around.

I'm trying to get it working using world anchors and while i can get the anchor created on menu placement im not having any success in the next scene using that world anchor as the starting point for the scene.

any samples would be greatly appreciated.

This is used to create the world anchor

public class MenuPlacement : Singleton<MenuPlacement>
{

    public bool IsPlaced { get; private set; }
    private bool animationPlayed = false;
    private WorldAnchorStore _Store;

    // Use this for initialization
    void Start()
    {
        WorldAnchorStore.GetAsync(AnchorStoreLoaded);
    }

    // Update is called once per frame
    void Update()
    {
        if (IsPlaced)
        {
            if (!animationPlayed)
            {
                GetComponent<MenuBase>().SendMessage("Animate");
                animationPlayed = true;
                CreateWorldAnchor();
            }
        }
        else
        {
            transform.position = Vector3.Lerp(transform.position, GetPosition(), 0.2f);
        }
    }

    void CreateWorldAnchor()
    {
        if (_Store == null)
            return;

        var anchor = GetComponent<WorldAnchor>();
        if (anchor == null)
            anchor = gameObject.AddComponent<WorldAnchor>();

        if(anchor.isLocated)
        {
            _Store.Save(Constants.MenuAnchor, anchor);
        }
        else
        {
            anchor.OnTrackingChanged += Anchor_OnTrackingChanged_InitialAnchor;
        }
    }

    private void Anchor_OnTrackingChanged_InitialAnchor(WorldAnchor self, bool located)
    {
        if (located)
        {
            _Store.Save(Constants.MenuAnchor, self);
        }
        else
        {
            Debug.Log("Failed to locate anchor");
        }

        self.OnTrackingChanged -= Anchor_OnTrackingChanged_InitialAnchor;
    }

    void AnchorStoreLoaded(WorldAnchorStore store)
    {
        _Store = store;
    }

    public void OnSelect()
    {
        IsPlaced = true;
    }

    Vector3 GetPosition()
    {
        //Have to account for the origin being off on this model
        var position = Camera.main.transform.position;
        return position + Camera.main.transform.forward * 2;
    }
}

This is put on the gameObject in the scenes after the menu

public class AnchorToMenu : MonoBehaviour
{

    WorldAnchorStore _Store;
    bool _Anchored;

    // Use this for initialization
    void Start()
    {
        WorldAnchorStore.GetAsync(AnchorStoreReady);
    }

    void AnchorStoreReady(WorldAnchorStore store)
    {
        _Store = store;
    }

    // Update is called once per frame
    void Update()
    {
        if (!_Anchored)
        {
            var anchor = _Store.Load(Constants.MenuAnchor, gameObject);

            if (!anchor.isLocated)
            {
                anchor.OnTrackingChanged += AnchorManager_OnTrackingChanged_Attaching;
            }

            _Anchored = true;
        }
    }

    private void AnchorManager_OnTrackingChanged_Attaching(WorldAnchor self, bool located)
    {
        Debug.Log("anchor " + located);

        self.OnTrackingChanged -= AnchorManager_OnTrackingChanged_Attaching;
    }
}
Tagged:

Answers

  • ConleyCWConleyCW
    edited June 2016

    I'm working on a multi scene project where in the first scene you place objects around the room. There's UI buttons which you click on to start the main scene. I have a simple "Don't destroy on Load" script which I will attach below which maintains the objects to the next scene, however, their placement moves significantly once I load the main scene. I've tried looking at the world anchors page to see how to utilize them but I have been competeley unsuccesfull in my attempts. If you have any examples from your own projects that match my problem please help me. Thank you!

    The "Don't destroy on load" script:
    public class DontDestroyOnLoad : MonoBehaviour
    {
    public int currentLevel = 0;

    void Start()
    {
        DontDestroyOnLoad(gameObject);
    }
    void update()
    {
    
    }
    

    }

  • You might want to take a look at how GalaxyExplorer does its scene management. Consider loading your scene(s) additively and keeping your Anchors alive in your base/root scene.

  • In addition to what Tim suggested, you can also look at the Sharing test scene in HoloToolkit-Unity for how we persist anchors even if all the clients are out of the session. As long as you have the same session ID and area this could work for you as well.

    From ImportExportAnchorManager.cs:

    // To keep anchors alive even if all users have left the session ...
    240 // Pass in true instead of false in CreateRoom.
    241 currentRoom = roomManager.CreateRoom(new XString("DefaultRoom"), roomID, false);

Sign In or Register to comment.