still got momentum after "Use Gravity" On rigidbody is turned off
I want my player to be able to switch between walking and flying fluently. But after i turn off "Use gravity" on the rigidbody the player has still got the momentum, i was wondering if there is anyway around this? theres probably a easy fix but i just havent seen it yet.
public float moveSpeed = 15f;
public float flySpeed = 10f;
public float velocitySpeed = 0f;
public float jumpHeight = 5f;
private float rayHeight = 1.1f;//ray is raycast down towards the ground, to check if player grounded
private bool isGrounded;
public bool isFlying;//testing to see if the player is walking or flying
private Rigidbody rigid;
// Start is called before the first frame update
void Start()
{
rigid = gameObject.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
int layerMask = 1 << 9;
layerMask = 9;
RaycastHit hit;
Ray ray = new Ray(transform.position, -transform.up);
Physics.Raycast(ray, out hit, rayHeight, layerMask);
Debug.DrawRay(ray.origin, ray.direction * rayHeight, Color.red);
if (hit.collider)
{
Debug.Log("Hitting Collider");
isGrounded = true;
isFlying = false;
}
else if (!hit.collider)
isGrounded = false;
if (isGrounded)
{
if (Input.GetKeyDown(KeyCode.Space))
{
rigid.AddRelativeForce(new Vector3(0,jumpHeight), ForceMode.Impulse);
}
}
if (!isGrounded)
{
if (Input.GetKeyDown(KeyCode.Space))
{
isFlying = true;
}
}
if (!isFlying)
{
rigid.useGravity = false;
float translationZ = Input.GetAxis("Horizontal") * moveSpeed;
float translationX = Input.GetAxis("Vertical") * moveSpeed;
translationZ *= Time.deltaTime;
translationX *= Time.deltaTime;
transform.Translate(translationX, 0, translationZ);
}
if (isFlying)
{
rigid.useGravity = true;
velocitySpeed = Mathf.Clamp(velocitySpeed, -0.1f, 0.1f);
float translationZ = Input.GetAxis("Horizontal") * flySpeed;
float translationX = Input.GetAxis("Vertical") * flySpeed;
float translationY = Input.GetAxis("Jump") * +velocitySpeed * Time.deltaTime;
translationZ *= Time.deltaTime;
translationX *= Time.deltaTime;
bool increaseHeight;
if (Input.GetKeyDown(KeyCode.Space))
{
increaseHeight = true;
if (increaseHeight)
{
velocitySpeed += 0.1f;
}
}
if (Input.GetKeyUp(KeyCode.Space))
{
increaseHeight = false;
if (!increaseHeight){
velocitySpeed = 0f;
}
}
if (Input.GetKeyDown(KeyCode.LeftShift))
{
increaseHeight = true;
if (increaseHeight)
{
velocitySpeed -= 0.1f;
}
}
if (Input.GetKeyUp(KeyCode.LeftShift))
{
increaseHeight = false;
if (!increaseHeight)
{
velocitySpeed = 0f;
}
}
transform.Translate(translationX, velocitySpeed, translationZ);
}
}
}
Answer by lgarczyn · Dec 13, 2019 at 07:36 PM
You shouldn't use Translate on rigidbodies.
You should only use MovePosition on a kinematic rigidbody. You should only set the velocity or use AddForce on a dynamic (non-kinematic) rigidbody. (There are exceptions, but that's the gist of it.)
The problem is that right now you use both transform-based movement and physics based movement.
To answer your question, you can just reset the momentum or velocity like this:
rigidbody.velocity = Vector3.zero;
However you need to chose between a kinematic rigidbody, dynamic rigidbody, or CharacterController.
I advise that you use a CharacterController, and use Move to move it around. You can replace all your calls to Translate by Move. Copy this script to apply gravity when not flying.
A kinematic rigidbody will need a Raycast to check for collisions, but it won't be affected by the rest of the world.
A dynamic rigidbody has access to velocity, and therefore can have useGravity, but it might get pushed around by other moving objects.