How to move player on a moving vehicle


I’m working on a “Sea of thieves like”, and I have a problem.

My ship is controlled by forces added to its rigidbody, to make its movement with some inertia.
My player also have a rigidbody, so it’s using gravity, velocity etc…

When the player is on the ship, I want the player to be moving with the ship, and moving freely on the ship ( go on the bridge, in its room, etc etc…).

So, at the moment, I’m adding ship’s rigidbody.velocity to the player’s rigidbody, and the player is moving as I want.

Now my problem is, when the ship start turning, the player don’t follow its rotation.

 Here is my script: 

    public class ControllerFPS : MonoBehaviour {
    Rigidbody rb;

    [SerializeField] float velocity = 2.0f;
    [SerializeField] float angularVelocity = 360.0f;
    [SerializeField] float angularVelocityVertical = 100.0f;
    [SerializeField] float jumpVelocity = 10.0f;

    GameObject gBoat;
    Rigidbody rBoat;

    float deltaRot;
    float boatRot;

    float currentRotation = 0.0f;

    // Use this for initialization
    void Start () {
        rb = GetComponent<Rigidbody>();
        Cursor.lockState = CursorLockMode.Locked;

        gBoat = GameObject.Find("Bateau");
        rBoat = gBoat.GetComponent<Rigidbody>();

        boatRot = gBoat.transform.rotation.y;
	// Update is called once per frame
	void Update () {

        Vector3 tmpVelocity =;

        float desiredVelocity = velocity;

        tmpVelocity += transform.forward * Input.GetAxis("Vertical") * desiredVelocity;
        tmpVelocity += transform.right * Input.GetAxis("Horizontal") * desiredVelocity;
        tmpVelocity = Vector3.ClampMagnitude(tmpVelocity, desiredVelocity);

        if (Input.GetButtonDown("Jump"))
           tmpVelocity.y = jumpVelocity;
        else if (Input.GetButtonDown("Crouch"))

           tmpVelocity.y = -jumpVelocity;
            tmpVelocity.y = rb.velocity.y;

        rb.velocity = tmpVelocity + rBoat.velocity;
        //rb.velocity = tmpVelocity;

        deltaRot = gBoat.transform.rotation.y - boatRot;
        boatRot = gBoat.transform.rotation.y;
        transform.Rotate(Vector3.up, Input.GetAxis("Mouse X") * Time.deltaTime * angularVelocity + deltaRot);
        //transform.eulerAngles = transform.eulerAngles + new Vector3(0.0f, deltaRot, 0.0f);
        //transform.localEulerAngles = transform.localEulerAngles + new Vector3(0.0f, deltaRot, 0.0f);

        currentRotation += Input.GetAxis("Mouse Y") * Time.deltaTime * angularVelocityVertical;
        currentRotation = Mathf.Clamp(currentRotation, -85.0f, 85.0f);
        Camera.main.transform.localEulerAngles = new Vector3(-currentRotation,0,0);


As you can see, I’ve tried some things, but these don’t work.

Thanks for reading me, and waiting for help!

Looks many have this problem like me, A simple two steps in the rigid body of the FPS controller makes this work for me

  1. FPS->Rigidbody ->Interpolate option change it to “Interpolate” from default “None”
  2. FPS->Rigidbody ->Collision detection> select “continuous”

and your FPS object need to the the child of your vehicle.

This works for me in my hot air balloon and boat :slight_smile: