Mirror: [SyncVar] GameObject race condition
Just gathering my findings here.
The bug:
Player.cs has [SyncVar] GameObject pet;
Pet.cs has [SyncVar] GameObject owner;
In other words: circular references.
Now this player+pet are spawned at another client, here is what happens:
- Player component is spawned. pet is set to that pet, which doesn’t exist yet (hence null)
- Pet component is spawned. owner is set to that player, which exists (see 1.). hence not null.
so instead of Player knowing Pet and Pet knowing Player, only Pet knows Player because it was spawned after Player. Player was spawned before Pet, so it doesn’t know Pet.
What weaver does right now:
for every [SyncVar] GameObject player; it creates:
- a
uint ___playerNetId; - a Networkplayer property that does this:
public GameObject Networkplayer
{
get
{
return this.player;
}
[param: In] set
{
this.SetSyncVarGameObject(value, ref this.player, 8388608UL, ref this.____playerNetId);
}
}
The get just returns the original variable. The set sets calls SetSyncVarGameObject which sets dirty and then sets the original variable.
3. replaces all player = ... (writes) in code with NetworkPlayer = ....
4. In PreStartClient() assigns Networkplayer = ClientScene.FindLocalObject(__playerNetId)
Solution 1
What it should do is to also replace all ... = player (reads) with ... = Networkplayer and in Networkplayer get return ClientScene.FindLocalObject(___playerNetId)
In other words: for every [SyncVar] GameObject test variable it should wrap get/set around the __testNetId field. The netId is just an int, it doesn’t matter when we receive it. The ‘get’ will simply return objects[netId] which is null if not spawned yet, or != null if spawned yet.
Solution 2 Spawn everything first. Then assign. Perhaps it’s already meant to do that but it doesn’t for some reason. The NetworkPlayer field is assigned in ‘PreStartClient()’ after all.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 18 (4 by maintainers)
@Abdel-Fattah-Radwan Please don’t necrobump old tickets, this ticket was from 2018/2019.
Please open a new ticket and reference this one. Thanks.
This is what it should look like in the end.
Might need a helper function so we don’t have to do all of that with the weaver.