BITFALL/Assets/Artists/Scripts/Player/CharacterControllerPro/PlayerCharacterStates.cs

830 lines
22 KiB
C#
Raw Normal View History

2023-08-23 01:59:40 +08:00
using System;
2023-08-27 02:58:19 +08:00
using BITFALL.Entities.Player.Movement.States;
2023-11-15 23:54:54 +08:00
using BITFALL.Player.Equip;
2023-08-23 01:59:40 +08:00
using BITFALL.Player.Movement;
2024-04-19 00:40:34 +08:00
using BITFALL.Sensors;
2023-10-20 19:31:12 +08:00
using BITKit;
using BITKit.Entities;
2023-11-30 00:23:23 +08:00
using BITKit.PlayerCamera;
2024-04-19 00:40:34 +08:00
using BITKit.Sensors;
2023-08-23 01:59:40 +08:00
using BITKit.StateMachine;
using Cysharp.Threading.Tasks;
2023-08-23 01:59:40 +08:00
using Lightbug.CharacterControllerPro.Core;
2024-04-19 00:40:34 +08:00
using Steamworks.ServerList;
2023-08-23 01:59:40 +08:00
using UnityEngine;
using UnityEngine.InputSystem;
2023-08-23 01:59:40 +08:00
// ReSharper disable InvertIf
// ReSharper disable RedundantJumpStatement
// ReSharper disable ConvertToConstant.Global
2023-08-27 02:58:19 +08:00
namespace BITFALL.Entities.Player.Movement.States
2023-08-23 01:59:40 +08:00
{
2023-11-30 00:23:23 +08:00
public abstract class BasicMovement : PlayerCharacterState, IPlayerMovementState
2023-08-23 01:59:40 +08:00
{
2024-04-06 16:33:57 +08:00
[SerializeField] internal Vector3 initialCameraPosition;
[SerializeField] internal Vector2 initialSize=new Vector2(0.8f,1.6f);
[SerializeField] internal float initialSpeed = 3f;
[SerializeField] internal float initialJumpForce = 5f;
2023-10-20 19:31:12 +08:00
[Inject] protected IKnockdown knockdown;
2023-11-30 00:23:23 +08:00
[Inject] protected IPlayerCameraService _cameraService;
2023-10-20 19:31:12 +08:00
2024-01-27 04:09:57 +08:00
public override void OnStateEntry(IState old)
{
base.OnStateEntry(old);
2024-04-06 16:33:57 +08:00
actor.SetSize(initialSize,CharacterActor.SizeReferenceType.Bottom);
2024-04-19 21:43:30 +08:00
self.ReferenceSpeed = initialSpeed;
2024-01-27 04:09:57 +08:00
}
2023-08-23 01:59:40 +08:00
public override void BeforeUpdateMovement(float deltaTime)
{
2024-04-19 21:43:30 +08:00
self.CurrentCameraPosition.shouldBe = initialCameraPosition;
2023-08-23 01:59:40 +08:00
}
2023-10-20 19:31:12 +08:00
public override void AfterUpdateMovement(float deltaTime)
{
if (knockdown.IsKnockdown)
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Knockdown>();
}
2024-02-21 01:40:53 +08:00
2024-04-19 21:43:30 +08:00
if (knockdown.IsKnockdown is false && self.ExpectParachute.shouldBe)
2023-10-20 19:31:12 +08:00
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Parachute>();
self.ExpectParachute.Reset();
2023-11-30 00:23:23 +08:00
}
2024-02-21 01:40:53 +08:00
2024-04-19 21:43:30 +08:00
if (self.RequestClimb is false) return;
if(self.topBlocked)return;
2024-02-21 01:40:53 +08:00
2024-04-19 21:43:30 +08:00
if (self.vaultPoint.TryGetClosePoint(out var closePoint))
2024-02-21 01:40:53 +08:00
{
2024-04-19 21:43:30 +08:00
self.ExpectClimb.shouldBe = closePoint;
self.TransitionState<Vault>();
self.ExpectJump.Reset();
2024-04-26 03:55:43 +08:00
//self.RequestClimb = false;
2024-02-21 01:40:53 +08:00
return;
}
2024-04-22 01:21:28 +08:00
if (actor.Velocity.y > 0)
2023-11-21 18:05:18 +08:00
{
2024-04-22 01:21:28 +08:00
if (self.climbClosePoint.TryGetClosePoint(out closePoint))
{
self.ExpectClimb.shouldBe = closePoint;
self.TransitionState<Climb>();
self.ExpectJump.Reset();
2024-04-26 03:55:43 +08:00
//self.RequestClimb = false;
2024-04-22 01:21:28 +08:00
return;
}
2024-02-21 01:40:53 +08:00
2024-04-22 01:21:28 +08:00
if (self.Stamina > 0)
if (self.edgeClimbPoint.TryGetClosePoint(out closePoint))
{
self.ExpectClimb.shouldBe = closePoint;
self.TransitionState<EdgeClimb>();self.ExpectJump.Reset();
self.RequestClimb = false;
return;
}
}
else
2024-02-21 01:40:53 +08:00
{
2024-04-22 01:21:28 +08:00
if (self.Stamina > 0)
{
if (self.edgeClimbPoint.TryGetClosePoint(out closePoint))
{
self.ExpectClimb.shouldBe = closePoint;
self.TransitionState<EdgeClimb>();self.ExpectJump.Reset();
self.RequestClimb = false;
return;
}
if (self.climbClosePoint.TryGetClosePoint(out closePoint))
{
self.ExpectClimb.shouldBe = closePoint;
self.TransitionState<Climb>();
self.ExpectJump.Reset();
2024-04-26 03:55:43 +08:00
//self.RequestClimb = false;
2024-04-22 01:21:28 +08:00
return;
}
}
2023-10-20 19:31:12 +08:00
}
2024-04-22 01:21:28 +08:00
2023-10-20 19:31:12 +08:00
}
2023-11-30 00:23:23 +08:00
public override void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime)
2023-08-23 01:59:40 +08:00
{
2024-04-19 21:43:30 +08:00
var rotation = Quaternion.Euler(0, self.LookInput.y, 0);
var movementInput = self.MovementInput;
2023-11-30 00:23:23 +08:00
if (_cameraService?.IsCameraActivated is false)
{
rotation =Quaternion.LookRotation( _cameraService.CameraRotation * Vector3.forward,Vector3.up);
}
var moveVelocity = rotation * new Vector3(
2024-04-19 21:43:30 +08:00
movementInput.x * Mathf.Min(self.initialSpeed, initialSpeed),
2023-11-21 18:05:18 +08:00
0,
2023-11-30 00:23:23 +08:00
movementInput.z * initialSpeed
);
if (_cameraService?.IsCameraActivated is false)
{
moveVelocity = rotation * movementInput * initialSpeed;
}
2024-04-19 21:43:30 +08:00
if (self.limitSpeed.Allow)
2023-11-30 00:23:23 +08:00
{
2024-04-19 21:43:30 +08:00
switch (self.CurrentState)
2023-11-30 00:23:23 +08:00
{
case IPlayerWalkState:
case IPlayerCrouchState:
2024-04-19 21:43:30 +08:00
moveVelocity = Vector3.ClampMagnitude(moveVelocity, self.limitSpeed.Value);
2023-11-30 00:23:23 +08:00
break;
}
}
2024-04-19 21:43:30 +08:00
if (self.IsGrounded)
2023-08-23 01:59:40 +08:00
{
var effectiveGroundNormal = actor.GroundStableNormal;
2023-11-30 00:23:23 +08:00
2023-08-23 01:59:40 +08:00
var inputRight = Vector3.Cross(moveVelocity, Vector3.up);
2023-11-30 00:23:23 +08:00
var reorientedInput = Vector3.Cross(effectiveGroundNormal, inputRight).normalized *
moveVelocity.magnitude;
var targetMovementVelocity = reorientedInput; //* initialSpeed;
2023-08-23 01:59:40 +08:00
// Smooth movement Velocity
2023-11-30 00:23:23 +08:00
var newVelocity =
Vector3.Lerp(currentVelocity, targetMovementVelocity, 1f - Mathf.Exp(-16 * deltaTime));
currentVelocity = newVelocity;
2023-09-01 14:33:54 +08:00
2024-04-19 21:43:30 +08:00
if (self.ExpectJump.shouldBe)
2023-09-01 14:33:54 +08:00
{
actor.ForceNotGrounded();
2024-03-18 18:20:23 +08:00
2024-03-25 16:08:26 +08:00
// if (characterController.landFreeze.AllowUpdateWithoutReset is false)
// {
// currentVelocity = Vector3.Lerp(currentVelocity, default, 0.8f);
// }
2024-03-18 18:20:23 +08:00
currentVelocity.y+= initialJumpForce;
2024-04-19 21:43:30 +08:00
self.ExpectJump.Reset();
2023-11-30 00:23:23 +08:00
2024-04-19 21:43:30 +08:00
self.ExecuteCommand<OnPlayerJumpCommand>();
2023-09-01 14:33:54 +08:00
}
2023-08-23 01:59:40 +08:00
}
else
{
2024-04-19 21:43:30 +08:00
if (moveVelocity.sqrMagnitude > 0f && self.landFreeze.AllowUpdateWithoutReset)
2023-08-23 01:59:40 +08:00
{
var addedVelocity = moveVelocity * (3 * deltaTime);
var currentVelocityOnInputsPlane = Vector3.ProjectOnPlane(currentVelocity, Vector3.up);
// Limit air velocity from inputs
if (currentVelocityOnInputsPlane.magnitude < 5)
{
// clamp addedVel to make total vel not exceed max vel on inputs plane
Vector3 newTotal = Vector3.ClampMagnitude(currentVelocityOnInputsPlane + addedVelocity, 5);
addedVelocity = newTotal - currentVelocityOnInputsPlane;
}
else
{
// Make sure added vel doesn't go in the direction of the already-exceeding velocity
if (Vector3.Dot(currentVelocityOnInputsPlane, addedVelocity) > 0f)
{
2023-11-30 00:23:23 +08:00
addedVelocity =
Vector3.ProjectOnPlane(addedVelocity, currentVelocityOnInputsPlane.normalized);
2023-08-23 01:59:40 +08:00
}
}
// Prevent air-climbing sloped walls
if (actor.WallCollision)
{
if (Vector3.Dot(currentVelocity + addedVelocity, addedVelocity) > 0f)
{
2023-11-30 00:23:23 +08:00
var perpenticularObstructionNormal = Vector3
.Cross(Vector3.Cross(Vector3.up, actor.GroundContactNormal), Vector3.up).normalized;
2023-08-23 01:59:40 +08:00
addedVelocity = Vector3.ProjectOnPlane(addedVelocity, perpenticularObstructionNormal);
}
}
// Apply added velocity
currentVelocity += addedVelocity;
}
2024-03-25 16:08:26 +08:00
else
{
var tempVelocity = currentVelocity;
tempVelocity = Vector3.Lerp(tempVelocity, default, 2*deltaTime);
currentVelocity.x = tempVelocity.x;
currentVelocity.z = tempVelocity.z;
}
2023-08-23 01:59:40 +08:00
// Gravity
currentVelocity += -Vector3.up * (30 * deltaTime);
// Drag
2024-03-25 16:08:26 +08:00
currentVelocity *= (1f / (1f + 0.1f * deltaTime));
2023-08-23 01:59:40 +08:00
}
}
2023-11-30 00:23:23 +08:00
2023-08-23 01:59:40 +08:00
public override void UpdateRotation(ref Quaternion currentRotation, float deltaTime)
{
2024-04-19 21:43:30 +08:00
var newRotation = Quaternion.Euler(0, self.LookInput.y, 0);
2023-11-30 00:23:23 +08:00
if (_cameraService.IsCameraActivated is false)
{
if (Physics.Raycast(_cameraService.CameraPosition, _cameraService.CameraRotation * Vector3.forward,
out var hit, 256, LayerMask.GetMask("Default"), QueryTriggerInteraction.Ignore))
{
2024-04-19 21:43:30 +08:00
self.ViewForward = (hit.point - (self.Position +
self.Rotation *
self.ViewCenter)).normalized;
2023-11-30 00:23:23 +08:00
2024-04-19 21:43:30 +08:00
newRotation = Quaternion.LookRotation(self.ViewForward);
self.ViewRotation = newRotation;
2023-11-30 00:23:23 +08:00
2024-04-19 21:43:30 +08:00
self.FocusPoint = hit.point;
2023-11-30 00:23:23 +08:00
Debug.DrawLine(_cameraService.CameraPosition, hit.point, Color.green, 0.1f);
2024-04-19 21:43:30 +08:00
Debug.DrawLine(self.Position + self.ViewCenter,
self.Position +
self.ViewCenter + self.ViewRotation * Vector3.forward
2023-11-30 00:23:23 +08:00
, Color.blue, 0.1f);
}
else
{
2024-04-19 21:43:30 +08:00
self.ViewRotation = Quaternion.Euler(self.LookInput);;
2023-11-30 00:23:23 +08:00
2024-04-19 21:43:30 +08:00
self.FocusPoint = self.Position +
self.ViewRotation * Vector3.forward * 256;
2023-11-30 00:23:23 +08:00
Debug.DrawLine(_cameraService.CameraPosition, _cameraService.CameraRotation * Vector3.forward,
Color.red, 0.1f);
}
2024-04-19 21:43:30 +08:00
var rotationDirection = _cameraService.CameraRotation * self.MovementInput;
2023-11-30 00:23:23 +08:00
rotationDirection = Vector3.ProjectOnPlane(rotationDirection, Vector3.up);
if (rotationDirection.sqrMagnitude >= 0.16f)
{
var newPlayerRotation =Quaternion.LookRotation(rotationDirection) ;
currentRotation = Quaternion.Lerp(currentRotation, newPlayerRotation, 1f - Mathf.Exp(-16 * deltaTime));
}
2024-04-19 21:43:30 +08:00
if (self.allowFocus)
2023-11-30 00:23:23 +08:00
{
currentRotation =
Quaternion.LookRotation(_cameraService.CameraRotation * Vector3.forward, Vector3.up);
}
}
else
{
currentRotation = newRotation;
}
2023-08-23 01:59:40 +08:00
}
}
2023-11-30 00:23:23 +08:00
2023-08-23 01:59:40 +08:00
[Serializable]
2024-04-06 16:33:57 +08:00
public sealed class Walk : BasicMovement, IPlayerWalkState
2023-08-23 01:59:40 +08:00
{
2024-01-27 04:09:57 +08:00
[Inject] private InputActionGroup _inputActionGroup;
2024-04-06 16:33:57 +08:00
2023-08-23 01:59:40 +08:00
public override void AfterUpdateMovement(float deltaTime)
{
2023-10-20 19:31:12 +08:00
base.AfterUpdateMovement(deltaTime);
2024-04-19 21:43:30 +08:00
if (self.CurrentState != this) return;
switch (self.ExpectRun.shouldBe, self.ExpectCrouch.shouldBe)
2023-08-23 01:59:40 +08:00
{
2024-04-19 21:43:30 +08:00
case (_,_) when self.topBlocked && self.IsGrounded:
2024-04-06 16:33:57 +08:00
case (_, true):
2024-04-19 21:43:30 +08:00
self.TransitionState<Crouch>();
2023-11-15 23:54:54 +08:00
return;
2024-04-19 21:43:30 +08:00
case (true, false) when self.pauseRun.Allow is false &&
self.MovementInput.z > 0:
self.TransitionState<Run>();
2023-11-15 23:54:54 +08:00
return;
2023-08-23 01:59:40 +08:00
}
}
}
2024-04-19 00:40:34 +08:00
[Serializable]
public sealed class Crawl : BasicMovement,IPlayerCrawlState
{
[Inject] private IEquipService _equipService;
public override void OnStateEntry(IState old)
{
_equipService.AllowEquip.AddDisableElements(this);
2024-04-19 21:43:30 +08:00
self.LimitViewAngle = 20;
2024-04-19 00:40:34 +08:00
base.OnStateEntry(old);
}
public override void AfterUpdateMovement(float deltaTime)
{
if (actor.IsGrounded is false)
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Walk>();
2024-04-19 00:40:34 +08:00
return;
}
2024-04-19 21:43:30 +08:00
self.CurrentCameraPosition.shouldBe = self.FpvLocalPosition;
2024-04-19 00:40:34 +08:00
}
public override void UpdateRotation(ref Quaternion currentRotation, float deltaTime)
{
var targetRotation = currentRotation;
base.UpdateRotation(ref targetRotation,deltaTime);
currentRotation = Quaternion.RotateTowards(currentRotation,targetRotation,90*deltaTime);
}
public override void OnStateExit(IState old, IState newState)
{
base.OnStateExit(old, newState);
2024-04-19 21:43:30 +08:00
self.LimitViewAngle = 0;
2024-04-19 00:40:34 +08:00
_equipService.AllowEquip.RemoveDisableElements(this);
}
}
2023-10-20 19:31:12 +08:00
[Serializable]
public sealed class Parachute : PlayerCharacterState, IPlayerParachuteState
{
[SerializeField] private float moveDamping = 3f;
[SerializeField] private float damping = 1f;
2023-11-15 23:54:54 +08:00
[Inject] private IEquipService _equipService;
2023-10-20 19:31:12 +08:00
public override void OnStateEntry(IState old)
{
2023-11-15 23:54:54 +08:00
base.OnStateEntry(old);
2024-04-19 21:43:30 +08:00
self.InvokeOpenParachute();
2023-11-15 23:54:54 +08:00
_equipService.AllowEquip.AddDisableElements(this);
2024-04-19 00:40:34 +08:00
var velocity = actor.Velocity;
velocity.y = Mathf.Clamp(velocity.y, -2, 2);
actor.Velocity = velocity;
2023-10-20 19:31:12 +08:00
}
public override void OnStateExit(IState old, IState newState)
{
2023-11-15 23:54:54 +08:00
base.OnStateExit(old, newState);
2024-04-19 21:43:30 +08:00
self.InvokeCloseParachute();
2023-11-15 23:54:54 +08:00
_equipService.AllowEquip.RemoveDisableElements(this);
2023-10-20 19:31:12 +08:00
}
public override void UpdateRotation(ref Quaternion currentRotation, float deltaTime)
{
2024-04-19 21:43:30 +08:00
currentRotation = Quaternion.Euler(0,self.LookInput.y,0);
2023-10-20 19:31:12 +08:00
}
public override void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime)
{
2024-04-19 21:43:30 +08:00
var rotation = Quaternion.Euler(0,self.LookInput.y,0);
var moveVelocity = rotation * self.MovementInput;
2023-10-20 19:31:12 +08:00
currentVelocity.y =
Mathf.MoveTowards(
currentVelocity.y,
-8,
damping * deltaTime
);
currentVelocity+= moveVelocity.normalized * (moveDamping * deltaTime);
currentVelocity.x = Mathf.Clamp(currentVelocity.x, -moveDamping, moveDamping);
currentVelocity.z = Mathf.Clamp(currentVelocity.z, -moveDamping, moveDamping);
}
public override void AfterUpdateMovement(float deltaTime)
{
if (actor.IsGrounded)
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Walk>();
2023-10-20 19:31:12 +08:00
}
2024-04-19 21:43:30 +08:00
self.ExpectParachute.Reset();
self.CurrentCameraPosition.shouldBe = self.FpvLocalPosition;
2023-10-20 19:31:12 +08:00
}
}
2023-08-23 01:59:40 +08:00
[Serializable]
public sealed class Run:BasicMovement,IPlayerRunState
{
public override void OnStateEntry(IState old)
{
2024-04-19 21:43:30 +08:00
self.ExpectRun.being = true;
2023-08-23 01:59:40 +08:00
}
public override void OnStateExit(IState old, IState newState)
{
2024-04-19 21:43:30 +08:00
self.ExpectRun.being = false;
2023-08-23 01:59:40 +08:00
}
2024-04-19 00:40:34 +08:00
public override void UpdateRotation(ref Quaternion currentRotation, float deltaTime)
{
if (_cameraService.IsCameraActivated is false)
{
base.UpdateRotation(ref currentRotation, deltaTime);
return;
}
var baseRotation = Quaternion.identity;
base.UpdateRotation(ref baseRotation, deltaTime);
2024-04-19 21:43:30 +08:00
var targetRotation = Quaternion.LookRotation(baseRotation * self.MovementInput);
2024-04-19 00:40:34 +08:00
float maxAngleDelta = 30; // 你可以根据需要调整最大角度差值
float maxDeltaMagnitude = Mathf.Sin(Mathf.Deg2Rad * maxAngleDelta / 2);
targetRotation = Quaternion.RotateTowards(targetRotation,baseRotation , maxDeltaMagnitude);
var max = Quaternion.RotateTowards(targetRotation, currentRotation, maxAngleDelta);
var lerp = Quaternion.Lerp(currentRotation, targetRotation, 12 * deltaTime);
if (Quaternion.Angle(currentRotation, max) < Quaternion.Angle(currentRotation, lerp))
{
currentRotation = lerp;
}
else
{
currentRotation = max;
}
}
public override void OnStateUpdate(float deltaTime)
{
base.OnStateUpdate(deltaTime);
2024-04-19 21:43:30 +08:00
AudioSensorService.MakeNoise(actor.Position,self.transform,3,new MovementNoise());
2024-04-19 00:40:34 +08:00
}
2023-08-23 01:59:40 +08:00
public override void AfterUpdateMovement(float deltaTime)
{
2023-10-20 19:31:12 +08:00
base.AfterUpdateMovement(deltaTime);
2024-02-21 01:40:53 +08:00
2024-04-19 21:43:30 +08:00
switch (self.CurrentState)
2023-11-15 23:54:54 +08:00
{
2024-02-21 01:40:53 +08:00
case Walk:
case Run:
case Sprint:
case Crouch:
2024-04-19 21:43:30 +08:00
switch (self.ExpectRun.shouldBe, self.ExpectCrouch.shouldBe)
2024-02-21 01:40:53 +08:00
{
case (_, true):
2024-04-19 21:43:30 +08:00
self.TransitionState<Crouch>();
2024-02-21 01:40:53 +08:00
return;
case (false, false):
2024-04-19 21:43:30 +08:00
self.TransitionState<Walk>();
2024-02-21 01:40:53 +08:00
return;
}
2024-04-19 00:40:34 +08:00
if (_cameraService.IsCameraActivated)
2024-02-21 01:40:53 +08:00
{
2024-04-19 21:43:30 +08:00
if (self.MovementInput.z <= 0)
2024-04-19 00:40:34 +08:00
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Walk>();
2024-04-19 00:40:34 +08:00
return;
}
}
else
{
2024-04-19 21:43:30 +08:00
if (self.MovementInput == default)
2024-04-19 00:40:34 +08:00
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Walk>();
2024-04-19 00:40:34 +08:00
return;
}
2024-02-21 01:40:53 +08:00
}
2024-04-19 21:43:30 +08:00
if (self.pauseRun.Allow)
2024-02-21 01:40:53 +08:00
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Walk>();
2024-02-21 01:40:53 +08:00
return;
}
2024-04-19 21:43:30 +08:00
if (self.ExpectSprint.shouldBe && self.MovementInput.z > 0)
2024-02-21 01:40:53 +08:00
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Sprint>();
2024-02-21 01:40:53 +08:00
return;
}
break;
2023-08-23 01:59:40 +08:00
}
}
public override void ExecuteCommand<T>(T command)
{
if (Enabled is false) return;
if (command is PlayerCancelRunCommand)
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Walk>();
2023-08-23 01:59:40 +08:00
}
}
}
2023-10-20 19:31:12 +08:00
[Serializable]
public sealed class Slide : BasicMovement, IPlayerSlideState
{
[Header(nameof(Slide))]
[SerializeField] private float additiveSpeed = 1f;
[SerializeField] private float damping = 1;
[SerializeField] private float stopSpeed = 0.64f;
[SerializeField] private bool alwaysSlide;
private bool _addedVelocity;
public override void OnStateEntry(IState old)
{
2024-04-06 16:33:57 +08:00
base.OnStateEntry(old);
2024-04-19 21:43:30 +08:00
self.ExpectCrouch.being = true;
self.ExpectCrouch.shouldBe = true;
self.ExecuteCommand<PlayerCancelRunCommand>();
2023-10-20 19:31:12 +08:00
_addedVelocity = false;
}
public override void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime)
{
if (alwaysSlide && actor.IsGrounded is false)
{
base.UpdateVelocity(ref currentVelocity, deltaTime);
}
else
{
if (_addedVelocity is false)
{
currentVelocity += currentVelocity.normalized * additiveSpeed;
_addedVelocity = true;
}
else
{
currentVelocity = Vector3.Lerp(currentVelocity, Vector3.zero, deltaTime * damping);
}
}
}
public override void AfterUpdateMovement(float deltaTime)
{
2024-04-19 21:43:30 +08:00
if (self.ExpectRun.shouldBe)
2023-10-20 19:31:12 +08:00
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Run>();
2023-10-20 19:31:12 +08:00
return;
}
2024-04-19 21:43:30 +08:00
if (self.ExpectCrouch.shouldBe is false || (alwaysSlide is false && actor.IsGrounded is false))
2023-10-20 19:31:12 +08:00
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Walk>();
2023-10-20 19:31:12 +08:00
return;
}
if (actor.Velocity.sqrMagnitude <= stopSpeed)
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Crouch>();
2023-10-20 19:31:12 +08:00
}
2024-04-19 21:43:30 +08:00
self.CurrentCameraPosition.shouldBe = self.FpvLocalPosition;
2023-10-20 19:31:12 +08:00
}
}
2023-08-23 01:59:40 +08:00
[Serializable]
public sealed class Crouch:BasicMovement,IPlayerCrouchState
{
2024-04-06 16:33:57 +08:00
private readonly IntervalUpdate standInterval = new(0.1f);
2023-08-23 01:59:40 +08:00
public override void OnStateEntry(IState old)
{
2024-04-06 16:33:57 +08:00
base.OnStateEntry(old);
2024-04-19 21:43:30 +08:00
self.ExpectCrouch.being = true;
2024-04-06 16:33:57 +08:00
standInterval.Reset();
2023-08-23 01:59:40 +08:00
}
public override void OnStateExit(IState old, IState newState)
{
2024-04-19 21:43:30 +08:00
self.ExpectCrouch.being = false;
2023-08-23 01:59:40 +08:00
}
public override void AfterUpdateMovement(float deltaTime)
{
2023-10-20 19:31:12 +08:00
base.AfterUpdateMovement(deltaTime);
2024-04-06 16:33:57 +08:00
2024-04-19 21:43:30 +08:00
if(self.topBlocked)standInterval.Reset();
2024-04-06 16:33:57 +08:00
2024-04-19 21:43:30 +08:00
if (self.ExpectRun.shouldBe)
2023-08-23 01:59:40 +08:00
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Run>();
2023-08-23 01:59:40 +08:00
return;
}
2024-04-19 21:43:30 +08:00
if (self.ExpectCrouch.shouldBe is false)
2023-08-23 01:59:40 +08:00
{
2024-04-19 21:43:30 +08:00
if (self.topBlocked)
2024-04-06 16:33:57 +08:00
{
}
else if(standInterval.AllowUpdateWithoutReset)
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Walk>();
2024-04-06 16:33:57 +08:00
}
2023-08-23 01:59:40 +08:00
return;
}
}
}
[Serializable]
public sealed class Sprint:BasicMovement,IPlayerSprintState
{
2023-10-20 19:31:12 +08:00
[SerializeField] private int slideCost = 16;
[SerializeField] private int staminaCost = 1;
2023-08-23 01:59:40 +08:00
public override void OnStateEntry(IState old)
{
2024-04-19 21:43:30 +08:00
self.ExpectSprint.being = true;
2023-08-23 01:59:40 +08:00
}
public override void OnStateExit(IState old, IState newState)
{
2024-04-19 21:43:30 +08:00
self.ExpectSprint.being = false;
2023-08-23 01:59:40 +08:00
}
2024-04-19 00:40:34 +08:00
public override void UpdateRotation(ref Quaternion currentRotation, float deltaTime)
{
if (_cameraService.IsCameraActivated is false)
{
base.UpdateRotation(ref currentRotation, deltaTime);
return;
}
var baseRotation = Quaternion.identity;
base.UpdateRotation(ref baseRotation, deltaTime);
2024-04-19 21:43:30 +08:00
var targetRotation = Quaternion.LookRotation(baseRotation * self.MovementInput);
2024-04-19 00:40:34 +08:00
float maxAngleDelta = 30; // 你可以根据需要调整最大角度差值
float maxDeltaMagnitude = Mathf.Sin(Mathf.Deg2Rad * maxAngleDelta / 2);
targetRotation = Quaternion.RotateTowards(targetRotation,baseRotation , maxDeltaMagnitude);
var max = Quaternion.RotateTowards(targetRotation, currentRotation, maxAngleDelta);
2024-03-18 18:20:23 +08:00
2024-04-19 00:40:34 +08:00
var lerp = Quaternion.Lerp(currentRotation, targetRotation, 12 * deltaTime);
if (Quaternion.Angle(currentRotation, max) < Quaternion.Angle(currentRotation, lerp))
{
currentRotation = lerp;
}
else
{
currentRotation = max;
}
}
2023-10-20 19:31:12 +08:00
public override void OnStateUpdate(float deltaTime)
{
2024-04-19 21:43:30 +08:00
if (actor.IsGrounded && actor.Velocity.GetLength() > self.initialSpeed/2)
self.Stamina -= staminaCost * deltaTime;
AudioSensorService.MakeNoise(actor.Position,self.transform);
2023-10-20 19:31:12 +08:00
}
2023-08-23 01:59:40 +08:00
public override void AfterUpdateMovement(float deltaTime)
{
2023-10-20 19:31:12 +08:00
base.AfterUpdateMovement(deltaTime);
2024-03-29 00:58:24 +08:00
if (Enabled is false) return;
2024-04-19 21:43:30 +08:00
if (self.pauseRun.Allow)
2023-11-15 23:54:54 +08:00
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Walk>();
2023-11-15 23:54:54 +08:00
return;
}
2024-04-19 21:43:30 +08:00
switch (self.ExpectRun.shouldBe,self.ExpectCrouch.shouldBe)
2023-08-23 01:59:40 +08:00
{
2024-04-19 21:43:30 +08:00
case (_,_) when self.Stamina is 0:
self.ExpectSprint.Reset();
self.TransitionState<Run>();
2023-11-15 23:54:54 +08:00
return;
2024-04-19 21:43:30 +08:00
case (_,true) when self.IsGrounded && self.Stamina > 0:
self.Stamina -= slideCost;
self.TransitionState<Slide>();
2023-11-15 23:54:54 +08:00
return;
2023-08-23 01:59:40 +08:00
case (_,true):
2024-04-19 21:43:30 +08:00
self.TransitionState<Crouch>();
2023-11-15 23:54:54 +08:00
return;
2024-04-19 21:43:30 +08:00
case (true,false) when self.MovementInput.z <=0:
2023-08-23 01:59:40 +08:00
case (false,false):
2024-04-19 21:43:30 +08:00
self.TransitionState<Walk>();
2023-11-15 23:54:54 +08:00
return;
2023-08-23 01:59:40 +08:00
}
}
public override void ExecuteCommand<T>(T command)
{
if (Enabled is false) return;
if(command is PlayerCancelRunCommand)
2024-04-19 21:43:30 +08:00
self.TransitionState<Walk>();
2023-08-23 01:59:40 +08:00
}
}
2023-10-20 19:31:12 +08:00
[Serializable]
public sealed class Knockdown : BasicMovement, IPlayerKnockdownState
{
public override void Initialize()
{
base.Initialize();
knockdown.OnKnockdown += OnKnockdown;
knockdown.OnRevive += OnRevive;
}
2024-04-19 00:40:34 +08:00
public override void OnStateEntry(IState old)
{
base.OnStateEntry(old);
actor.UseRootMotion = true;
}
2023-10-20 19:31:12 +08:00
2024-04-19 00:40:34 +08:00
public override void OnStateExit(IState old, IState newState)
{
base.OnStateExit(old, newState);
actor.UseRootMotion = false;
}
public override void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime)
{
base.UpdateVelocity(ref currentVelocity, deltaTime);
if (knockdown.IsPressured)
{
currentVelocity.x = 0;
currentVelocity.z = 0;
}
}
2024-04-19 00:40:34 +08:00
public override void AfterUpdateMovement(float deltaTime)
{
base.AfterUpdateMovement(deltaTime);
2024-04-19 21:43:30 +08:00
self.CurrentCameraPosition.shouldBe = self.FpvLocalPosition;
2024-04-19 00:40:34 +08:00
}
2023-10-20 19:31:12 +08:00
private void OnRevive()
{
2024-04-19 21:43:30 +08:00
if(Enabled)self.TransitionState<Walk>();
2023-10-20 19:31:12 +08:00
}
private void OnKnockdown()
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Knockdown>();
2023-10-20 19:31:12 +08:00
}
}
[Serializable]
public sealed class Clip:PlayerCharacterState
{
[BITCommand]
public static void NoClip()
{
_clipAction?.Invoke();
}
private static Action _clipAction;
[SerializeField] private InputActionReference clipAction;
[SerializeReference, SubclassSelector] private IReference clipEnv;
[Inject] private IHealth _health;
[Inject] private InputActionGroup _inputActionGroup;
public override void Initialize()
{
base.Initialize();
_health.OnSetAlive += OnSetAlive;
Data.AddListener<bool>(clipEnv.Value, OnClip);
_clipAction = _ClipAction;
2024-04-19 21:43:30 +08:00
self.destroyCancellationToken.Register(() =>
{
Data.RemoveListender<bool>(clipEnv.Value, OnClip);
});
}
private void _ClipAction()
{
var clip = Data.Get<bool>(clipEnv.Value);
Data.Set(clipEnv.Value, !clip);
}
private async void OnClip(bool obj)
{
await UniTask.SwitchToMainThread();
if(_health.IsAlive is false) return;
if (obj && Enabled is false)
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Clip>();
//BIT4Log.Log<Clip>("NoClip Enabled");
}else if (Enabled && obj is false)
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Walk>();
//BIT4Log.Log<Clip>("NoClip Disabled");
}
}
private void OnSetAlive(bool obj)
{
if (Enabled && obj is false)
{
2024-04-19 21:43:30 +08:00
self.TransitionState<Walk>();
}
}
public override void OnStateEntry(IState old)
{
base.OnStateEntry(old);
actor.Velocity = default;
actor.ColliderComponent.enabled = false;
actor.alwaysNotGrounded = true;
}
public override void OnStateExit(IState old, IState newState)
{
base.OnStateExit(old, newState);
actor.ColliderComponent.enabled = true;
actor.alwaysNotGrounded = false;
}
public override void AfterUpdateMovement(float deltaTime)
{
base.AfterUpdateMovement(deltaTime);
2024-04-19 21:43:30 +08:00
actor.Position += self.ViewRotation * self.MovementInput * (
deltaTime * (_inputActionGroup.GetAction(self.RunAction).IsPressed()
? 8
2024-04-19 21:43:30 +08:00
: self.initialSpeed
));
2024-04-19 21:43:30 +08:00
actor.Rotation = Quaternion.Euler(0,self.LookInput.y,0);
}
}
2023-08-23 01:59:40 +08:00
}