protected void Hanging(float elapsedTime) { VerticalSpeed = 0; if (MecanimAnimator.GetBool(MecanimHashes.Hang)) { if (ActiveHangTarget == null) { MecanimAnimator.SetBool(MecanimHashes.Fall, true); return; } if (ActiveHangTarget.DoesFaceZAxis()) { HorizontalSpeed = 0.0f; Direction = Vector3.zero; } else { HorizontalSpeed = Direction.x * Settings.LedgeClimbingSpeed; if (IsHangTargetToRight) { Direction = Vector3.right; } else { Direction = Vector3.left; } } MecanimAnimator.SetBool(MecanimHashes.Hang, false); } if (ActiveHangTarget != null) { ActivePlatform = ActiveHangTarget.transform; } MecanimAnimator.SetBool(MecanimHashes.Fall, false); if (ActiveHangTarget == null) { DropHangTarget(); MecanimAnimator.SetBool(MecanimHashes.Fall, true); } else if (ActiveHangTarget is Ledge && (CharInput.Up || InputMoveForward)) { _ledge = ActiveHangTarget as Ledge; MecanimAnimator.SetBool(MecanimHashes.ClimbLedge, true); } else if (CharInput.JumpPressed) { DropHangTarget(); MecanimAnimator.SetBool(MecanimHashes.Jump, true); } else if (CharInput.Down) { DropHangTarget(); MecanimAnimator.SetBool(MecanimHashes.Fall, true); } }
// FallingState = Animator.StringToHash("Air.Falling"); protected void Falling(float elapsedTime) { // Maintain horizontal speed by default, but allow 1/2 the normal movement for horizontal input if (CharInput.Right || CharInput.Left) { ApplyMovingHorizontal(elapsedTime * 0.5f); } // Vertical Motion ApplyGravity(elapsedTime); MecanimAnimator.SetBool(MecanimHashes.Fall, false); // You can grab onto the walls while falling MecanimAnimator.SetBool(MecanimHashes.GrabWall, CanGrabWall); // You can regrab the hangable object you last let go of if (!(ActiveHangTarget is Ledge && ((Ledge)ActiveHangTarget).Obstacle) && (CanHangOffObject && ActiveHangTarget.DoesFaceXAxis() && VerticalSpeed < 0) || (CanHangOffObject && ActiveHangTarget.DoesFaceZAxis() && CharInput.Up)) { MecanimAnimator.SetBool(MecanimHashes.Hang, true); VerticalSpeed = 0; HorizontalSpeed = 0; SetMecanimAnimatorHorizontalSpeedFloat(); MecanimAnimator.SetFloat(MecanimHashes.VerticalSpeed, VerticalSpeed); } else { MecanimAnimator.SetBool(MecanimHashes.Hang, false); } }
protected void Falling(float elapsedTime) { if (CharInput.Right || CharInput.Left) // maintain horizontal momentum, but slow down if does input { ApplyMovingHorizontal(elapsedTime); } ApplyGravity(elapsedTime); MecanimAnimator.SetBool(MecanimHashes.Fall, false); if (!(ActiveHangTarget is Ledge && ((Ledge)ActiveHangTarget).Obstacle) && (CanHangOffObject && ActiveHangTarget.DoesFaceXAxis() && VerticalSpeed < 0) || (CanHangOffObject && ActiveHangTarget.DoesFaceZAxis() && CharInput.Up)) { MecanimAnimator.SetBool(MecanimHashes.Hang, true); VerticalSpeed = 0; HorizontalSpeed = 0; } else { MecanimAnimator.SetBool(MecanimHashes.Hang, false); } if (CanGrabWall && ((Direction.x > 0 && IsHangTargetToRight) || (Direction.x < 0 && !IsHangTargetToRight))) { MecanimAnimator.SetBool(MecanimHashes.GrabWall, true); } }
// RollingState = Animator.StringToHash("Ground.Rolling"); protected void Rolling(float elapsedTime) { // We only need to set motion settings at the beginning of the animation if (!MecanimAnimator.GetBool(MecanimHashes.ClimbLedge)) { return; } // We need to make sure we know what we're going to roll over. if (ActiveHangTarget == null) { Debug.LogWarning("Failed to have hang target while doing rolling!"); return; } // Meta-data about the motion we need to do MecanimAnimator.SetBool(MecanimHashes.ClimbLedge, false); Bounds ledgeBounds = ActiveHangTarget.GetComponent <Collider>().bounds; float animationTime = MecanimAnimator.GetCurrentAnimatorStateInfo(0).length; // Horizontal motion float distanceToMove = Direction.x > 0 ? ledgeBounds.max.x - Controller.bounds.center.x : ledgeBounds.min.x - Controller.bounds.center.x; HorizontalSpeed = distanceToMove / animationTime; SetMecanimAnimatorHorizontalSpeedFloat(); // Vertical motion float distanceToClimb = ledgeBounds.max.y - Controller.bounds.min.y; VerticalSpeed = distanceToClimb / animationTime; MecanimAnimator.SetFloat(MecanimHashes.VerticalSpeed, VerticalSpeed); }
// JumpingState = Animator.StringToHash("Jumping.Jumping"); // FrontflipState = Animator.StringToHash("Jumping.Frontflip"); // FrontflipLoopState = Animator.StringToHash("Jumping.FrontflipLoop"); protected void Jumping(float elapsedTime) { // We only determine vertical speed (Horizontal Speed is maintained throughout the jump) if (MecanimAnimator.GetBool(MecanimHashes.Jump)) { float jumpHeight = Settings.JumpHeight; if (CurrentState.fullPathHash == FrontflipState) { jumpHeight *= 1.5f; } VerticalSpeed = Mathf.Sqrt(2 * jumpHeight * Settings.Gravity); MecanimAnimator.SetFloat(MecanimHashes.VerticalSpeed, VerticalSpeed); MecanimAnimator.SetBool(MecanimHashes.Jump, false); } else { ApplyGravity(elapsedTime); } // You can increase horizontal speed midair ONLY if doing a sneak jump and you weren't already at max speed if (CurrentState.fullPathHash == JumpingState && (CharInput.Left || CharInput.Right)) { float prevSpeed = HorizontalSpeed; ApplyMovingHorizontal(elapsedTime * 0.5f); if (Mathf.Abs(HorizontalSpeed) < Mathf.Abs(prevSpeed)) { HorizontalSpeed = prevSpeed; } else if (Direction.x > 0 && HorizontalSpeed > 0.79f * Settings.MaxHorizontalSpeed) { HorizontalSpeed = 0.79f * Settings.MaxHorizontalSpeed; } else if (Direction.x < 0 && HorizontalSpeed < -0.79f * Settings.MaxHorizontalSpeed) { HorizontalSpeed = -0.79f * Settings.MaxHorizontalSpeed; } SetMecanimAnimatorHorizontalSpeedFloat(); } // You can grab onto walls while jumping MecanimAnimator.SetBool(MecanimHashes.GrabWall, CanGrabWall); // You can hang off most objects while jumping bool shouldHang = (CanHangOffObject && ActiveHangTarget.DoesFaceXAxis() && VerticalSpeed < 0) || (CanHangOffObject && ActiveHangTarget.DoesFaceZAxis() && CharInput.Up); MecanimAnimator.SetBool(MecanimHashes.Hang, shouldHang); // You can re-grab ropes you just let go of bool shouldRegrabRope = CharInput.Up && PreviousHangTarget != null && PreviousHangTarget.GetComponent <Collider>().bounds.Contains(transform.position); if (shouldRegrabRope) { AddHangTarget(PreviousHangTarget); MecanimAnimator.SetBool(MecanimHashes.ClimbRope, true); } }
// WalljumpingState = Animator.StringToHash("Wall.Walljumping"); protected void Walljumping(float elapsedTime) { // Determine motion on the first frame if (MecanimAnimator.GetBool(MecanimHashes.JumpWall)) { Direction = -Direction; HorizontalSpeed = Settings.MaxHorizontalSpeed * Direction.x * 0.79f; SetMecanimAnimatorHorizontalSpeedFloat(); VerticalSpeed = Mathf.Sqrt(2 * Settings.JumpHeight * Settings.Gravity); MecanimAnimator.SetFloat(MecanimHashes.VerticalSpeed, VerticalSpeed); _wallJumpCount++; MecanimAnimator.SetBool(MecanimHashes.JumpWall, false); } else { ApplyGravity(elapsedTime); } // You eventually start falling down if (transform.position.y >= LastGroundHeight - 1) { MecanimAnimator.SetBool(MecanimHashes.Fall, false); } // You can do consecutive wall grabs/jumps if (CanGrabWall) { MecanimAnimator.SetBool(MecanimHashes.GrabWall, true); } // You can grab onto ledges if (!(ActiveHangTarget is Ledge && ((Ledge)ActiveHangTarget).Obstacle) && (CanHangOffObject && ActiveHangTarget.DoesFaceXAxis() && VerticalSpeed < 0) || (CanHangOffObject && ActiveHangTarget.DoesFaceZAxis() && CharInput.Up)) { MecanimAnimator.SetBool(MecanimHashes.Hang, true); VerticalSpeed = 0; MecanimAnimator.SetFloat(MecanimHashes.VerticalSpeed, VerticalSpeed); HorizontalSpeed = 0; } else { MecanimAnimator.SetBool(MecanimHashes.Hang, false); } }
protected void Jumping(float elapsedTime) { if (Mathf.Abs(CharInput.Horizontal) > 0.1) { ApplyMovingHorizontal(elapsedTime); } if (MecanimAnimator.GetBool(MecanimHashes.Jump)) { if (CharInput.JumpLeft || CharInput.JumpLeftReleased) { Direction = Vector3.left; HorizontalSpeed = -1.0f * Settings.MaxHorizontalSpeed; } else if (CharInput.JumpRight || CharInput.JumpRightReleased) { Direction = Vector3.right; HorizontalSpeed = 1.0f * Settings.MaxHorizontalSpeed; } VerticalSpeed = Mathf.Sqrt(2 * Settings.JumpHeight * Settings.Gravity); MecanimAnimator.SetBool(MecanimHashes.Jump, false); } else { ApplyGravity(elapsedTime); } //ApplyBiDirection(); if (transform.position.y >= LastGroundHeight - 1) { MecanimAnimator.SetBool(MecanimHashes.Fall, false); } MecanimAnimator.SetBool(MecanimHashes.Hang, (CanHangOffObject && ActiveHangTarget.DoesFaceXAxis() && VerticalSpeed < 0) || (CanHangOffObject && ActiveHangTarget.DoesFaceZAxis() && CharInput.Up)); if (CanGrabWall && ((Direction.x > 0 && IsHangTargetToRight) || (Direction.x < 0 && !IsHangTargetToRight))) { MecanimAnimator.SetBool(MecanimHashes.GrabWall, true); } }
// BackflipState = Animator.StringToHash("Air.Backflip"); protected void Backflip(float elapsedTime) { // We determine our target speed on the first frame of the action if (MecanimAnimator.GetBool(MecanimHashes.Backflip)) { MecanimAnimator.SetBool(MecanimHashes.Backflip, false); _desiredDirectionX = -Direction.x; _desiredSpeed = -HorizontalSpeed; VerticalSpeed = Mathf.Sqrt(2 * Settings.JumpHeight * 1.5f * Settings.Gravity); MecanimAnimator.SetFloat(MecanimHashes.VerticalSpeed, VerticalSpeed); } else { ApplyGravity(elapsedTime); } // Adjust horizontal speed frame by frame float accelerationSmoothing = Settings.HorizontalAcceleration * elapsedTime; if (TimeInCurrentState > 0.15f) { Vector3 newDir = new Vector3(Mathf.Lerp(Direction.x, _desiredDirectionX, accelerationSmoothing), 0, 0); if (newDir.x * Direction.x < 0) { HorizontalSpeed = -HorizontalSpeed; } Direction = newDir; } accelerationSmoothing = Settings.HorizontalAcceleration * elapsedTime; HorizontalSpeed = Mathf.Lerp(HorizontalSpeed, _desiredSpeed, accelerationSmoothing); SetMecanimAnimatorHorizontalSpeedFloat(); // You can grab onto objects even in the middle of a backflip bool shouldHang = (CanHangOffObject && ActiveHangTarget.DoesFaceXAxis() && VerticalSpeed < 0) || (CanHangOffObject && ActiveHangTarget.DoesFaceZAxis() && CharInput.Up); MecanimAnimator.SetBool(MecanimHashes.Hang, shouldHang); // Make sure we don't enter the other Air states MecanimAnimator.SetBool(MecanimHashes.Jump, false); MecanimAnimator.SetBool(MecanimHashes.Fall, false); }
protected void ClimbingVertical(float elapsedTime) { if (ActiveHangTarget == null) { DropHangTarget(); MecanimAnimator.SetBool(MecanimHashes.Fall, true); return; } HorizontalSpeed = 0; float vertical = CharInput.Vertical; ApplyClimbingVertical(vertical); if (ActiveHangTarget.DoesFaceZAxis()) { Direction = Vector3.zero; } MecanimAnimator.SetFloat(MecanimHashes.HorizontalSpeed, HorizontalSpeed); MecanimAnimator.SetFloat(MecanimHashes.VerticalSpeed, VerticalSpeed); if (CharInput.InteractionPressed) { MecanimAnimator.SetBool(MecanimHashes.Fall, true); DropHangTarget(); return; } else { MecanimAnimator.SetBool(MecanimHashes.Fall, false); } if (CharInput.JumpActive) { MecanimAnimator.SetBool(MecanimHashes.Jump, true); DropHangTarget(); } }
// ClimbingLadderState = Animator.StringToHash("Climbing.ClimbingLadder"); // ClimbingRopeState = Animator.StringToHash("Climbing.ClimbingRope"); protected void ClimbingVertical(float elapsedTime) { // Make sure we have something to climb on if (ActiveHangTarget == null) { DropHangTarget(); MecanimAnimator.SetBool(MecanimHashes.Fall, true); return; } // We let go when we touch the floor if (IsGrounded && TimeInCurrentState > 0) { DropHangTarget(); return; } // Horizontal motion //if(VerticalSpeed != 0 && ActiveHangTarget.DoesFaceZAxis()) // ApplyClimbingStrafing( CharInput.Horizontal ); //else HorizontalSpeed = 0; SetMecanimAnimatorHorizontalSpeedFloat(); // Make sure we're facing the correct direction if (ActiveHangTarget.DoesFaceZAxis()) { Direction = Vector3.zero; } else { bool ladderToRight = ActiveHangTarget.transform.position.x - transform.position.x > 0.0f; if (ladderToRight) { Direction = Vector3.right; } else { Direction = Vector3.left; } } // The vertical motion is the most important when climbing ApplyClimbingVertical(CharInput.Vertical); if (VerticalSpeed == 0) { if (InputMoveForward) { VerticalSpeed = Settings.LadderClimbingSpeed; } else if (InputMoveBackward) { VerticalSpeed = -Settings.LadderClimbingSpeed; } MecanimAnimator.SetFloat(MecanimHashes.VerticalSpeed, VerticalSpeed); MecanimAnimator.SetBool(MecanimHashes.Fall, false); } // You can press up/forward on ledges to climb up if (ActiveHangTarget is Ledge && (CharInput.Up || InputMoveForward)) { _ledge = ActiveHangTarget as Ledge; MecanimAnimator.SetBool(MecanimHashes.ClimbLedge, true); // You can let go of what you're climbing with the pickup button } else if (CharInput.PickupPressed) { MecanimAnimator.SetBool(MecanimHashes.Fall, true); MecanimAnimator.SetBool(MecanimHashes.ClimbRope, false); DropHangTarget(); return; } // You can jump off ropes and ladders AllowAirJump(); }
// HangingState = Animator.StringToHash("Climbing.Hanging"); protected void Hanging(float elapsedTime) { // Make sure we actually have something to hang on if (ActiveHangTarget == null) { DropHangTarget(); MecanimAnimator.SetBool(MecanimHashes.Fall, true); Debug.LogWarning("Player lost track of hang target and fell!"); return; } // We determine all our motion on the first frame if (MecanimAnimator.GetBool(MecanimHashes.Hang)) { if (ActiveHangTarget.DoesFaceZAxis()) { HorizontalSpeed = 0.0f; Direction = Vector3.zero; } else { HorizontalSpeed = Direction.x * Settings.LedgeClimbingSpeed; if (IsHangTargetToRight) { Direction = Vector3.right; } else { Direction = Vector3.left; } } SetMecanimAnimatorHorizontalSpeedFloat(); VerticalSpeed = 0; MecanimAnimator.SetFloat(MecanimHashes.VerticalSpeed, VerticalSpeed); MecanimAnimator.SetBool(MecanimHashes.Hang, false); } // Stay on whatever we're hanging on, even if it's moving ActivePlatform = ActiveHangTarget.transform; MecanimAnimator.SetBool(MecanimHashes.Fall, false); // You can press up/forward on ledges to climb up if (ActiveHangTarget is Ledge && (CharInput.Up || InputMoveForward)) { _ledge = ActiveHangTarget as Ledge; MecanimAnimator.SetBool(MecanimHashes.ClimbLedge, true); // You can jump off whatever you're hanging } else if (CharInput.JumpPressed) { AllowAirJump(); // You can also just let go } else if (CharInput.PickupPressed) { DropHangTarget(); MecanimAnimator.SetBool(MecanimHashes.Fall, true); } }