CharacterController and slopes

Hi,

I’ve got a character with a modified third person character control script attached. I only just now tried to set the slopeLimit to a different value, so he wouldnt be able to walk up ridiculous gradients.

I’ve tested this with a flat plane, angled at past 50 degrees, and set the slopeLimit parameter to under 50 (as low as 15). Regardless of what i set it to, the character can always walk right up super-steep slopes.

Any ideas what i’m doing wrong?

'lo again…

really nobody know what might be going wrong here? i can’t imagine i’m the first person to have this problem, surely it’s something small I’m missing?

If I’ve explained the problem badly could someone point it out? Basically the slopelimit parameter on my character controller doesn’t seem to affect his movement on slopes - regardless of where it’s set he can walk up near vertical slopes.

Anyone help me?

Have you modified the Character Controller script in any way?

Can you post a screenshot of your settings in the Inspector?

hey there :slight_smile:

when you ask if i’ve modified the character controller script, I assume you mean the third person controller script that comes with unity? if so, yeah I have modified it quite a bit, but I’ve not changed any of the fundamental stuff that makes the character move around/collide with the scenery.

A shot of the inspector showing the character controller’s settings is attached. hope this helps identify the problem!

You can see in the shot that slope limit is set to 30, and i tested it when i took the shot and i was able to walk up a near vertical slope.

Doesn’t shed any light on the problem?

Is there some special component that needs to be added to the surface I want the slope on, or something like that?

Does nobody have any idea what might be causing this?

anyone…? tears hair out

Are there any updates on this since I have the same problem.

I can even set the SlopeLimit to zero and the character climbs the highest mountains. I’ve never modified the CharacterController…

As far as I know, the slope limit has never worked properly for character controllers.

So are there any alternatives since this behavior isn’t acceptable :?

We have been searching for a solution for this since January. The best we were able to come up with is make a bunch of collision boxes not to allow people to go up the mountain side.

The slope condition needs to be checked with a single (or 2) vertical ray, normally downwards.
if you use 1, then you use the collision normal to decide if it is too steep and slide down / force back the character.

if you use 2, then the second is in front of you at the point of the next step and you use the two positions to decide if you can move forward before doing so

Ok, I understand the concept but I can’t see how I could configure the CharacterController concerning rays :roll:

Are you trying to say you want to have this slope limit without programming?

You can’t
Above is the concept, now you must implement that in code.

No code, no solution

Okay, I came across this thread earlier when I faced this problem…

I solved it somehow just now. Here´s the solution I implemented:
Whenever the player is moving, I cast down two rays, one from his center and the second 0.1 units to the direction he is trying to move.
Both rays hit the ground, with that and a little geometry you can figure the slope angle. If the angle is too great (this happens when the ray cast down in front of him hits a much higher point then the one cast below him) you can just stop his movement.

A few things before I post the code for this:
1- There is a probably better solution using RaycastHit.normal.
2- I just programmed this off of the ThirdPersonController that came with Unity, in the last hour or so. This means every variable is hard coded and nothing is done to actually treat the problem (such as slide the character down).
3- I will post this now because I believe it is the most generic code I´ll have, since from now I´ll start making all kinds of checks to slide the character, make a wall jump, etc, etc…

Sooo, to stop the character from moving up very steep slopes you can get started by placing this code on your ThirdPersonControler:

	//Dont move forward if there a steep slope in front of you
	var hit : RaycastHit;
	Physics.Raycast(transform.position, Vector3(0, -1, 0), hit);
	var pointBelow = hit.point;
	if(!Physics.Raycast(transform.position + moveDirection.normalized/10, Vector3(0, -1, 0), hit))
		movement = Vector3(-movement.x, movement.y, -movement.z); //executing this means ray went though terrain/wall -> very steep slope -> dont move.
	var pointForward = hit.point;
	var heightDiff = pointForward.y - pointBelow.y;
	if (heightDiff > 0)
	{
		if (Mathf.Atan2(heightDiff, 0.1) * Mathf.Rad2Deg > 30  IsGrounded())
			movement = Vector3(-movement.x/10, movement.y, -movement.z/10);
	}

This code should in the Update() function, just below the following:

	// Calculate actual motion
	var movement = moveDirection * moveSpeed + Vector3 (0, verticalSpeed, 0) + inAirVelocity;
	movement *= Time.deltaTime;

And just above the following:

	// Move the controller
	var controller : CharacterController = GetComponent(CharacterController);
	wallJumpContactNormal = Vector3.zero;
	collisionFlags = controller.Move(movement);

Ok, now your character won´t be able to walk steep slopes (I define steep as above 30, it´s hard coded there, go ahead and change it for whatever you think is good).
The problem is that the movement will only be stopped if the character is on the ground (otherwise he would never be able to jump over or fly over those slopes either), that means he can just jump his way up a slope. To stop that you can just block the jump if the character is on a steep slope. To do that you have to place another little bit of code:

Find the function ApplyJumping() and place this code before anything else:

	//Dont if on a steep slope.
	var hit : RaycastHit;
	Physics.Raycast(transform.position, Vector3(0, -1, 0), hit);
	var pointBelow = hit.point;
	if(!Physics.Raycast(transform.position + moveDirection.normalized/10, Vector3(0, -1, 0), hit))
		return;
	var pointForward = hit.point;
	var heightDiff = pointForward.y - pointBelow.y;
	if (heightDiff > 0)
	{
		if (Mathf.Atan2(heightDiff, 0.1) * Mathf.Rad2Deg > 30  IsGrounded())
			return;
	}

This will stop the char from jumping if he is standing on a slope.

Ok, this solution is far from the best you can get, it still needs a lot of work. But the work is a little more project-specific (depends on what you want to happen if you find a steep slope), so I will just post this much.

This solution works with the default ThirdPersonControler and a terrain from Unity, you don´t need any invisible colliders or anything else really.
The behavior I made is to flip the character speed and reduce it whenever he finds a steep slope, this is just so the code works “nicely” right off the box, but you need to think what it best for you and implement it.

Anyhow, this thread helped me figure out how to deal with the problem, I hope this post will help you too.

G. Otranto

Hello. I’ am a programmer in many platforms specially JacaScript. . I figured out a solution to your problem. You want slopeLimit is 30.
Create a box collder in your terrain or a GameObject which is never seen , scale it and put it in (30.high) where ever you want . If you doing this the player cant past the this slopeLimit. Also you can do this with programming. Good Luck!!

1 Like