2D character controllers and slopes

Hi all,

Getting back into Unity again! Yay!

I’ve been playing with making my own character controller “from scratch” as it were, and I’ve run into an interesting problem:

If I apply this to a character (right now, just test cube with a height of 1.0), and have that character run up a somewhat steep slope, everything works fine. However, if the character tries to go down the same slope, they don’t stay on the ground. Every few steps they launch off the slope the tiniest amount, then come back down again.

Apart from creating jittery motion, this makes it hard to jump from areas when the character is standing on sloped ground. Even a small running jump can prove impossible.

I’m thinking that to solve this I’ll have to get the normal of the ground collision, make a vector tangent to it, and move the character along that direction. I’m just wondering if anyone else has solved this issue? Thanks!

To see the issue, make two cubes. One is a simple character, and the other is the platform. If you stretch the platform out and rotate it to 45 degrees on the X axis (my game world is set up so that left and right is Z, and up is Y), then run down it, you’ll see what happens.

var speed = 10.0;
var jumpSpeed = 24.0;
var gravity = 48.0;

private var moveDirection = Vector3.zero;
private var grounded : boolean = false;

private var threshold : float = 0.1;

// This is a modified version of the FPS controller


function FixedUpdate() {
	var horizontal:float = Input.GetAxis("Horizontal");
	var vertical:float = Input.GetAxis("Vertical");
	
	if (grounded) {
		// We are grounded, so recalculate movedirection directly from axes
		// in this script we're only calculating jump when grounded
		moveDirection = new Vector3(0, 0, -horizontal);
		moveDirection = transform.TransformDirection(moveDirection);
		moveDirection *= speed;

		if (vertical >= threshold) {
			moveDirection.y = jumpSpeed;
		}
	}
	else {
		// allow the character to move in midair, but not jump
		var tempVector:Vector3 = transform.TransformDirection(new Vector3(0, 0, -horizontal));
		moveDirection.z = tempVector.z * speed;		
	}

	// Apply gravity
	moveDirection.y -= gravity * Time.deltaTime;
	
	// Move the controller
	var controller : CharacterController = GetComponent(CharacterController);
	var flags = controller.Move(moveDirection * Time.deltaTime);
	grounded = (flags  CollisionFlags.CollidedBelow) != 0;
}

@script RequireComponent(CharacterController)

Oh awesomesauce!

I am planing to make a pack of scripts that I have made. One of the scripts is a 2d camera, which is useless without this script. Can I add this script to the pack, if I give you credits?

Also, the pack is free. I’m not selling it.

Sorry for the slow reply; spam filter caught my subscription.

You’re more than welcome to do as you like with the script, but it doesn’t work 100% properly which is why I posted in the first place. :wink:

Test it on a slope running downhill and you’ll see.

Anyway, if you put it in this pack please link to my blog at confectionary malfunction . But I still want to figure out how to fix this issue. :slight_smile: