Server game object hierarchy is not the same as client game object hierarchy

Spawning game objects across the network is flaky, as I see it.

On the server, the object hierarchy is far more “different” than on the client side. As you can see, I spawn them in a nested way on the server, however, the client does not correspond to the nested spawning, and thus creates a different layout.

How do you organize them, so it is consistent on both the clients and the server? I tried prefabs, but they only work when game objects are inside a prefab. Multiple prefabs will break the layout.

I found out this the hard way. Now my project is close to a deadline, and my “severe Unity design flaw” stems out like this. I blame myself for not seeing this before when I had the chance, but I really wanted to fix this.

I wanted both the clients and the server to have consistent hierarchy when “spawning” the NetworkManager registered prefabs.

It’s frustrating to see this happening…

I had the same problem with my project, but it was happening the following:
On host:

  • Player1
    –Object1
  • Player2
    –Object2

And on client:
-Player1
-Object1
-Player2
–Object2

So on the host it was not being set in the correct position. One easy and fast way i’ve found to fix this was to create a StartCoroutine and wait for 5 seconds before initializing any object.

Can you post how you spawning this? Or these are just the player prefabs?

Yeah. We need to see more. It looks like you spawning things as children on the server, but not on the client. The only way I know this is possible, is if you Instantiate, then NetworkServer.Spawn …and then on the server make changes to the objects parentage.

Sorry about that. When I posted this thread, I was mad, and sleepy at 4AM.

This is the code I used for the test project:

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class CubeTest : NetworkBehaviour {
    public GameObject spawnParent;
    public GameObject unitUmbrella;

    // Use this for initialization
    void Start () {
     
    }
 
    // Update is called once per frame
    void Update () {
        if (Input.GetKeyUp(KeyCode.S)) {
            CmdTest();
        }
    }

    [ServerCallback]
    public void ServerStuff() {
        GameObject obj = MonoBehaviour.Instantiate(this.spawnParent) as GameObject;
        obj.transform.position = new Vector3(Random.Range(-10f, 30f), Random.Range(-10f, 30f), Random.Range(-10f, 30f));
        obj.transform.SetParent(unitUmbrella.transform);
        NetworkServer.SpawnWithClientAuthority(obj, this.connectionToClient);
        RpcTest();
    }

    [ClientCallback]
    public void ClientStuff() {
    }

    [ClientRpc]
    public void RpcTest() {
        if (!isLocalPlayer) {
            return;
        }

        Debug.Log("TEST>");
    }

    [Command]
    public void CmdTest() {
        ServerStuff();
    }
}

When you mentioned “…Instantiating the object, then NetworkServer.Spawn()…”, do they actually keep the hierarchy relations with one another? I kept experimenting to see if I can just spawn in with prefabs of similar hierarchical relations, and they sort of do. You can spawn in only up to 2 tiers in total, but you can’t spawn more than 2 tiers.

Can do this on the client when doing the same on the server:

  • Tier 1

  • Tier 2

  • Tier 1

  • Tier 2

Can’t do this on the client when doing the same on the server:

  • Tier 1

  • Tier 2

  • Tier 1

  • Tier 2

  • Tier 1

  • Tier 2

I don’t know if I’m doing it right through scripting. All I know is that I was mad because it severely broke and crippled my multiplayer game. :frowning: Probably never going to use GetComponentInChildren()…

I guess you need to do a clientRCP like the following (Adjusting to your hierarch)

[ClientRpc] //Server calls client
void RpcSetParent(GameObject instance)
{
instance.transform.parent = transform;
}

Call this one after obj.transform.setParent()

Tell me if it worked

I’ll go ahead and try. Once I know it’s working, I’ll come back and update.