private void UpdateMovement()
{
Vector3 smoothedInputVelocity = inputVelocity * 0.6f + lastInputVelocity * 0.45f;
lastInputVelocity = smoothedInputVelocity;
// jump and dash
dashCooldown -= Time.deltaTime;
bool justJumped = false;
if((networkView.isMine) && Time.time - lastJumpInputTime <= JumpInputQueueTime)
{
bool groundedOrRecentRocketJump = controller.isGrounded || RecentlyDidRocketJump;
bool recoilOk = recoilVelocity.y <= 0;
// TODO ugly booleans
if ((groundedOrRecentRocketJump || sinceNotGrounded < 0.25f) && (recoilOk || RecentlyDidRocketJump))
{
ConsumedRocketJump();
//Debug.Log("Accepted jump");
lastJumpInputTime = -1;
justJumped = true;
activelyJumping = true;
fallingVelocity.y = jumpVelocity;
characterAnimation.CrossFade(currentAnim = "jump", IdleTransitionFadeLength );
playJumpSound = true;
if( GlobalSoundsScript.soundEnabled )
jumpSound.Play();
sinceNotGrounded = 0.25f;
}
else if(dashCooldown <= 0)
{
activelyJumping = false;
lastJumpInputTime = -1;
dashCooldown = timeBetweenDashes;
if (currentAnim == "jump")
characterAnimation.Rewind("jump");
characterAnimation.CrossFade(currentAnim = "jump", IdleTransitionFadeLength );
playDashSound = true;
if(GlobalSoundsScript.soundEnabled) {
dashSound.Play();
}
Vector3 dashDirection = RawAxisMovementDirection;
// Dash upwards if no significant direction input
if (dashDirection.magnitude < Mathf.Epsilon)
dashDirection = Vector3.up * 0.4f;
fallingVelocity +=
dashDirection * dashForwardVelocity +
Vector3.up * dashUpwardVelocity;
recoilVelocity.y *= 0.5f;
}
}
if(controller.isGrounded)
{
if (!justJumped)
{
sinceNotGrounded = 0;
jumpsSinceGrounded = 0;
}
// infinite friction
if (fallingVelocity.y <= 0)
fallingVelocity = Vector3.up * gravity * Time.deltaTime;
}
else
{
sinceNotGrounded += Time.deltaTime;
// air drag / gravity
fallingVelocity.y += gravity * Time.deltaTime;
fallingVelocity.x *= Mathf.Pow(airVelocityDamping, Time.deltaTime);
fallingVelocity.z *= Mathf.Pow(airVelocityDamping, Time.deltaTime);
}
// Update running animation
if( controller.isGrounded && !justJumped && !activelyJumping)
{
if( MathHelper.AlmostEquals( smoothedInputVelocity, Vector3.zero, 0.1f ) && currentAnim != "idle" )
characterAnimation.CrossFade( currentAnim = "idle", IdleTransitionFadeLength );
else
{
var xDir = Vector3.Dot( smoothedInputVelocity, transform.right );
var zDir = Vector3.Dot( smoothedInputVelocity, transform.forward );
const float epsilon = 15f;
//Debug.Log("xDir : " + xDir + " | zDir : " + zDir);
if (zDir > epsilon)
{
if (currentAnim != "run")
characterAnimation.CrossFade(currentAnim = "run", IdleTransitionFadeLength );
}
else if (zDir < -epsilon)
{
if (currentAnim != "backward")
characterAnimation.CrossFade(currentAnim = "backward", IdleTransitionFadeLength );
}
else if (xDir > epsilon)
{
if (currentAnim != "strafeRight")
characterAnimation.CrossFade(currentAnim = "strafeRight", IdleTransitionFadeLength );
}
else if (xDir < -epsilon)
{
if (currentAnim != "strafeLeft")
characterAnimation.CrossFade(currentAnim = "strafeLeft", IdleTransitionFadeLength );
}
}
}
// If nothing else has caused us to play the jump animation now, being
// airborne for a while seems like a good time to do it.
if (sinceNotGrounded > 0.05 && currentAnim != "jump")
characterAnimation.CrossFade(currentAnim = "jump", IdleTransitionFadeLength );
var smoothFallingVelocity = fallingVelocity * 0.4f + lastFallingVelocity * 0.65f;
lastFallingVelocity = smoothFallingVelocity;
// damp recoil
if (!controller.isGrounded)
{
recoilVelocity.x *= Mathf.Pow(recoilDamping * 10, Time.deltaTime);
recoilVelocity.y *= Mathf.Pow(recoilDamping * 100, Time.deltaTime);
recoilVelocity.z *= Mathf.Pow(recoilDamping * 10, Time.deltaTime);
}
else
{
recoilVelocity.x *= Mathf.Pow(recoilDamping / 25, Time.deltaTime);
recoilVelocity.y *= Mathf.Pow(recoilDamping * 100, Time.deltaTime);
recoilVelocity.z *= Mathf.Pow(recoilDamping / 25, Time.deltaTime);
}
// move!
Vector3 movementVelocity = smoothFallingVelocity + smoothedInputVelocity + recoilVelocity;
Vector3 movementVector = movementVelocity * Time.deltaTime;
controller.Move(movementVector);
bool doesOverlap = CheckOverlap(transform.position);
if (doesOverlap)
{
// The maximum speed we can be moving when overlapping. Prevents
// velocity from building up and eventually allowing us to
// penetrate.
const float maxVelocityMagnitudeWhenOverlapping = 60f;
fallingVelocity = Vector3.ClampMagnitude(fallingVelocity, maxVelocityMagnitudeWhenOverlapping);
if (InstantOverlapEjection)
transform.position = LastNonCollidingPosition;
else
transform.position = Vector3.Lerp(transform.position, LastNonCollidingPosition, Time.deltaTime * OverlapEjectionSpeed);
}
else
{
LastNonCollidingPosition = transform.position;
}
if (sinceNotGrounded > 0.25f && controller.isGrounded) {
if(GlobalSoundsScript.soundEnabled) {
landingSound.Play();
}
}
if (sinceNotGrounded > 0.25f && controller.isGrounded) {
if(GlobalSoundsScript.soundEnabled) {
landingSound.Play();
}
}
if (controller.isGrounded)
recoilVelocity.y = 0;
// Prevent recoil velocity from sticking us to the ceiling for a while
// by checking to see if we're hitting it. A smarter solution, honestly,
// is to raycast and then modify our velocity by the surface hit normal.
// But this is a good enough hack for now.
Vector3 aboveUs = transform.position;
aboveUs.y += 1;
bool hittingHeadOnCeiling = CheckOverlap(aboveUs);
if (!controller.isGrounded && hittingHeadOnCeiling)
{
recoilVelocity.y = Mathf.Min(0f, recoilVelocity.y);
fallingVelocity.y = Mathf.Min(0f, fallingVelocity.y);
}
}