BITKit/Packages/Runtime~/Unity/Scripts/Entity/Components/EntityMovement/EntityMovement.cs

181 lines
5.4 KiB
C#

using System;
using System.Collections.Generic;
using BITKit.StateMachine;
using UnityEngine;
using UnityEngine.InputSystem;
namespace BITKit.Entities
{
/// <summary>
/// 期望状态与当前状态
/// </summary>
/// <typeparam name="T"></typeparam>
[Serializable]
public struct ExpectState<T>
{
/// <summary>
/// 期望状态
/// </summary>
public T shouldBe;
/// <summary>
/// 当前状态
/// </summary>
public T being;
/// <summary>
/// 强制状态
/// </summary>
public T force;
public bool UnExpect => !shouldBe.Equals(being);
public void Reset()
{
shouldBe = being = force = default;
}
public void Release()
{
being = shouldBe;
}
public void Release(T value)
{
force = default;
being = shouldBe = value;
}
public static implicit operator ExpectState<T>(T value)
{
return new ExpectState<T> { shouldBe = value, being = value };
}
public static implicit operator T(ExpectState<T> value)
{
return value.being;
}
}
/// <summary>
/// Entity移动组件接口定义
/// </summary>
public interface IEntityMovement:IStateMachine<IEntityMovementState>
{
/// <summary>
/// 世界空间的速度
/// </summary>
Vector3 Velocity { get; }
/// <summary>
/// 在地面的速度 = with <see cref="Velocity"/> {y=0}
/// </summary>
Vector3 GroundVelocity { get; }
/// <summary>
/// 是否在地面上
/// </summary>
bool IsGrounded { get; }
/// <summary>
/// 同步移动,用于网络或强制同步移动信息
/// </summary>
/// <param name="velocity"></param>
/// <param name="position"></param>
/// <param name="rotation"></param>
/// <param name="isGrounded"></param>
void SyncMovement(Vector3 velocity, Vector3 position,Quaternion rotation,bool isGrounded);
/// <summary>
/// 基于相对坐标的移动
/// </summary>
/// <param name="relativeVector"></param>
void Movement(Vector3 relativeVector);
/// <summary>
/// 基于InputAction的移动
/// </summary>
/// <param name="context"></param>
void Movement(InputAction.CallbackContext context);
void ExecuteCommand<T>(T command=default);
}
public interface IEntityMovementState:IState
{
void UpdateVelocity(ref Vector3 currentVelocity,float deltaTime);
void UpdateRotation(ref Quaternion currentRotation,float deltaTime);
void BeforeUpdateMovement(float deltaTime);
void AfterUpdateMovement(float deltaTime);
void ExecuteCommand<T>(T command);
}
public interface IPlayerMovementCommand{}
[Serializable]
public class MonoMovementProxy:IEntityMovement
{
[SerializeField] private MonoBehaviour monoBehaviour;
private IEntityMovement _entityMovementImplementation=>monoBehaviour as IEntityMovement;
public Vector3 Velocity => _entityMovementImplementation.Velocity;
public Vector3 GroundVelocity => _entityMovementImplementation.GroundVelocity;
public bool IsGrounded => _entityMovementImplementation.IsGrounded;
public void SyncMovement(Vector3 velocity, Vector3 position, Quaternion rotation, bool isGrounded)
{
_entityMovementImplementation.SyncMovement(velocity, position, rotation, isGrounded);
}
public void Movement(Vector3 relativeVector)
{
_entityMovementImplementation.Movement(relativeVector);
}
public void Movement(InputAction.CallbackContext context)
{
_entityMovementImplementation.Movement(context);
}
public void ExecuteCommand<T>(T command)=>_entityMovementImplementation.ExecuteCommand(command);
public bool Enabled
{
get => _entityMovementImplementation.Enabled;
set => _entityMovementImplementation.Enabled = value;
}
public IEntityMovementState CurrentState
{
get => _entityMovementImplementation.CurrentState;
set => _entityMovementImplementation.CurrentState = value;
}
public event Action<IEntityMovementState, IEntityMovementState> OnStateChanged
{
add => _entityMovementImplementation.OnStateChanged += value;
remove => _entityMovementImplementation.OnStateChanged -= value;
}
public IDictionary<Type, IEntityMovementState> StateDictionary => _entityMovementImplementation.StateDictionary;
public void Initialize()
{
_entityMovementImplementation.Initialize();
}
public void UpdateState()
{
_entityMovementImplementation.UpdateState();
}
public void DisposeState()
{
_entityMovementImplementation.DisposeState();
}
public void TransitionState<State>() where State : IEntityMovementState
{
_entityMovementImplementation.TransitionState<State>();
}
public void TransitionState(IEntityMovementState state)
{
_entityMovementImplementation.TransitionState(state);
}
}
}