using Unity.Netcode; using UnityEngine; /// /// Per-avatar network glue on the spawned player. The local owner binds the scene singletons /// (GameModeManager, cameras) to itself via ; remote /// avatars stop simulating so their transform is driven purely by the NetworkTransform replication. /// Position-sync milestone: remote avatars still show their mesh/idle pose, just no local control. /// [RequireComponent(typeof(PlayerCharacterController))] [DisallowMultipleComponent] public class NetworkPlayerSetup : NetworkBehaviour { public override void OnNetworkSpawn() { var controller = GetComponent(); if (IsOwner) { var manager = FindFirstObjectByType(FindObjectsInactive.Include); if (manager) manager.BindLocalPlayer(controller); return; } // Remote avatar: NetworkTransform owns the transform here, so disable the local // simulation (input/movement) and the CharacterController's own depenetration. if (controller) controller.enabled = false; var cc = GetComponent(); if (cc) cc.enabled = false; // Owner cleanup: the concealment meter is a per-frame skinned-mesh bake + voxelization + // physics overlap whose result only feeds the LOCAL player (HUD / gameplay). A remote avatar's // concealment is computed on its own owner's machine, so running it here is pure wasted CPU. var concealment = GetComponentInChildren(true); if (concealment) concealment.enabled = false; // NOTE: SkinnedColliderBaker deliberately stays ENABLED on remotes. MeshPainter's stamp replay // (ApplyNetworkStamp -> DrawBrushGpu) rasterizes the baker's live, per-frame BakedMesh to map a // 3D brush placement into UV space; freezing the bake would mis-map replicated paint onto any // non-rest pose. Its bake is the necessary cost of correct remote paint, not wasted work. } }