Skip to content

fix: Parenting does not preserve WorldPositionStays option and other parenting related issues #2146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
611aed6
fix
NoelStephensUnity Aug 17, 2022
e0164c4
fix
NoelStephensUnity Aug 18, 2022
9f5d7ec
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Aug 18, 2022
15fa292
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Aug 24, 2022
413e5ff
style
NoelStephensUnity Aug 24, 2022
05a2e92
style
NoelStephensUnity Aug 24, 2022
e7b1ec6
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Aug 24, 2022
9a92f3a
Update-JOlmer-Suggestions
NoelStephensUnity Aug 24, 2022
f2ad223
Update-JOlmer-Suggestion-2
NoelStephensUnity Aug 24, 2022
2e9b2bb
update
NoelStephensUnity Aug 24, 2022
02b281e
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Aug 24, 2022
4eb3665
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Aug 25, 2022
1b6656e
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Sep 8, 2022
84b18b5
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Sep 8, 2022
9fa5e0b
fix
NoelStephensUnity Sep 9, 2022
80d1af5
test
NoelStephensUnity Sep 9, 2022
c798c47
update
NoelStephensUnity Sep 9, 2022
3704e84
test update
NoelStephensUnity Sep 9, 2022
d24443b
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Sep 9, 2022
eca807d
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Sep 14, 2022
1250f30
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Sep 14, 2022
8d18c1d
update
NoelStephensUnity Sep 14, 2022
80de0e9
fix
NoelStephensUnity Sep 14, 2022
1ef4c63
style
NoelStephensUnity Sep 15, 2022
babd4a2
fix
NoelStephensUnity Sep 15, 2022
d478169
test
NoelStephensUnity Sep 15, 2022
ae8fade
update
NoelStephensUnity Sep 15, 2022
5016303
update
NoelStephensUnity Sep 15, 2022
2e43737
style
NoelStephensUnity Sep 15, 2022
95ae7bb
fix
NoelStephensUnity Sep 15, 2022
c735a38
update
NoelStephensUnity Sep 15, 2022
2d98f75
refactor
NoelStephensUnity Sep 15, 2022
76c0e85
fix
NoelStephensUnity Sep 16, 2022
d7384b4
style
NoelStephensUnity Sep 16, 2022
e767757
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Sep 19, 2022
505b27b
update
NoelStephensUnity Sep 19, 2022
0408358
update
NoelStephensUnity Sep 20, 2022
839ff2e
update
NoelStephensUnity Sep 20, 2022
0b7b3ae
update
NoelStephensUnity Sep 20, 2022
8ea66a8
update
NoelStephensUnity Sep 21, 2022
2488249
style
NoelStephensUnity Sep 21, 2022
19a291d
update
NoelStephensUnity Sep 21, 2022
0532a4f
update
NoelStephensUnity Sep 21, 2022
7817eb1
fix
NoelStephensUnity Sep 23, 2022
02de172
test updates
NoelStephensUnity Sep 23, 2022
1e19f30
update
NoelStephensUnity Sep 23, 2022
98318cf
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Sep 23, 2022
fdbad87
style
NoelStephensUnity Sep 23, 2022
0a1558f
test update
NoelStephensUnity Sep 23, 2022
b2e4516
update
NoelStephensUnity Sep 23, 2022
a7b1e72
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Sep 23, 2022
aab4980
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Sep 23, 2022
aecb750
update
NoelStephensUnity Sep 23, 2022
46eb1ef
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Sep 23, 2022
0a74e63
test update
NoelStephensUnity Sep 23, 2022
1a87cdb
fix
NoelStephensUnity Sep 23, 2022
c659916
style
NoelStephensUnity Sep 23, 2022
4a60e1b
test
NoelStephensUnity Sep 23, 2022
0a3f0d8
style
NoelStephensUnity Sep 23, 2022
1972488
fix
NoelStephensUnity Sep 27, 2022
289bf72
test in-scene placed
NoelStephensUnity Sep 27, 2022
a51ae69
update
NoelStephensUnity Sep 27, 2022
719ffa2
update and style
NoelStephensUnity Sep 27, 2022
1ab8128
test
NoelStephensUnity Sep 27, 2022
30ba251
update
NoelStephensUnity Sep 27, 2022
0adc908
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Sep 27, 2022
b9fb55b
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Sep 27, 2022
45e8c8d
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Sep 28, 2022
da1372b
style
NoelStephensUnity Sep 28, 2022
682c020
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Sep 28, 2022
058f401
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Sep 28, 2022
dc54216
style
NoelStephensUnity Sep 28, 2022
89a50a4
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Sep 30, 2022
7e5bcd3
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Oct 1, 2022
c13b3f2
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Oct 3, 2022
59cf57a
Merge branch 'develop' into fix/parenting-does-not-preserve-worldposi…
NoelStephensUnity Oct 3, 2022
e6d654c
style
NoelStephensUnity Oct 3, 2022
4db2627
update
NoelStephensUnity Oct 4, 2022
9ab7199
Merge develop into fix/parenting-does-not-preserve-worldpositionstays…
netcode-ci-service Oct 4, 2022
956d331
Merge develop into fix/parenting-does-not-preserve-worldpositionstays…
netcode-ci-service Oct 4, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions com.unity.netcode.gameobjects/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ Additional documentation and release notes are available at [Multiplayer Documen

- IPv6 is now supported for direct connections when using `UnityTransport`. (#2232)
- Added WebSocket support when using UTP 2.0 with `UseWebSockets` property in the `UnityTransport` component of the `NetworkManager` allowing to pick WebSockets for communication. When building for WebGL, this selection happens automatically. (#2201)
- Added position, rotation, and scale to the `ParentSyncMessage` which provides users the ability to specify the final values on the server-side when `OnNetworkObjectParentChanged` is invoked just before the message is created (when the `Transform` values are applied to the message). (#2146)
- Added `NetworkObject.TryRemoveParent` method for convenience purposes opposed to having to cast null to either `GameObject` or `NetworkObject`. (#2146)

### Changed

Expand All @@ -33,6 +35,11 @@ Additional documentation and release notes are available at [Multiplayer Documen
- Implicit conversion of NetworkObjectReference to GameObject will now return null instead of throwing an exception if the referenced object could not be found (i.e., was already despawned) (#2158)
- Fixed warning resulting from a stray NetworkAnimator.meta file (#2153)
- Fixed Connection Approval Timeout not working client side. (#2164)
- Fixed issue where the `WorldPositionStays` parenting parameter was not being synchronized with clients. (#2146)
- Fixed issue where parented in-scene placed `NetworkObject`s would fail for late joining clients. (#2146)
- Fixed issue where scale was not being synchronized which caused issues with nested parenting and scale when `WorldPositionStays` was true. (#2146)
- Fixed issue with `NetworkTransform.ApplyTransformToNetworkStateWithInfo` where it was not honoring axis sync settings when `NetworkTransformState.IsTeleportingNextFrame` was true. (#2146)
- Fixed issue with `NetworkTransform.TryCommitTransformToServer` where it was not honoring the `InLocalSpace` setting. (#2146)
- Fixed ClientRpcs always reporting in the profiler view as going to all clients, even when limited to a subset of clients by `ClientRpcParams`. (#2144)
- Fixed RPC codegen failing to choose the correct extension methods for `FastBufferReader` and `FastBufferWriter` when the parameters were a generic type (i.e., List<int>) and extensions for multiple instantiations of that type have been defined (i.e., List<int> and List<string>) (#2142)
- Fixed the issue where running a server (i.e. not host) the second player would not receive updates (unless a third player joined). (#2127)
Expand Down
67 changes: 21 additions & 46 deletions com.unity.netcode.gameobjects/Components/NetworkTransform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -451,19 +451,6 @@ internal NetworkTransformState GetLastSentState()
return m_LastSentState;
}

/// <summary>
/// Calculated when spawned, this is used to offset a newly received non-authority side state by 1 tick duration
/// in order to end the extrapolation for that state's values.
/// </summary>
/// <remarks>
/// Example:
/// NetworkState-A is received, processed, and measurements added
/// NetworkState-A is duplicated (NetworkState-A-Post) and its sent time is offset by the tick frequency
/// One tick later, NetworkState-A-Post is applied to end that delta's extrapolation.
/// <see cref="OnNetworkStateChanged"/> to see how NetworkState-A-Post doesn't get excluded/missed
/// </remarks>
private double m_TickFrequency;

/// <summary>
/// This will try to send/commit the current transform delta states (if any)
/// </summary>
Expand All @@ -488,14 +475,16 @@ protected void TryCommitTransformToServer(Transform transformToCommit, double di
}
else // Non-Authority
{
var position = InLocalSpace ? transformToCommit.localPosition : transformToCommit.position;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noticed this while working on parenting with multi-generation nested children (there was a bug elsewhere it turned out). I went ahead and fixed it as I have more parenting integration tests I am working on that will be using this method when the parented NetworkObjects have a NetworkTransform too.

var rotation = InLocalSpace ? transformToCommit.localRotation : transformToCommit.rotation;
// We are an owner requesting to update our state
if (!m_CachedIsServer)
{
SetStateServerRpc(transformToCommit.position, transformToCommit.rotation, transformToCommit.localScale, false);
SetStateServerRpc(position, rotation, transformToCommit.localScale, false);
}
else // Server is always authoritative (including owner authoritative)
{
SetStateClientRpc(transformToCommit.position, transformToCommit.rotation, transformToCommit.localScale, false);
SetStateClientRpc(position, rotation, transformToCommit.localScale, false);
}
}
}
Expand All @@ -521,37 +510,24 @@ private void TryCommitTransform(Transform transformToCommit, double dirtyTime)
}
}

/// <summary>
/// Initializes the interpolators with the current transform values
/// </summary>
private void ResetInterpolatedStateToCurrentAuthoritativeState()
{
var serverTime = NetworkManager.ServerTime.Time;

// TODO: Look into a better way to communicate the entire state for late joining clients.
// Since the replicated network state will just be the most recent deltas and not the entire state.
//m_PositionXInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.PositionX, serverTime);
//m_PositionYInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.PositionY, serverTime);
//m_PositionZInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.PositionZ, serverTime);

//m_RotationInterpolator.ResetTo(Quaternion.Euler(m_LocalAuthoritativeNetworkState.RotAngleX, m_LocalAuthoritativeNetworkState.RotAngleY, m_LocalAuthoritativeNetworkState.RotAngleZ), serverTime);

//m_ScaleXInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.ScaleX, serverTime);
//m_ScaleYInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.ScaleY, serverTime);
//m_ScaleZInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.ScaleZ, serverTime);

// NOTE ABOUT THIS CHANGE:
// !!! This will exclude any scale changes because we currently do not spawn network objects with scale !!!
// Regarding Scale: It will be the same scale as the default scale for the object being spawned.
var position = InLocalSpace ? transform.localPosition : transform.position;
m_PositionXInterpolator.ResetTo(position.x, serverTime);
m_PositionYInterpolator.ResetTo(position.y, serverTime);
m_PositionZInterpolator.ResetTo(position.z, serverTime);

var rotation = InLocalSpace ? transform.localRotation : transform.rotation;
m_RotationInterpolator.ResetTo(rotation, serverTime);

// TODO: (Create Jira Ticket) Synchronize local scale during NetworkObject synchronization
// (We will probably want to byte pack TransformData to offset the 3 float addition)
m_ScaleXInterpolator.ResetTo(transform.localScale.x, serverTime);
m_ScaleYInterpolator.ResetTo(transform.localScale.y, serverTime);
m_ScaleZInterpolator.ResetTo(transform.localScale.z, serverTime);
var scale = transform.localScale;
m_ScaleXInterpolator.ResetTo(scale.x, serverTime);
m_ScaleYInterpolator.ResetTo(scale.y, serverTime);
m_ScaleZInterpolator.ResetTo(scale.z, serverTime);
}

/// <summary>
Expand Down Expand Up @@ -602,63 +578,63 @@ private bool ApplyTransformToNetworkStateWithInfo(ref NetworkTransformState netw
isDirty = true;
}

if (SyncPositionX && Mathf.Abs(networkState.PositionX - position.x) >= PositionThreshold || networkState.IsTeleportingNextFrame)
if (SyncPositionX && (Mathf.Abs(networkState.PositionX - position.x) >= PositionThreshold || networkState.IsTeleportingNextFrame))
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bug I found while debugging parent-child scale issues when the NetworkObject also had a NetworkTransform. I had turned the NetworkTransform scale synchronization flags (X, Y,Z) off but it seemed to keep updating them...which made me realize the initial state after 1 or 2 network ticks is a "teleport state"...which the previous logic (without the braces) would apply all axis whether marked to be synchronized or not.

{
networkState.PositionX = position.x;
networkState.HasPositionX = true;
isPositionDirty = true;
}

if (SyncPositionY && Mathf.Abs(networkState.PositionY - position.y) >= PositionThreshold || networkState.IsTeleportingNextFrame)
if (SyncPositionY && (Mathf.Abs(networkState.PositionY - position.y) >= PositionThreshold || networkState.IsTeleportingNextFrame))
{
networkState.PositionY = position.y;
networkState.HasPositionY = true;
isPositionDirty = true;
}

if (SyncPositionZ && Mathf.Abs(networkState.PositionZ - position.z) >= PositionThreshold || networkState.IsTeleportingNextFrame)
if (SyncPositionZ && (Mathf.Abs(networkState.PositionZ - position.z) >= PositionThreshold || networkState.IsTeleportingNextFrame))
{
networkState.PositionZ = position.z;
networkState.HasPositionZ = true;
isPositionDirty = true;
}

if (SyncRotAngleX && Mathf.Abs(Mathf.DeltaAngle(networkState.RotAngleX, rotAngles.x)) >= RotAngleThreshold || networkState.IsTeleportingNextFrame)
if (SyncRotAngleX && (Mathf.Abs(Mathf.DeltaAngle(networkState.RotAngleX, rotAngles.x)) >= RotAngleThreshold || networkState.IsTeleportingNextFrame))
{
networkState.RotAngleX = rotAngles.x;
networkState.HasRotAngleX = true;
isRotationDirty = true;
}

if (SyncRotAngleY && Mathf.Abs(Mathf.DeltaAngle(networkState.RotAngleY, rotAngles.y)) >= RotAngleThreshold || networkState.IsTeleportingNextFrame)
if (SyncRotAngleY && (Mathf.Abs(Mathf.DeltaAngle(networkState.RotAngleY, rotAngles.y)) >= RotAngleThreshold || networkState.IsTeleportingNextFrame))
{
networkState.RotAngleY = rotAngles.y;
networkState.HasRotAngleY = true;
isRotationDirty = true;
}

if (SyncRotAngleZ && Mathf.Abs(Mathf.DeltaAngle(networkState.RotAngleZ, rotAngles.z)) >= RotAngleThreshold || networkState.IsTeleportingNextFrame)
if (SyncRotAngleZ && (Mathf.Abs(Mathf.DeltaAngle(networkState.RotAngleZ, rotAngles.z)) >= RotAngleThreshold || networkState.IsTeleportingNextFrame))
{
networkState.RotAngleZ = rotAngles.z;
networkState.HasRotAngleZ = true;
isRotationDirty = true;
}

if (SyncScaleX && Mathf.Abs(networkState.ScaleX - scale.x) >= ScaleThreshold || networkState.IsTeleportingNextFrame)
if (SyncScaleX && (Mathf.Abs(networkState.ScaleX - scale.x) >= ScaleThreshold || networkState.IsTeleportingNextFrame))
{
networkState.ScaleX = scale.x;
networkState.HasScaleX = true;
isScaleDirty = true;
}

if (SyncScaleY && Mathf.Abs(networkState.ScaleY - scale.y) >= ScaleThreshold || networkState.IsTeleportingNextFrame)
if (SyncScaleY && (Mathf.Abs(networkState.ScaleY - scale.y) >= ScaleThreshold || networkState.IsTeleportingNextFrame))
{
networkState.ScaleY = scale.y;
networkState.HasScaleY = true;
isScaleDirty = true;
}

if (SyncScaleZ && Mathf.Abs(networkState.ScaleZ - scale.z) >= ScaleThreshold || networkState.IsTeleportingNextFrame)
if (SyncScaleZ && (Mathf.Abs(networkState.ScaleZ - scale.z) >= ScaleThreshold || networkState.IsTeleportingNextFrame))
{
networkState.ScaleZ = scale.z;
networkState.HasScaleZ = true;
Expand Down Expand Up @@ -1007,7 +983,6 @@ public override void OnNetworkSpawn()
{
m_CachedIsServer = IsServer;
m_CachedNetworkManager = NetworkManager;
m_TickFrequency = 1.0 / NetworkManager.NetworkConfig.TickRate;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯 nice unused variable


Initialize();

Expand Down
33 changes: 25 additions & 8 deletions com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2070,14 +2070,31 @@ internal void HandleConnectionApproval(ulong ownerClientId, ConnectionApprovalRe

if (response.CreatePlayerObject)
{
var networkObject = SpawnManager.CreateLocalNetworkObject(
isSceneObject: false,
response.PlayerPrefabHash ?? NetworkConfig.PlayerPrefab.GetComponent<NetworkObject>().GlobalObjectIdHash,
ownerClientId,
parentNetworkId: null,
networkSceneHandle: null,
response.Position,
response.Rotation);
var playerPrefabHash = response.PlayerPrefabHash ?? NetworkConfig.PlayerPrefab.GetComponent<NetworkObject>().GlobalObjectIdHash;

// Generate a SceneObject for the player object to spawn
var sceneObject = new NetworkObject.SceneObject
{
Header = new NetworkObject.SceneObject.HeaderData
{
IsPlayerObject = true,
OwnerClientId = ownerClientId,
IsSceneObject = false,
HasTransform = true,
Hash = playerPrefabHash,
},
TargetClientId = ownerClientId,
Transform = new NetworkObject.SceneObject.TransformData
{
Position = response.Position.GetValueOrDefault(),
Rotation = response.Rotation.GetValueOrDefault()
}
};

// Create the player NetworkObject locally
var networkObject = SpawnManager.CreateLocalNetworkObject(sceneObject);

// Spawn the player NetworkObject locally
SpawnManager.SpawnNetworkObjectLocally(
networkObject,
SpawnManager.GetNetworkObjectId(),
Expand Down
Loading