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)