Rigidbody Velocities

In my on-going quest to put a FPS controller on a ship, accelerate the ship, and keep the controller moving exatly relative to the ship…

Why can’t I just set the rigidbody.velocity of player equal to that of the ship and have that work? The rigidbody settings are the same on both (just for testing). The player is not a child of the ship. So, if I set the velocity of one equal to the other, shouldn’t they move exactly the same way? Because they don’t…

Here is a suggestion - using the Rigidbody FPSWalker script:

var speed = 10.0;
var gravity = 10.0;
var maxVelocityChange = 10.0;
var canJump = true;
var jumpHeight = 2.0;
var grounded = false;

@script RequireComponent(Rigidbody)

function Awake ()
{
    rigidbody.freezeRotation = true;
    rigidbody.useGravity = false;
}

function FixedUpdate ()
{
    if (grounded)
    {
        // Calculate how fast we should be moving
        var targetVelocity = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
        targetVelocity = transform.TransformDirection(targetVelocity);
        targetVelocity *= speed;
        
        // Apply a force that attempts to reach our target velocity
        var velocity = rigidbody.velocity;
        var velocityChange = (targetVelocity - velocity);
        velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
        velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
        velocityChange.y = 0;
        rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);
    
        // Jump
        if (canJump  Input.GetButton("Jump"))
        {
            rigidbody.velocity = Vector3(velocity.x, CalculateJumpVerticalSpeed(), velocity.z);
        }
    }
    
    // We apply gravity manually for more tuning control
    rigidbody.AddForce(Vector3 (0, -gravity * rigidbody.mass, 0));
    
    grounded = false;
}

function OnCollisionStay ()
{
    grounded = true;    
}

function CalculateJumpVerticalSpeed ()
{
    // From the jump height and gravity we deduce the upwards speed 
    // for the character to reach at the apex.
    return Mathf.Sqrt(2 * jumpHeight * gravity);
}

If you choose to apply this script to your FPS Player, I would suggest making a ‘Physic material’ and increase the friction on it. Then apply the Physic material to the ship and/or the FPS Player so that it will hold the player better.

Yeah, I thought of doing this. It doesn’t work. I already tried the physics material thing and cranked up the friction to ridiculous amounts. Hit the main engines on the ship, the ship takes off, and the controller is left behind, plumetting through the air(because I don’t have a collider at the back of my ship). Friction, alone, will not give the controller the necessary grip. That is why I was trying just set the controller’s velocity to the ship’s velocity. I still don’t get why that doesn’t work.

I’m still looking for an answer to the question as to why you can’t set one rigidbody’s velocity equal to another’s and have them move the same way. For example, take two spheres, add rigidbodies to them and don’t change anything except turning gravity off. Write a quick script:

var other : Rigidbody;   //the other sphere

function FixedUpdate()
{
    rigidbody.Addforce(Vector3.forward*5*Time.deltaTime,ForceMode.VelocityChange);
    other.velocity = rigidbody.velocity;
}

When I run this, the second sphere moves faster than the first. I’m trying to figure out why this happens.

The velocity of a rigid body, when appliying a force, will vary depending on the rigid body’s mass (and probably, another factors like friction).
If you assign a value to the rigid body’s velocity, it will move at certain speed regardless of its mass.

So, if you have two spheres with equals properties… wait a minute… i misunderstood the post. O_o

Right. This is an “all things being equal” scenario. Try it out when you get a chance. Maybe it is something buggy on my end.

Do you have gravity switched off for the player rigidbody? If you don’t have a force pushing the player down to the surface he is resting on, you probably won’t get much effect from the friction. You could try using “artificial” gravity on the ship by pushing the player to the floor surface with an additional force.