# Rigibody.velocity.magnitude on slopes.

Using the code below under FixedUpdate. Attached a video showing that the speed is shown correctly when on a flat plane, but as soon as I begin to climb a slope, it does not slown down (my char does) and when stopped over the hill, the actualPlayerSpeed gets crazy. Any Solution?

// Forward Input
if (vertical > 0.0f && horizontal == 0.0f) {

playerRigidBody.velocity = transform.forward * maximumPlayerSpeed;

}

actualPlayerSpeed = playerRigidBody.velocity.magnitude

You are only adding velocity to your transform.forward. So when the terrain gradually gets more and more in front of you, the forward velocity becomes useless. To fix this you should consider rotating your player along the normals of the surface you are on.

Can you give me a simple example, please?

There isn’t really a simple example, it isn’t the easiest problem.
This might help you out: Orient vehicle to ground normal (terrain hugging) - Questions & Answers - Unity Discussions

Ok. Thanks for helping. I am gonna try.

Ok. Using this:

``````    if(Physics.Raycast(transform.position, -transform.up, out tick));
{
transform.rotation = Quaternion.FromToRotation(transform.up, tick.normal);
Debug.DrawRay (tick.point, tick.normal*5f, Color.red);

}
``````
1. Raycast to find normal of slope;
2. QuaternionFromToRotation gets the angle I shoud rotate my char in the “x” axis, the angle between transform.up and normal;
3. But now, how do I rotate my char in the x axis? I tried: playerRigidBody.transform.Rotate(transform.rotation.eulerAngles, 0, 0); with no sucess. Video attached.

Figured out! This ^^&^& script was messing it all!!
Code (CSharp):

It was at update reseting my X rotation all time. Even though, my "current speed value “is still crazy when climbing slopes”. Why?

How are you calculating current speed?

I am using:

actualPlayerSpeed = playerRigidBody.velocity.magnitude;

I discovered that when using any other function that does a transform.rotation, like the Mouse RotatePlayer I mentioned above,the speed begins to get crazy on slopes, but only when stopped. If moving, the speed value is correct… So, the align player with normals do the same thing. To solve the problem I am adding a function to check if the player is moving:

``````    void CheckIfPlayerIsMoving()

{
Vector3 curPos = transform.position;

if (curPos == lastPos)
{
actualPlayerSpeed = 0f;
} else
{
actualPlayerSpeed = playerRigidBody.velocity.magnitude;
}

lastPos = curPos;
}
``````

Now, when not moving,the speed goes instantly to zero and speed when stopped is not “flickering” anymore (values like 1.xxxxxxxxxx-e). I dont know if is the right thing to do it, but its working. If anyone has a better suggestion… I am accepting, because I found a 'solution", but I want to understand what is causing the issue. Thanks.

Physics in Unity3D certainly is not perfect. And your method for zeroing the speed is fine if it works. When dealing with rigidbody.velocity you typically want to zero that value out if you know you are not moving - since this may cause some unnatural jitter if it is never getting zeroed. So where you say:

actualPlayerSpeed = 0f;

You may also want to put:

playerRigidBody.velocity = Vector3.zero;