Networking with Mirror NetworkTransform Position and Rotation Glitching out

Hello all, I am working on a game where two players will drive a tank like vehicle. there are two “seats”. one for a driver and the other for a navigator. Driver obviously drives the whole ship, while the Navigation seat follows the ship but can rotate independently of the ship like the top of a tank. ultimately i would like for either player to be able to walk around inside the ship while the other drives around, or have both in their respected seats moving around together.

So the issue I’m having currently is for the host everything works as expected but the client can get in the ship and drive it and once out of the driver seat the ship pops back to the position that it was when the client got in but also on the host the ship stays where the client put it. the nav seat will sometimes pop up like 10 feet higher sometimes for the client.

So basically i have my FirstPersonController script that controls the player when the the player is not in a seat.
PlayerControllerHandler to handle all of the player states.
ShipController to handle the movement of the ship.
And NavSeatController to handle the nav seat movement.
the ShipController and the NavSeatController scripts are basically the same with variations for the controls so to simplify it I’m going to focus on the ship. I also dont think the issue lies with the FPS controller so ill skip that one to keep things clean.

PlayerControllerHandler

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;


public class PlayerControlHandler : NetworkBehaviour
{

    [SyncVar]
    public bool DriverSeatTaken;
    [SyncVar]
    public bool NavSeatTaken;
    public ShipController ship;
    public NavSeatController navSeat;
    public bool canControlPlayer;
    private void Start()
    {
        //CmdUpdateDriverSeatTaken(false);
    }
    private void UpdateDriverSeatTaken(bool oldValue, bool newValue)
    {
        
    }
    public void enterDriverSeat()
    {
        ship = GameObject.Find("Ship").GetComponent<ShipController>();
        Debug.Log("Entering Seat");
        GetComponent<FirstPersonController>().enabled = false;
        CmdAssignShipAuthority(ship.netIdentity);
        CmdUpdateDriverSeatTaken(true);
        if(isClientOnly)
        {
            ship.gameObject.GetComponent<NetworkTransformReliable>().syncDirection = SyncDirection.ClientToServer;
            CmdChangeShipTransformSyncDirectionCtoS(ship.netIdentity);
        }
    }
    public void exitDriverSeat(Transform OutOfSeat)
    {
        ship = GameObject.Find("Ship").GetComponent<ShipController>();
        Debug.Log("Leaving Seat");
        if (isClientOnly)
        {
            Debug.Log("Changing sync direction");
            ship.gameObject.GetComponent<NetworkTransformReliable>().syncDirection = SyncDirection.ServerToClient;
            CmdChangeShipTransformSyncDirectionStoC(ship.netIdentity);
        }
        CmdRemoveShipAuthority(ship.netIdentity);
        CmdUpdateDriverSeatTaken(false);
        GetComponent<CharacterController>().enabled = false;
        transform.position = OutOfSeat.position;
        GetComponent<CharacterController>().enabled = true;
        GetComponent<FirstPersonController>().enabled = true;
    }

    public void enterNavSeat()
    {
        navSeat = GameObject.Find("NavPod").GetComponent<NavSeatController>();
        navSeat.enabled = true;
        Debug.Log("Entering Nav Seat");
        GetComponent<FirstPersonController>().enabled = false;
        CmdAssignNavAuthority(navSeat.netIdentity);
        CmdUpdateNavSeatTaken(true);
        if (isClient)
        {
            navSeat.gameObject.GetComponent<NetworkTransformReliable>().syncDirection = SyncDirection.ClientToServer;
            CmdChangeNavTransformSyncDirectionCtoS(navSeat.netIdentity);
        }

    }

    public void exitNavSeat(Transform NavOutOfSeat)
    {
        navSeat = GameObject.Find("NavPod").GetComponent<NavSeatController>();
        Debug.Log("Leaving Nav Seat");
        if (isClient)
        {
            navSeat.gameObject.GetComponent<NetworkTransformReliable>().syncDirection = SyncDirection.ServerToClient;
            CmdChangeNavTransformSyncDirectionStoC(navSeat.netIdentity);
        }
        navSeat.enabled = false;
        CmdRemoveNavAuthority(navSeat.netIdentity);
        CmdUpdateNavSeatTaken(false);
        GetComponent<CharacterController>().enabled = false;
        transform.position = NavOutOfSeat.position;
        GetComponent<CharacterController>().enabled = true;
        GetComponent<FirstPersonController>().enabled = true;
    }

    [Command(requiresAuthority = false)]
    public void CmdUpdateDriverSeatTaken(bool value)
    {
        DriverSeatTaken = value;
    }
    [Command(requiresAuthority = false)]
    public void CmdUpdateNavSeatTaken(bool value)
    {
        NavSeatTaken = value;
    }

    [Command]
    public void CmdAssignShipAuthority(NetworkIdentity _networkIdentity) 
    {
        ship = _networkIdentity.GetComponent<ShipController>();
        Debug.Log("Assigning Authority");
        
        if(ship.objectOwner != this.netIdentity)
        {
            _networkIdentity.RemoveClientAuthority();
            _networkIdentity.AssignClientAuthority(connectionToClient);

            ship.objectOwner = this.netIdentity;
            Debug.Log("Authority Assigned");
        }
    }

    [Command]
    public void CmdRemoveShipAuthority(NetworkIdentity _networkIdentity)
    {
        ship = _networkIdentity.GetComponent<ShipController>();
        if (ship.objectOwner != null && ship.objectOwner == this.netIdentity)
        {
            _networkIdentity.RemoveClientAuthority();
            ship.objectOwner = null;
        }
    }

