- Home /
Help sliding Rigidbody down slope
Hello folks, I'm using a rigidbody to control my character & trying to come up with a logical method for sliding the rigidbody down steep slopes. This is the code I have now:
float GroundAngle = Vector3.Angle (HitNormal, Vector3.up);
if(GroundAngle >= _SlideAngle)
{
Vector3 SlopeForce = new Vector3(HitNormal.x, -0.75f, HitNormal.z);
if(GroundAngle < 0) { GroundAngle *= -1; }
float SlideSpeed = (GroundAngle * _SlopeModifier) / 2;
fSlideRate = Mathf.Lerp (fSlideRate, SlideSpeed, Time.time);
SlopeForce *= fSlideRate;
_RigidBody.AddForce (SlopeForce, ForceMode.VelocityChange);
}
The reason I want to do it like this is so the player's movement speed is affected by how much of an angle he's walking on, so the larger the angle, the more force there will be against the player. There's a few problems though, one being the Lerp doesn't seem to work properly. Ideally I'd like the slide speed to begin at 0 and gradually increase, so that a player can begin walking on a slope that's too steep until SlopeForce overcomes walk speed. It also makes better motion when a player begins to slide, rather then instantly sliding down at full speed.
I've been hacking away at this for a few hours but can't seem to get anything to work. This is the closest I've come to smooth sliding, but it's still flawed. If anybody here could help polish my code I'd appreciate it
EDIT: I noticed Rigidbody's will naturally slide down slopes at a slow rate with Gravity enabled. I toyed around with this trying to come up with something, adjusting Physics.gravity based on the angle of the ground, but this seems like a super hacky solution that will cause other problems later on.
edit: After clearing my $$anonymous$$d for a bit I came up with something simple and clean, it'll do the job for now.
if(HitNormal.y <= 0.7f)
{
bSliding = true;
vSlideVelocity = new Vector3(HitNormal.x, -HitNormal.y, HitNormal.z);
fSlideRate += _SlideSpeed * Time.deltaTime / 2;
vSlideVelocity *= fSlideRate;
fSlideRate += _SlideSpeed * Time.deltaTime / 2;
fSlideRate = $$anonymous$$athf.Clamp (fSlideRate, 0, _SlideSpeed);
_RigidBody.AddForce(vSlideVelocity, Force$$anonymous$$ode.VelocityChange);
}
Answer by Justinger · Dec 06, 2014 at 10:36 PM
I agree that using AddForce is usually the way to go instead of gravity as that is global. If I'm understanding you right, your code may be a little more complex than neccesary.
float slidingForceMultiplier = 10;
if(HitNormal.y <= 0.7f)
{
//create a value between 0 and 1 describing how sharp the slope is
//Then multiply it by whatever you like to adjust strength
float slidingForce = (1 - (HitNormal.y/0.7f)) * slidingForceMultiplier;
_RigidBody.AddForce(Vector3.down * slidingForce);
}
I am pretty new to unity, but this is the approach that came to mind. I think if every frame you are adding additional forces onto your target, it should naturally accelerate in that direction, overcoming your characters forward movement. I haven't tested this code, but hopefully it's somewhat helpful. Otherwise, you could take the slidingForce into account to decrease the force of your players movement that they are inputting.