Search Unity

Resolved Client network transform (C.N.T) does not collide with another C.N.T

Discussion in 'Netcode for GameObjects' started by CodeTrigger, Jan 12, 2024.

  1. CodeTrigger

    CodeTrigger

    Joined:
    Jul 26, 2018
    Posts:
    3
    I am doing an FPS to learn NFGO and when spawning two players are not able to collide with each other due to the aforementioned component, once it is deactivated the collision works again.

    I need the most beginner friendly solution to this problem, thanks!
     
  2. CodeTrigger

    CodeTrigger

    Joined:
    Jul 26, 2018
    Posts:
    3
    I solved the problem by making my own Network Transform adapted to my needs, I attach the code in case someone needs it, I am using the CharacterController to move my player, explanations are commented in the code. If anyone can optimize it I would appreciate it. Thank you!

    Code (CSharp):
    1. using UnityEngine;
    2. using Unity.Netcode;
    3.  
    4. [RequireComponent(typeof(CharacterMotor))]
    5. public class NetworkTransformCustom : NetworkBehaviour
    6. {
    7.  
    8.     [SerializeField] private bool _serverAuth;
    9.     [SerializeField] private float _cheapInterpolationTime = 0.1f;
    10.  
    11.     private NetworkVariable<PlayerNetworkState> _playerState;
    12.     private CharacterMotor motor;
    13.  
    14.     private void Awake()
    15.     {
    16.         motor = GetComponent<CharacterMotor>();
    17.  
    18.         var permission = _serverAuth ? NetworkVariableWritePermission.Server : NetworkVariableWritePermission.Owner;
    19.         _playerState = new NetworkVariable<PlayerNetworkState>(writePerm: permission);
    20.     }
    21.  
    22.     private void Update()
    23.     {
    24.         if (IsOwner) TransmitState();
    25.         else ConsumeState();
    26.     }
    27.  
    28.     #region Transmit State
    29.  
    30.     private void TransmitState()
    31.     {
    32.         var state = new PlayerNetworkState
    33.         {
    34.             Position = motor.transform.position,
    35.             Rotation = transform.rotation.eulerAngles
    36.         };
    37.  
    38.         if (IsServer || !_serverAuth)
    39.             _playerState.Value = state;
    40.         else
    41.             TransmitStateServerRpc(state);
    42.     }
    43.  
    44.     [ServerRpc]
    45.     private void TransmitStateServerRpc(PlayerNetworkState state)
    46.     {
    47.         _playerState.Value = state;
    48.     }
    49.  
    50.     #endregion
    51.  
    52.     #region Interpolate State
    53.  
    54.     private Vector3 _posVel;
    55.     private float _rotVelY;
    56.  
    57.     private void ConsumeState()
    58.     {
    59.         // Here you'll find the cheapest, dirtiest interpolation you'll ever come across. Please do better in your game
    60.         // 'TeleportPlayer' disable CharacterController, change the position of transform with 'transform.position = newPosition' and enable the controller
    61.         motor.TeleportPlayer(Vector3.SmoothDamp(motor.transform.position, _playerState.Value.Position, ref _posVel, _cheapInterpolationTime));
    62.  
    63.         transform.rotation = Quaternion.Euler(
    64.             0, Mathf.SmoothDampAngle(transform.rotation.eulerAngles.y, _playerState.Value.Rotation.y, ref _rotVelY, _cheapInterpolationTime), 0);
    65.     }
    66.  
    67.     #endregion
    68.  
    69.     private struct PlayerNetworkState : INetworkSerializable
    70.     {
    71.         private float _posX, _posY, _posZ;
    72.         private short _rotY;
    73.  
    74.         internal Vector3 Position
    75.         {
    76.             get => new(_posX, _posY, _posZ);
    77.             set
    78.             {
    79.                 _posX = value.x;
    80.                 _posY = value.y;
    81.                 _posZ = value.z;
    82.             }
    83.         }
    84.  
    85.         internal Vector3 Rotation
    86.         {
    87.             get => new(0, _rotY, 0);
    88.             set => _rotY = (short)value.y;
    89.         }
    90.  
    91.         public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
    92.         {
    93.             serializer.SerializeValue(ref _posX);
    94.             serializer.SerializeValue(ref _posY);
    95.             serializer.SerializeValue(ref _posZ);
    96.  
    97.             serializer.SerializeValue(ref _rotY);
    98.         }
    99.     }
    100. }