- Home /
Player launches into air when hitting steep slopes
I've been debugging an issue where when my player is moving forward at high speeds (I have configurable movement modes for an overview/overwatch mode) if they are in walk mode and hit a steep slope the player gets launched into the air as though they've bounced or jumped. So far I've narrowed it to something in this portion of the code (called from Update() with a conditional flag):
CharacterMotor.js (SNIPPET)
private function UpdateFunction () {
// We copy the actual velocity into a temporary variable that we can manipulate.
var velocity : Vector3 = movement.velocity;
// Update velocity based on input
velocity = ApplyInputVelocityChange(velocity);
// Apply gravity and jumping force
velocity = ApplyGravityAndJumping (velocity);
// Moving platform support
var moveDistance : Vector3 = Vector3.zero;
// Save lastPosition for velocity calculation.
var lastPosition : Vector3 = tr.position;
// We always want the movement to be framerate independent. Multiplying by Time.deltaTime does this.
var currentMovementOffset : Vector3 = velocity * Time.deltaTime;
// Find out how much we need to push towards the ground to avoid loosing grouning
// when walking down a step or over a sharp change in slope.
var pushDownOffset : float = Mathf.Max(controller.stepOffset, Vector3(currentMovementOffset.x, 0, currentMovementOffset.z).magnitude);
if (grounded){
Debug.Log(currentMovementOffset);
currentMovementOffset -= pushDownOffset * Vector3.up;
}
// Reset variables that will be set by collision function
movingPlatform.hitPlatform = null;
groundNormal = Vector3.zero;
// Move our character!
movement.collisionFlags = controller.Move (currentMovementOffset);
movement.lastHitPoint = movement.hitPoint;
lastGroundNormal = groundNormal;
// Calculate the velocity based on the current and previous position.
// This means our velocity will only be the amount the character actually moved as a result of collisions.
var oldHVelocity : Vector3 = new Vector3(velocity.x, 0, velocity.z);
movement.velocity = (tr.position - lastPosition) / Time.deltaTime;
var newHVelocity : Vector3 = new Vector3(movement.velocity.x, 0, movement.velocity.z);
// The CharacterController can be moved in unwanted directions when colliding with things.
// We want to prevent this from influencing the recorded velocity.
if (oldHVelocity == Vector3.zero) {
movement.velocity = new Vector3(0, movement.velocity.y, 0);
}
else {
var projectedNewVelocity : float = Vector3.Dot(newHVelocity, oldHVelocity) / oldHVelocity.sqrMagnitude;
movement.velocity = oldHVelocity * Mathf.Clamp01(projectedNewVelocity) + movement.velocity.y * Vector3.up;
}
if (movement.velocity.y < velocity.y - 0.001) {
if (movement.velocity.y < 0) {
// Something is forcing the CharacterController down faster than it should.
// Ignore this
movement.velocity.y = velocity.y;
}
else {
// The upwards movement of the CharacterController has been blocked.
// This is treated like a ceiling collision - stop further jumping here.
jumping.holdingJumpButton = false;
}
}
Debug.Log("Before the bounce test: " + tr.position);
// We were grounded but just loosed grounding
if (grounded && !IsGroundedTest()) {
grounded = false;
Debug.Log("Before bounce?");
SendMessage("OnFall", SendMessageOptions.DontRequireReceiver);
Debug.Log("1. Lost grounding, maybe bounced?");
// We pushed the character down to ensure it would stay on the ground if there was any.
// But there wasn't so now we cancel the downwards offset to make the fall smoother.
Debug.Log(tr.position);
tr.position += pushDownOffset * Vector3.up;
Debug.Log(tr.position);
// Debug.Break();
}
// We were not grounded but just landed on something
else if (!grounded && IsGroundedTest()) {
Debug.Log("3. Found my grounding");
grounded = true;
jumping.jumping = false;
SubtractNewPlatformVelocity();
SendMessage("OnLand", SendMessageOptions.DontRequireReceiver);
}
}
Specifically if we look at the line "if (grounded && !IsGroundedTest()) {" is where I can capture the bounce as it happens. When putting in break points my first debug message fires "Before Bounce" just before launch. On landing we get the Debug message "3. found my grounding".
Unfortunately I'm not experienced enough with character movement to determine exactly why it's launching the player up, any advice on debugging and tracking the issue more closely is appreciated
$$anonymous$$ost recent debug results:
Before the bounce test (5655.7, 65.1, 6032.1)
IsGroundedTestResults: False
Before bounce?
Lost grounding, maybe bounced?
(56.557, 65.1, 6032.1) [NOTE this is the first Debug.Log(tr.position)]
(56.557, 65.1, 6032.1) [NOTE this is the second Debug.Log(tr.position)]
Then we are back to normal
Your answer
Follow this Question
Related Questions
simple ball rolling mechanic 0 Answers
Why isn't my teleport on collision script working? 0 Answers
Enemy AI Movement Decision Making 1 Answer