I am using SyncLists and I notice they throw errors when I use them during the Awake() method. This seems to be new to 5.2. Anybody else having this problem?
The flow I’d like to achieve is:
-Instantiate object on server
-Set SyncVar’s during server Awake()
-Spawn object on client. All SyncVar’s should be set by the spawn so correct values are there when OnStartClient() is called… this is why I’m trying to set SyncVar’s during Awake() and not Start()
using UnityEngine;
using System.Collections;
using UnityEngine.Networking; //needed for NetworkBehavior
public class TestSyncListAwake : NetworkBehaviour
{
private SyncListInt syncListIntTest = new SyncListInt();
private void Awake()
{
syncListIntTest.Add(5); //this causes error "SyncList not initialized"!!!!
}
private void Start()
{
syncListIntTest.Add(3); //this works fine without error
}
}
I’ve found Awake isn’t safe for other UNet things too, such as isServer. Though I noticed this before 5.2, and have generally adapted to use Start for any initialization reliant on the network.
Might be really handy to see an updated version of the Unity Execution Order doc, with UNet and UnityUI referenced.
Thanks for link. I agree with the object creation flow and I’m trying to do that, but running into “SyncList not initialized” errors when attempting to set SyncList values during Awake() on the server before spawning. See picture below. I’m not sure the proper way to handle this.
If I set SyncList during Awake() it throws “SyncList not initialized” error
If I set SyncList with external initialization function (called immediately after instantiate) it throws “SendBytesToReady object TestPrefab(Clone) (UnityEngine.GameObject) has not been spawned” warning.
If I set SyncList during Start() the SyncList will not be set before spawning unless somehow I add a frame or two delay between instantiate and spawn.
What’s the proper way to set SyncList before spawning?
So I’ve been doing some more testing and found something that works (although it throws error messages). My current flow is to.
1: Instantiate prefab on server
2: During prefab server Awake() method I set the SyncList (this throws “SyncList not initialized” errors… but functionally works just fine!)
3: Spawn prefab on clients (they get the proper SyncList values)
I tried an initialization function called externally to the prefab after Awake() but before Start(). This throws “SendBytesToReady object TestPrefab(Clone) (UnityEngine.GameObject) has not been spawned” warnings.
I am not sure why it is throwing warnings when setting SyncList before spawning, because that is the intended flow from my understanding.
SyncValues don’t seem to initialize until OnStartClient is called, which is called after Awake but before Start (typically, anyway). I get around this by either creating my own “Init” function which I call OnStartClient, or by feeding the variables to another controller object for storage.
I think I figured out the proper order to initialize.
For SceneObjects
The order things are called
Server.Awake()
Server.OnStartClient()
Server.Start()
—at some point here the object is “Spawned” automatically on the client
Client.OnStartClient()
Client.Start()
SyncVars/SyncList should be set during Server.OnStartClient() or Server.Start(). If you set them during Awake() or through external initialization before OnStartClient then it causes errors. Even if the SyncVars/SyncList values are set during Server.Start() the correct values are replicated to the client by the time Client.Start() is called.
For SpawnedObjects the correct order seems to be
-Spawn prefab on server
-During server prefab Start() or OnStartClient() set the SyncVars/SyncList values
-At the end of server Start() call NetworkServer.Spawn(gameObject). Do NOT call spawn externally before prefab.Start() is called or the SyncVars/SyncList values will not be initialized.
-The SyncVars/SyncList values will be correct by the time Client.Start() is called.
Am I missing something? How do you do an initialization function call on the object of SyncLists before it is spawned in? Or am I thinking too hard on this?