    [Command]
    public void CmdAssignNavAuthority(NetworkIdentity _networkIdentity)
    {
        navSeat = _networkIdentity.GetComponent<NavSeatController>();
        Debug.Log("Assigning Authority");
        if (navSeat.objectOwner != this.netIdentity)
        {
            _networkIdentity.RemoveClientAuthority();
            _networkIdentity.AssignClientAuthority(connectionToClient);

            navSeat.objectOwner = this.netIdentity;
            Debug.Log("Authority Assigned");
        }
    }

    [Command]
    public void CmdRemoveNavAuthority(NetworkIdentity _networkIdentity)
    {
        navSeat = _networkIdentity.GetComponent<NavSeatController>();
        if (navSeat.objectOwner != null && navSeat.objectOwner == this.netIdentity)
        {
            _networkIdentity.RemoveClientAuthority();
            navSeat.objectOwner = null;
        }
    }

    [Command(requiresAuthority = false)]
    public void CmdChangeShipTransformSyncDirectionStoC(NetworkIdentity _networkIdentity)
    {
        ship = _networkIdentity.GetComponent<ShipController>();
        if (ship.objectOwner != null && ship.objectOwner == this.netIdentity)
        {
            _networkIdentity.gameObject.GetComponent<NetworkTransformReliable>().syncDirection = SyncDirection.ServerToClient;
        }
    }
    [Command(requiresAuthority = false)]
    public void CmdChangeShipTransformSyncDirectionCtoS(NetworkIdentity _networkIdentity)
    {
        ship = _networkIdentity.GetComponent<ShipController>();
        if (ship.objectOwner != null && ship.objectOwner == this.netIdentity)
        {
            _networkIdentity.gameObject.GetComponent<NetworkTransformReliable>().syncDirection = SyncDirection.ClientToServer;
        }
    }

    [Command(requiresAuthority = false)]
    public void CmdChangeNavTransformSyncDirectionStoC(NetworkIdentity _networkIdentity)
    {
        navSeat = _networkIdentity.GetComponent<NavSeatController>();
        if (navSeat.objectOwner != null && navSeat.objectOwner == this.netIdentity)
        {
            _networkIdentity.gameObject.GetComponent<NetworkTransformReliable>().syncDirection = SyncDirection.ServerToClient;
        }
    }
    [Command(requiresAuthority = false)]
    public void CmdChangeNavTransformSyncDirectionCtoS(NetworkIdentity _networkIdentity)
    {
        navSeat = _networkIdentity.GetComponent<NavSeatController>();
        if (navSeat.objectOwner != null && navSeat.objectOwner == this.netIdentity)
        {
            _networkIdentity.gameObject.GetComponent<NetworkTransformReliable>().syncDirection = SyncDirection.ClientToServer;
        }
    }
}

The enterDriverSeat() function disables the fps controller assigns authority to the local player, and will change the NetworkTransform sync direction to Client to Server.
not sure if I’m supposed to change the sync direction but it fixed a previous issue to do that. The exitDriverSeat() does the same but in reverse.

ShipController

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;

public class ShipController : NetworkBehaviour
{
    [SyncVar(hook = nameof(OnOwnerChangedHook))]
    public NetworkIdentity objectOwner;
    public float spd;
    public float rotateSpd;
    public Transform DriverSeat;
    public Transform OutOfSeat;

    public PlayerControlHandler playerController;


    private void OnEnable()
    {
    }
    void Update()
    {
        moveShip();


        if (Input.GetKeyDown(KeyCode.E) && objectOwner != null)
        {

            objectOwner.GetComponent<PlayerControlHandler>().exitDriverSeat(OutOfSeat);
        }
    }

    public void moveShip()
    {
        if (isOwned)
        {
            playerController.transform.position = DriverSeat.transform.position;
            if (Input.GetKey(KeyCode.W))
            {
                transform.position += transform.forward * spd * Time.deltaTime;
            }
            if (Input.GetKey(KeyCode.S))
            {
                transform.position -= transform.forward * spd * Time.deltaTime;
            }
            if (Input.GetKey(KeyCode.A))
            {
                transform.Rotate(new Vector3(0, -rotateSpd, 0) * Time.deltaTime);
            }
            if (Input.GetKey(KeyCode.D))
            {
                transform.Rotate(new Vector3(0, rotateSpd, 0) * Time.deltaTime);
            }
        }
    }

    void OnOwnerChangedHook(NetworkIdentity _old, NetworkIdentity _new)
    {
        Debug.Log("OnOwnerChangedHook: " + objectOwner);

        if (objectOwner)
        {
            playerController = _new.GetComponent<PlayerControlHandler>();
            if (playerController) { playerController.canControlPlayer = false; }
        }
        else if (_old)
        {
            playerController = _old.GetComponent<PlayerControlHandler>();
            if (playerController)
            {
                playerController.canControlPlayer = true;
                playerController = null;
            }
        }

    }


}

This script is pretty straight forward only thing to note is the objectOwner is stored here.

The NetworTransform uses the default settings except the sync direction is set to ServerToClient and will change to ClientToServer at runtime when someone is in the seat.

I dont understand why when the client exits the seat the ship gets set back to the position it was at when the client entered the seat, and then the host and client become desynced. Sorry if this is too much info lol, but if i need to provide something else let me know. Thanks in advance.