using System; using Framework.Input.States; using UnityEngine; namespace Framework.Actors.Platformer { /// Lets the player control a character walking or running on the ground public class GroundMove : PlayerMove { /// Called when the actor has started the move public override void OnStarted() { base.OnStarted(); EnableGravity(true); } /// Called once per physics frame /// /// Updates the world position of the actor /// public override void FixedUpdate() { base.FixedUpdate(); // Update the grounded state (the actor's physics component will have // moved it before or after this code ran, so the isGrounded state is now stale) bool isGrounded = RecheckGrounding(); // If the actor is grounded, reset the jump count if(isGrounded) { ActorController.ConsecutiveJumpCount = 0; } else { // If the actor walks off a cliff, he'll be airborne SwitchToAirMove(jumped: false); ActorController.ActiveMove.FixedUpdate(); return; } PlatformerInputState inputState = InputManager.GetState(); // Standard left/right movement of the actor handleHorizontalMovement(inputState); // Begin dashing if the player hits the dash key and it's enabled if(inputState.Dash.WasTriggered) { if(Abilities.CanDash) { SwitchToDashMove(); return; } } // If the player pressed the jump key, we'll be airborne with upward velocity if(inputState.Jump.WasTriggered) { if(ActorController.ConsecutiveJumpCount < Abilities.JumpCount) { SwitchToAirMove(jumped: true); return; } } // Pressing down while standing still will switch to a squatting stance if(inputState.Down.IsActive) { Vector3 velocity = GetVelocity(); if(Abilities.CanSquat && (Mathf.Abs(velocity.x) < Abilities.WalkingSpeed)) { SwitchToSquatMove(); return; } if(Mathf.Abs(velocity.x) > Abilities.SpeedForFloorSlide) { SwitchToSlideMove(); } } } /// /// Switches the presenter to the animation state appropriate for this move /// protected override void SetPresenterState() { PlatformerActorPresenter presenter = ActorPresenter; if(presenter != null) { presenter.SetGroundedState(); } } /// Returns the speed at which the actor should move /// Inputs the player has made this frame /// The speed at which the actor should move protected virtual float GetMovementSpeed(PlatformerInputState inputState) { if(Abilities.CanSprint && inputState.Sprint.IsActive) { return Abilities.RunningSpeed; } else { return Abilities.WalkingSpeed; } } /// Movement logic to move the actor to the left and right /// Inputs the player has made this frame private void handleHorizontalMovement(PlatformerInputState inputState) { // Determine the speed at which the player wants to move and the highest // possible speed the actor could achieve (used to calculate acceleration) float fastestSpeed, targetSpeed; { fastestSpeed = GetMovementSpeed(inputState); targetSpeed = fastestSpeed * inputState.Horizontal; } float acceleration = fastestSpeed / Abilities.SecondsToFullSpeed; AccelerateToVelocity(targetSpeed, acceleration); // Turn the actor towards the direction it is moving float horizontalDirection = ActorPhysics.Velocity.x; if(horizontalDirection < Abilities.WalkingSpeed * -0.1f) { ActorController.FacingDirection = -1.0f; } else if(horizontalDirection > Abilities.WalkingSpeed * 0.1f) { ActorController.FacingDirection = +1.0f; } } } } // namespace Framework.Actors.Platformer