Repository navigation
Client NetworkObjects experience Awake, Start, OnEnable, and TriggerEnter, CollisionEnter at world 0,0,0 upon instantiation #3553
Description
Activity
- addedtype:bugBug ReportBug Reportstat:awaiting-triageStatus - Awaiting triage from the Netcode team.Status - Awaiting triage from the Netcode team.stat:reply-neededAwaiting reply from Unity accountAwaiting reply from Unity account
on Jul 17, 2025 @zachstronaut
It is a good point, but it would most likely need to be a flag as to whether it did this or not (in order to not change the behavior so it doesn't cause other issues for other projects).Regarding the issue you are currently having, you can solve this 0,0,0 issue a few ways:
- Make the network prefab's default world space position be something other than 0, 0, 0.
- It will then instantiate with that position which will avoid the trigger and collision.
- Disable the collider on the network prefab as the default setting and enable it within
OnNetworkPreSpawn.- If using a Rigidbody, then you would want to default to not allowing gravity and then within
OnNetworkPreSpawnenable it if it isOnNetworkPreSpawn.
- If using a Rigidbody, then you would want to default to not allowing gravity and then within
- Exit early within the trigger and collider if the NetworkObject is not spawned.
- Assuming the trigger is a spawned object...otherwise see the previous two possibilities.
- Once feat: AttachableBehaviour and ComponentController #3518 has landed and in the next update, you could opt to:
- Use a
ComponentController. - Leave the
ComponentController's default starting state as enabled. - Add the collider(s) to the
ComponentController's components so its/their enabled/disable state(s) are synchronized/controlled. - Set the enabled state delay for each component entry on the
ComponentControllerto like 1-5ms (i.e. wait until next frame) - Set the enabled state for each collider as disabled on the prefab itself so when it is first instantiated it won't interact with anything.
- Use a
With the component controller approach, you wouldn't need to write any code to work around that issue.
The component controller will automatically set the starting state for all of the components registered with it when instantiated. Since each one would have a delay on the enabled side, it would wait until the delay period specified and then set the enabled state...which by that time theTransformshould have been updated to the position and rotation specified.- Make the network prefab's default world space position be something other than 0, 0, 0.
- addedstat:awaiting-responseAwaiting response from author. This label should be added manually.Awaiting response from author. This label should be added manually.and removedstat:reply-neededAwaiting reply from Unity accountAwaiting reply from Unity account
on Jul 17, 2025 - addedstat:InvestigatingIssue is currently being investigatedIssue is currently being investigatedstat:reply-neededAwaiting reply from Unity accountAwaiting reply from Unity accountand removedstat:awaiting-responseAwaiting response from author. This label should be added manually.Awaiting response from author. This label should be added manually.
on Jul 17, 2025 Thanks for the quick response. Changing the Transform on the prefab itself to not be 0,0,0 is not something I had thought of! We can do that or leave a custom patch in InstantiateNetworkPrefab for our copy of Netcode. The other solutions would have unknown knockons potentially with how our code currently expects colliders to be enabled or not.
Hmmm... would this fix my problem while not changing behavior for anybody else? Grabbing Transform values from networkPrefab?
internal NetworkObject InstantiateNetworkPrefab(GameObject networkPrefab, uint prefabGlobalObjectIdHash, Vector3? position, Quaternion? rotation) { Vector3 defaultPosition = position ?? networkPrefab.transform.position; Quaternion defaultRotation = rotation ?? networkPrefab.transform.rotation; var networkObject = UnityEngine.Object.Instantiate(networkPrefab, defaultPosition, defaultRotation).GetComponent<NetworkObject>(); // networkObject.transform.position = position ?? networkObject.transform.position; // networkObject.transform.rotation = rotation ?? networkObject.transform.rotation; networkObject.NetworkManagerOwner = NetworkManager; networkObject.PrefabGlobalObjectIdHash = prefabGlobalObjectIdHash; return networkObject; }Reacted by Noel Stephens- addedpriority:mediumThis issue has medium priority and may take some time to be resolvedThis issue has medium priority and may take some time to be resolvedstat:importStatus - Issue is going to be saved internallyStatus - Issue is going to be saved internallyand removedstat:awaiting-triageStatus - Awaiting triage from the Netcode team.Status - Awaiting triage from the Netcode team.stat:InvestigatingIssue is currently being investigatedIssue is currently being investigated
on Jul 29, 2025 - addedstat:importedStatus - Issue is tracked internally at UnityStatus - Issue is tracked internally at Unityand removedstat:importStatus - Issue is going to be saved internallyStatus - Issue is going to be saved internally
on Aug 4, 2025 - removedstat:reply-neededAwaiting reply from Unity accountAwaiting reply from Unity account
on Aug 19, 2025
Description
When a client spawns a
NetworkObjectviaNetworkSpawnManage.InstantiateNetworkPrefab()there is no position or rotation data passed intoUnityEngine.Object.Instantiate()and therefore the object is created at world 0,0,0. On a later line of code the position and rotation are assigned, after instantiation.This means
Awake,Start, andOnEnableare all called when at world 0,0,0 -- this is arguably expected and why you haveOnNetworkSpawn.However,
OnTriggerEnter(and probablyOnCollisionEnter) also fire for things at world 0,0,0. That problem is outside of the scope of theOnNetworkSpawnwarmup in my opinion.Developers should not have to write custom code to handle this problem when the position and rotation could simply be passed into the instantiation.
Environment