Mixedrealitytoolkit-unity: Sharing with Unet: spawned objects rotation and position based on user starting position

Created on 21 Sep 2017  路  18Comments  路  Source: microsoft/MixedRealityToolkit-Unity

Project Summary

I basically have gotten the Sharing with unet example and added a different command to spawn an object into the scene as well as add a script to move the object around the scene. This works correctly when hosting with HoloLens and Unity editor as client.

Problem

The only problem I have is when I add another HoloLens as a client the spawned objects are offset in rotation and position based on where the client started the application in reference to the host. For example, if the host starts the application facing one way and the client faces 180 degrees in the opposite direction to start their application when they spawn an object it is offset by 180 degrees. Could this be something wrong on my end or something else entirely? Am I missing something?

Note

The players and text mesh import fine when starting the application and are in the correct position. It is only the spawned objects that their positions are offset.

Question

All 18 comments

Have you tried it without the editor connected? I had a similar problem recently at that seemed to help

Yes I have tried without the editor connected. It was just quicker to develop with deploying to only one HL instead of deploying to two every time. That's why I only noticed something wrong when I tried to do just the two HL.

I have a partner that is trying to do basically the same thing and we both have ran into this problem.

Are you using the sync object base class for you data model, or are you using the custom messages class?

[Edit] Does not pertain to this issue.

neither. All I did is basically copy the net bullet prefab from the example except made it a capsule instead and got rid of the velocity so that it just spawns in front of the player. The only thing that I can tell is that the clients anchor is not the same as the host's anchor. Because if I spawn the capsule with the same transform as the parent (Hologram Collection) after the import is completed it spawns on top of where the clients initial text mesh was located before import.

Oh sorry I read the issue wrong. I know nothing about the uNet stuff.

I found this on the Microsoft website:

After a GameObject is locked via the LockObject call, it will have a WorldAnchor which will keep it in the same physical position in the world, but it may be at a different location in the Unity coordinate space than other users.

Is there a way around this in order to make it have the same Unity coordinate space?

https://developer.microsoft.com/en-us/windows/mixed-reality/shared_experiences_in_unity

So I eventually figured this out, I feel like this was a noob mistake but, just like when calculating the player's transform via the shared anchor transform using inverse transform point. I had to do the same with the object that I spawned whenever I moved it.

That's great to hear!

So is this issue resolved then?

Yes

Hey @dtb49 I seem to be having the same issue as you. I am fairly new to unity and brand new to networking do you think you could elaborate on how you solved the issue? How did you ensure that the new spawned object was using a transform relative to the anchor?

@JakeMinerva Below is a link to a question where I elaborated on the answer a little more. I attached that script to my object prefab I was spawning. I'm pretty sure there is also a script in the HoloToolKit now that is similar to what I did, called UNetSharedHologram.cs.

Link:
https://forums.hololens.com/discussion/8574/sharing-with-unet-client-hololens-rotation-is-off

Basically, you want to use the Shared Anchor's position and set your object's position relative to it because that point is the same for both HoloLens. In order to do that you do something like this:

localPosition = sharedAnchorTrans.InverseTransformPoint(objPos);

This gets a little more complicated when you want the players to be able to move the objects themselves because you start getting into Authority. SO what the script says is: if you have authority over this object you want to send that position to the server relative to the shared Anchor's position. Otherwise, you just want to set it equal to the localPosition variable that is on the server.

This link doesn't really go into how I assigned authority but, what I basically did was when the user clicks I performed a Raycast and if it hit an object that was movable(tag/layer) then I would check if someone had authority over it or not, if not then I would assign authority to the player. Since you said you were new to Unity and Networking I would definitely look at some basic Unity and Unity Multiplayer Networking Tutorials.

@dtb49 thank you very much for the link and the advice, it has helped me alot. I am curious if you have any tips for syncing a bool across the network. My attempt so far has been to put the following into the player controller script.

    [SyncVar]
    public bool chunkToggle = true; 

    [Command]                                                                                      
    public void CmdSharedBool() {
        if (isLocalPlayer)
        {
            chunkToggle = !chunkToggle;
        }
    }

And then to call the CmdSharedBool function from another script using a trigger.
It works on the host but is not being shared to the client.
I appreciate any advice or places to look for further information.

So the reason it is only working for the server and not the client is because all a Command does is perform the method on the server. In order for all the other clients to get this bool change you have to send it to them. If you are trying to send it to all of the clients then I would do something like this below.


[Command]                                                                                      
    public void CmdSharedBool()
 {
       RpcSharedBool();       
 }

[ClientRpc]
public void RpcSharedBool()
{
    if(isLocalPlayer)
           chunkToggle = !chunkToggle;
}

Thanks for the input but that did not work. I have been reading up on ClientRpc functions and it makes sense to use one but there arent any used in the player script but the location data for the avatars is being shared. So I am curious how that works. Also any other ideas on why the boolean is not sharing would be much appreciated. Thanks for all your help!

Maybe take out the if isLocalPlayer and just change it directly and see if that works. I'm thinking back now and I don't think that you can use that in an rpc function and since you are changing it for everything I don't think it matters. Honestly, its been a couple months since working with multiplayer last haha

The player script uses SyncVars and Hooks to share their information much like the script from the one referenced above. You can try that and see if it works too.

If you don't quite understand the concepts of how multiplayer works I would definitely take a look at some tutorials, they can be really helpful, because it is a different way of thinking as far as your normal programmer would think about developing a single player game.

Also try and perform a debug inside the rpc function and make sure that the function is getting called on all the clients. You can put one in the Cmd too but, remember that it will only output on the server.

I got it!!! Thanks for all the help, it turned out to be more of an issue with what I was doing with the changed bool rather than an issue with the command or the Rpc. So instead of using a bool check in the update loop I used the command and the Rpc to directly toggle the game object on and off.
But anyhow your tips were what gave me the momentum to figure it all out.

Was this page helpful?
0 / 5 - 0 ratings