I’m writing a FPS controller script using CharacterController. I’m trying to keep the momentum of the character and allow some acceleration. To achieve this, I use the ‘velocity’ parameter every frame (see code below)
My problem:
When CharacterController performs an stepOffset elevation, the character is launched into the air.
The problem source:
When the CharacterController performs a stepOffset, its ‘velocity.y’ is set really high. I’m guessing equivalent to the height of the elevation divided by time spent getting there.
Also, stepOffset triggering seems to be hidden well within the CharacterController.
Question:
Is there a way to either subtract the vertical stepOffset velocity from the velocity, or otherwise check if the stepOffset did -something- this frame?
Possible fix #1: I tried Increasing the gravity to decrease the launch height, making it look like the character is simply “jumping onto the ledge”. This is acceptable, as long as the “jumping onto the ledge” is an acceptable behaviour. In my case, I’d like to avoid it.
Possible fix #2: More speed allows the rounded bottom of the charactercontrollers capsule collider to simply glide up from pure geometry alone. This is less than ideal, since most situations in my game will not involve a speedy character.
Possible fix #3: Set stepOffset to zero and write own collision raycast stepOffset functionality. I’m investigating this further tomorrow, unless any bright ideas pop up.
This is the code that runs every frame with Move():
// CharacterController charCon;
// Move towards horisontal input speed
Vector3 v3BodySpeed = charCon.velocity; // PROBLEM: Triggering a stepOffset sets a high y
// Only movetowards horizontal speed
float fSpeedY = v3BodySpeed.y; // save this while temporarily zeroing out vertical speed
v3BodySpeed.y = 0F; // temp
v3BodySpeed = Vector3.MoveTowards(v3BodySpeed, v3InputBodySpeed, fAccelerationSpeed);
v3BodySpeed.y = fSpeedY; // Reinstated vertical speed
// Jumping is instant instead of "MoveTowards"
if(isStartingAJump){
v3BodySpeed.y += fJumpSpeed;
isStartingAJump = false;
}
// Apply gravity
v3BodySpeed += Physics.gravity * Time.deltaTime;
// Make it move
charCon.Move(v3BodySpeed * Time.deltaTime);