Skip to content

Multiple re-parents and Teleport() calls on NetworkTransform corrupts In Local Space position #3653

@zachstronaut

Description

@zachstronaut

Description

If you use NetworkObject.TrySetParent() and NetworkTransform.Teleport() multiple times in the same frame and the NetworkTransform is InLocalSpace, the position data will get corrupted and out of sync between clients.

Repro is very straightforward!

ParrelSync with simulated 750ms lag so you can more easily see the problem.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Netcode;
using Unity.Netcode.Components;

public class Bug0000 : NetworkBehaviour
{
    public Transform position1; // None of these Transforms should be at world (0,0,0)
    public Transform position2;
    public Transform position3;
    public Transform parent1;
    public Transform parent2;
    public GameObject prefab;

    void SpawnBug()
    {
        var temp = GameObject.Instantiate(prefab, position1.position, Quaternion.identity) as GameObject;

        NetworkObject networkObj = temp.GetComponent<NetworkObject>();
        networkObj.SpawnWithOwnership( NetworkManager.ServerClientId );

        networkObj.TrySetParent( parent1 );

        Bug0000Move(networkObj, position2.position);

        networkObj.TrySetParent( parent2 );

        Bug0000Move(networkObj, position3.position);
    }

    void Bug0000Move(NetworkObject networkObj, Vector3 pos)
    {
        NetworkTransform netTransform = networkObj.GetComponent<NetworkTransform>();
        Debug.Assert(netTransform.InLocalSpace);
        var newPos = netTransform.transform.parent.InverseTransformPoint(pos);
        netTransform.Teleport(newPos, networkObj.transform.rotation, networkObj.transform.localScale);
    }
}
Image

The spawned object will end up in the incorrect position on the screen on the non-host client, and the incorrect position will persist indefinitely until the object is moved.

It appears to me that NetworkTransform:AdjustForChangeInTransformSpace() -- called via NetworkTransform:UpdateInterpolation () via NetworkTransform:OnUpdate() -- calculates an incorrect m_InternalCurrentPosition and therefore ApplyAuthoritativeState() moves the object to the wrong position.

If you run this repro case with the spawned object owner instead being the non-host, the same bug occurs but it resolves itself with an interpolation rather than persisting indefinitely.

Environment

OS: Windows 11
Unity Version: 6000.1.3f1
Netcode Version: 2.4.2
Netcode Topology: Client-Server

Metadata

Metadata

Labels

stat:InvestigatingIssue is currently being investigatedstat:awaiting-triageStatus - Awaiting triage from the Netcode team.stat:reply-neededAwaiting reply from Unity accounttype:bugBug Report

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions