using System;
using Framework.Input.States;
using UnityEngine;
namespace Framework.Actors.Shooter {
/// 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();
}
ShooterInputState inputState = InputManager.GetState();
// Standard left/right movement of the actor
handleHorizontalMovement(inputState);
// 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;
}
}
}
///
/// Switches the presenter to the animation state appropriate for this move
///
protected override void SetPresenterState() {
ShooterActorPresenter 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(ShooterInputState 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(ShooterInputState 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, runningSpeed, strafingSpeed;
{
fastestSpeed = GetMovementSpeed(inputState);
runningSpeed = fastestSpeed * inputState.Running;
strafingSpeed = Abilities.WalkingSpeed * inputState.Strafing;
}
float acceleration = fastestSpeed / Abilities.SecondsToFullSpeed;
AccelerateToVelocity(runningSpeed, strafingSpeed, acceleration);
// If the player is moving around, orient the actor towards the direction
// the player is looking (it would look very silly if the player looked to
// his left shoulder, pressed forward and ran sideways for longer distances).
if((Math.Abs(runningSpeed) + Mathf.Abs(strafingSpeed)) > Abilities.WalkingSpeed * 0.1f) {
ActorController.RotateOnlyBodyOnYTowards(
ActorController.LookDirection, Abilities.TurnDegreesPerSecond * Time.fixedDeltaTime
);
}
}
}
} // namespace Framework.Actors.Shooter