Unity Netcode (MLAPI) Host Moving And Client Connecting, But Client Not Moving

Viewed 1332

Recently started using Unity Netcode (MLAPI) to try and make a Multiplayer Racing game, but I am having some troubles. This is my first time making a multiplayer game, so I'm fairly new to this stuff.

What is happening: The Client connects to the Host perfectly fine, and the wheels move like the car is going to move, but the client is unable to move at all. The host can move just fine, and is able to collide with the client, and the client can view it all, but the client just isn't moving. I assume this is something to do with NetworkTransforms but I really unsure at this point.

Below is my attached movement script for the vehicles:

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

public class VehicleMovement : NetworkBehaviour
{
    private const string HORIZONTAL = "Horizontal";
    private const string VERTICAL = "Vertical";

    private float horizontalInput;
    private float verticalInput;
    private float currentSteerAngle;
    private bool isBraking;
    private float currentBrakeForce;

    [SerializeField] private float motorForce;
    [SerializeField] private float brakeForce;
    [SerializeField] private float maxSteeringAngle;

    [SerializeField] private WheelCollider frontLeftWheelCollider;
    [SerializeField] private WheelCollider frontRightWheelCollider;
    [SerializeField] private WheelCollider rearLeftWheelCollider;
    [SerializeField] private WheelCollider rearRightWheelCollider;

    [SerializeField] private Transform frontLeftWheelTransform;
    [SerializeField] private Transform frontRightWheelTransform;
    [SerializeField] private Transform rearLeftWheelTransform;
    [SerializeField] private Transform rearRightWheelTransform;
    private void FixedUpdate()
    {
        if (IsLocalPlayer)
        {
            GetInput();
            HandleMotor();
            HandleSteering();
            UpdateWheels();
        }
    }

    private void HandleMotor()
    {
        frontLeftWheelCollider.motorTorque = verticalInput * motorForce;
        frontRightWheelCollider.motorTorque = verticalInput * motorForce;
        currentBrakeForce = isBraking ? brakeForce : 0f;
        ApplyBraking();
    }

    private void ApplyBraking()
    {
        frontRightWheelCollider.brakeTorque = currentBrakeForce;
        frontLeftWheelCollider.brakeTorque = currentBrakeForce;
        rearRightWheelCollider.brakeTorque = currentBrakeForce;
        rearLeftWheelCollider.brakeTorque = currentBrakeForce;
    }

    private void HandleSteering()
    {
        currentSteerAngle = maxSteeringAngle * horizontalInput;
        frontLeftWheelCollider.steerAngle = currentSteerAngle;
        frontRightWheelCollider.steerAngle = currentSteerAngle;
    }
    private void GetInput()
    {
        horizontalInput = Input.GetAxis(HORIZONTAL);
        verticalInput = Input.GetAxis(VERTICAL);
        isBraking = Input.GetKey(KeyCode.Space);
    }

    private void UpdateWheels()
    {
        UpdateSingleWheel(frontLeftWheelCollider, frontLeftWheelTransform);
        UpdateSingleWheel(frontRightWheelCollider, frontRightWheelTransform);
        UpdateSingleWheel(rearLeftWheelCollider, rearLeftWheelTransform);
        UpdateSingleWheel(rearRightWheelCollider, rearRightWheelTransform);

    }

    private void UpdateSingleWheel(WheelCollider wheelCollider, Transform wheelTransform)
    {
        Vector3 pos;
        Quaternion rot;
        wheelCollider.GetWorldPose(out pos, out rot);
        wheelTransform.rotation = rot;
        wheelTransform.position = pos;
    }
}

My prefab consists of Transform, Rigidbody, [The script above], NetworkObject, NetworkTransform, and NetworkRigidbody.

Here is an Unlisted YouTube Video that hopefully visually shows the issue.

Any and all help would be appreciated! Thank you!

2 Answers

Turns out under the Package Manager there an optional import in "Netcode for GameObjects" hidden under "Samples" called "ClientNetwork Transform".

This completely solved the problem.

NetworkTransform is server authoritative by default, meaning only servers can update the NetworkTransform object.

We can get around this by creating a client network transform object that changes the permissions to client authoritative:

using UnityEngine;
using Unity.Netcode.Components;

[DisallowMultipleComponent]
public class ClientNetworkTransform : NetworkTransform
{
    protected override bool OnIsServerAuthoritative()
    {
        return false;
    }
}
Related