- Home /
How do I increase the speed of my rigidbody after going down the slope
So, right now, I'm trying to create a slide and I want to so when I slide down a slope, my movement speed builds up then it continues even after I finished sliding, basically, that increased movement speed will be applied to my walking and sprinting and all that, but I want to limit my movement speed and decrease my speed overtime after I finished descending the slope, sorry this is pretty hard but I really can't think of a way to do it. @Llama_w_2Ls I tried your method but it didn't work, I did (rb.velocity.magnitude < max speed) {rb.velocity += maxspeed}, but it wasnt working and was giving me an error says something about Vector3 and floats. Thanks to anyone who will try to help me.
Answer by ProfMonkey07 · Jul 25, 2020 at 11:08 PM
how are you detecting being on the slope? ontriggerenter? if so, do OnTriggerEnter(Collider other){ if(other.tag == slope){ rb.velocity += maxspeed
} else{ rb.velocity = normal velocity } }
I don't really have a method of detecting whether I'm on a slope or not that's why I kind of need help, also every time I type rb.velocity += max speed it doesn't work for some reason, it gives me errors when I try doing that
rb.velocity is a Vector3, whereas the variable maxspeed is a float. rb.velocity needs a direction. For example, rb.velocity.z, which would increase your speed on the z axis. If you dont have a specified direction, you could say that you wanted your speed to increase upwards and forwards. To do this, you could do:` Rigidbody rb; float $$anonymous$$axspeed = 20; float CurrentSpeed = 10; float NormalSpeed = 10; float SpeedIncrease = 0.2f; bool OnSlope = false;
private void Update()
{
if (OnSlope == true && CurrentSpeed < $$anonymous$$axspeed)
{
CurrentSpeed += SpeedIncrease;
rb.velocity = Vector3.forward * CurrentSpeed;
}
else if (OnSlope == false && CurrentSpeed > NormalSpeed)
{
CurrentSpeed -= SpeedIncrease;
rb.velocity = Vector3.forward * CurrentSpeed;
}
}
private void OnCollisionEnter(Collision collision)
{
if (collision.collider.CompareTag("Slope"))
{
OnSlope = true;
}
}
private void OnCollisionExit(Collision collision)
{
OnSlope = false;
}`
You'd have to tweak some values to get the speed right, but this should do it just fine. Just ask if you want code comments.
@Llama_w_2Ls you're a life savior, but I still don't understand the collision.collider.comparetag("slope"), do I have to create a tag for that slope?
Oh god, every time I press the play button I get this error that says Tag:Slope and it is not defined and my game freezes, I created a tag in Unity called Slope but it isnt working
Answer by mzaidan1996 · Jul 26, 2020 at 08:41 AM
@Llama_w_2Ls do I share both my movement and camera script and you try to find the issue?
Its an inspector issue. To asssign tags, you need to create one, then add that tag to the object that you want to be tagged.
I just tried using your script and I added increased gravity to keep me in the slope but I'm still having the same issue where my speed because 0 as soon as I finish going down the slope. Its pretty frustrating.
I fixed the tag issue, it's just that my speed is beco$$anonymous$$g literally 0 as soon as I finish going down the slope.
Try and debug the speed and see if the speed is decelerating very quickly or its immediately co$$anonymous$$g to a halt.
Answer by Llama_w_2Ls · Jul 26, 2020 at 01:25 PM
public CharacterController controller;
public float Walkspeed = 6f;
public float Runspeed = 12f;
public float gravity = -9.81f;
public Transform GroundCheck;
public float GroundDistance = 0.4f;
public LayerMask groundmask;
public float JumpHeight = 3f;
Vector3 velocity;
bool IsGrounded;
float Maxspeed = 20;
float SpeedIncrease = 0.05f;
public bool OnSlope = false;
// Update is called once per frame
void Update()
{
IsGrounded = Physics.CheckSphere(GroundCheck.position, GroundDistance, groundmask);
if (IsGrounded && velocity.y < 0) //fall
{
velocity.y = -2f;
}
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
if (Input.GetKey("w") || Input.GetKey("s") || Input.GetKey("d") || Input.GetKey("a")) // Walk
{
controller.Move(move * Walkspeed * Time.deltaTime);
}
if (Input.GetKey("w") && Input.GetKey("left shift") || Input.GetKey("s") && Input.GetKey("left shift") || Input.GetKey("d") && Input.GetKey("left shift") || Input.GetKey("a") && Input.GetKey("left shift")) // Run
{
controller.Move(move * Runspeed * Time.deltaTime);
}
if (Input.GetButtonDown("Jump") && IsGrounded) // Jump and gravity
{
velocity.y = Mathf.Sqrt(JumpHeight * -2f * gravity);
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
if (OnSlope == true && Walkspeed < Maxspeed)
{
Walkspeed += SpeedIncrease;
controller.Move(move * Walkspeed * Time.deltaTime);
Debug.Log(Walkspeed);
}
else if (OnSlope == false && Walkspeed > 6)
{
Walkspeed -= SpeedIncrease;
controller.Move(move * Walkspeed * Time.deltaTime);
}
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Slope"))
{
OnSlope = true;
}
}
private void OnTriggerExit(Collider other)
{
OnSlope = false;
}
My entire movement script + running when pressing shift + increasing walking speed when on a slope. You need to assign the script to an object (eg. capsule) that is parented to an empty gameobject with a character controller. The Parent should also have an empty gameobject under its own feet as a ground check, as well as a layer set to all objects that you can walk on (e.g. ground), which is the layer of the layermask. This FPS controller was set up by Brackeys, with some custom scripting for slope sliding. If anyone is interested in wall running, i can send my script for that as well.
Yeah I'm working on the wall running @Llama_w_2Ls but I'm having an issue where the movement aint that smooth and my camera doesnt tilt, the camera is on my other script so its kinda a pain right now.
The way i tilted my camera is a bit hard to explain, since its quaternions. Ill send the script in a bit.
public GameObject Turn; //The player
private float degrees = 0;
public bool StartRotatingLeft;
public bool StartRotatingRight;
// Update is called once per frame
void Update()
{
Vector3 EulerRotation = Turn.transform.rotation.eulerAngles;
if (StartRotatingLeft == true)
{
if (degrees < 20)
{
degrees += 2f;
Turn.transform.rotation = Quaternion.Euler(EulerRotation.x, EulerRotation.y, degrees);
}
}
else if (StartRotatingRight == true)
{
if (degrees > -20)
{
degrees -= 2f;
Turn.transform.rotation = Quaternion.Euler(EulerRotation.x, EulerRotation.y, degrees);
}
}
else
{
degrees = 0;
Turn.transform.rotation = Quaternion.Euler(EulerRotation.x, EulerRotation.y, degrees);
}
//Debug.Log(degrees);
}
private void OnTriggerEnter(Collider other)
{
if ((other.gameObject.CompareTag("Wall")) && Input.GetKey(KeyCode.D))
{
StartRotatingLeft = true;
}
else if ((other.gameObject.CompareTag("Wall")) && Input.GetKey(KeyCode.A))
{
StartRotatingRight = true;
}
if (other.gameObject.tag != "Wall")
{
StartRotatingLeft = false;
StartRotatingRight = false;
}
}
private void OnTriggerExit(Collider other)
{
StartRotatingLeft = false;
StartRotatingRight = false;
}
TBH, its not that smooth when you stop wall running. You just immediately return to 0 degrees.