UI NetworkObject Parenting ignores `SetParent` `worldPositionStays`
See original GitHub issueDescription
When using SetParent
on Server for UI, Client ignores the worldPositionStays
param, throws a warning: Parent of RectTransform is being set with parent property
Reproduce Steps
- Start Server
- Start Client, connect to Server
- On Server: Instantiate and Spawn Canvas with Network Object (
_parentInstance
):
_parentInstance = Instantiate(_parent);
_parentNetworkObject = _parentInstance.GetComponent<NetworkObject>();
_parentNetworkObject.Spawn();
- On Server: Instantiate and Spawn Image with Network Object (
_childInstance
):
_childInstance = Instantiate(_child);
_childNetworkObject = _childInstance.GetComponent<NetworkObject>();
_childNetworkObject.Spawn();
- On Server: set
_parentInstance
as parent of_childInstance
, withworldPositionStays
param set tofalse
:
_childInstance.transform.SetParent(_parentInstance.transform, worldPositionStays: false);
Actual Outcome
- ✅ On Server: Image is placed at the center of Canvas
- ❌ On Client: Image is placed at the bottom left of Canvas, as if it ignored the
worldPositionStays: false
Expected Outcome
- ✅ On Server: Image is placed at the center of Canvas
- ✅ On Client: Image is placed at the center of Canvas
Environment
- OS: macOS Monterey
- Unity Version: 2021.3.2f1
- Netcode Version: 1.0.0
- ParrelSync: 1.5.1
Additional Context
Full warning stack trace:
Parent of RectTransform is being set with parent property. Consider using the SetParent method instead, with the worldPositionStays argument set to false. This will retain local orientation and scale rather than world orientation and scale, which can prevent common UI scaling issues.
UnityEngine.Transform:set_parent (UnityEngine.Transform)
Unity.Netcode.NetworkObject:ApplyNetworkParenting () (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0/Runtime/Core/NetworkObject.cs:739)
Unity.Netcode.NetworkObject:OnTransformParentChanged () (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0/Runtime/Core/NetworkObject.cs:667)
SampleSpawner:SpawnUI () (at Assets/Scripts/SampleSpawner.cs:33)
SampleSpawner:OnNetworkSpawn () (at Assets/Scripts/SampleSpawner.cs:17)
Unity.Netcode.NetworkBehaviour:InternalOnNetworkSpawn () (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0/Runtime/Core/NetworkBehaviour.cs:438)
Unity.Netcode.NetworkObject:InvokeBehaviourNetworkSpawn () (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0/Runtime/Core/NetworkObject.cs:767)
Unity.Netcode.NetworkSpawnManager:SpawnNetworkObjectLocallyCommon (Unity.Netcode.NetworkObject,ulong,bool,bool,ulong,bool) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0/Runtime/Spawning/NetworkSpawnManager.cs:552)
Unity.Netcode.NetworkSpawnManager:SpawnNetworkObjectLocally (Unity.Netcode.NetworkObject,ulong,bool,bool,ulong,bool) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0/Runtime/Spawning/NetworkSpawnManager.cs:453)
Unity.Netcode.NetworkObject:SpawnInternal (bool,ulong,bool) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0/Runtime/Core/NetworkObject.cs:425)
SampleNetworkController:SpawnController () (at Assets/Scripts/SampleNetworkController.cs:21)
UnityEngine.EventSystems.EventSystem:Update () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:501)
I attach a barebones Unity Project to illustrate this. It uses ParrelSync to simulate a Client (I’ve tried making an actual macOS build, it changes nothing).
Steps to reproduce in project
- Open 2 Instances of the Project using ParrelSync, or make a build, which would act as Instance 2
- Open SampleScene
- Project Instance 1 (Server): start Server via “Start Server” UI button
- Project Instance 2 (Client): start Client via “Start Client” UI button
- Project Instance 1 (Server): click “Spawn Controller” UI button, which:
- spawns “Controller” prefab
- “Controller” instance
OnNetworkSpawn
method does the steps in Reproduce Steps section above
You should see the Image parented into Canvas in different spots on Server and Client.
Issue Analytics
- State:
- Created a year ago
- Comments:13 (6 by maintainers)
Top Results From Across the Web
Child UI world position shifted after parenting to a ...
- To keep the local orientation when parenting, use the overloaded version of SetParent() with "worldPositionStays" set to false.
Read more >NetworkObject Parenting
It's recommended to always use the NetworkObject.TrySetParent method when parenting if you plan on changing the WorldPositionStays default value ...
Read more >How to parent a NetworkObject in Netcode. For holding ...
I want to be able to pickup, hold, drop, or use the item while it is in the players hand. I have tried...
Read more >unity - Object scaling when parenting by script
SetParent (parent, false) to keep the object's local position, rotation, and scale unchanged when reparenting it: public void SetParent(Transform ...
Read more >parent of recttransform is being set with parent property.
Consider using the SetParent method instead, with the worldPositionStays argument set to false. It even tells you why ... Quote:.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@NoelStephensUnity Thank you, just tested, it works on my side too (from that branch).
I’ll text here if I find anything not working related to this, but otherwise I believe this issue can be closed. 👍
@MtPython Just following up: Running your more complex setup from the following branch:
fix/parenting-does-not-preserve-worldpositionstays-option
Yields the following results: (if you want to use that branch for the time being, you will need to remove your NetworkTransforms) 👍