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