200 lines
6.1 KiB
C#
200 lines
6.1 KiB
C#
using Fantasy;
|
||
using Fantasy.Entitas;
|
||
using Fantasy.Entitas.Interface;
|
||
using UnityEngine;
|
||
using UnityEngine.InputSystem;
|
||
using Log = NBC.Log;
|
||
|
||
namespace NBF
|
||
{
|
||
public class PlayerInput : Entity
|
||
{
|
||
public Player Player { get; private set; }
|
||
public PlayerView View { get; private set; }
|
||
|
||
#region 生命周期
|
||
|
||
public class PlayerViewAwakeSystem : AwakeSystem<PlayerInput>
|
||
{
|
||
protected override void Awake(PlayerInput self)
|
||
{
|
||
self.Player = self.GetParent<Player>();
|
||
self.View = self.Player.GetComponent<PlayerView>();
|
||
self.AddInputEvent();
|
||
}
|
||
}
|
||
|
||
public class PlayerViewUpdateSystem : UpdateSystem<PlayerInput>
|
||
{
|
||
protected override void Update(PlayerInput self)
|
||
{
|
||
self.UpdateMove();
|
||
}
|
||
}
|
||
|
||
public class PlayerViewDestroySystem : DestroySystem<PlayerInput>
|
||
{
|
||
protected override void Destroy(PlayerInput self)
|
||
{
|
||
self.RemoveInputEvent();
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Input
|
||
|
||
private void AddInputEvent()
|
||
{
|
||
InputManager.OnPlayerPerformed += OnPlayerCanceled;
|
||
InputManager.OnPlayerPerformed += OnPlayerPerformed;
|
||
|
||
InputManager.OnPlayerValueCanceled += OnPlayerValueCanceled;
|
||
InputManager.OnPlayerValuePerformed += OnPlayerValuePerformed;
|
||
}
|
||
|
||
private void RemoveInputEvent()
|
||
{
|
||
InputManager.OnPlayerPerformed += OnPlayerCanceled;
|
||
InputManager.OnPlayerPerformed += OnPlayerPerformed;
|
||
|
||
InputManager.OnPlayerValueCanceled += OnPlayerValueCanceled;
|
||
InputManager.OnPlayerValuePerformed += OnPlayerValuePerformed;
|
||
}
|
||
|
||
private void OnPlayerPerformed(string action)
|
||
{
|
||
if (action == InputDef.Player.Run)
|
||
{
|
||
Player.Run = true;
|
||
}
|
||
}
|
||
|
||
private void OnPlayerCanceled(string action)
|
||
{
|
||
if (action == InputDef.Player.Run)
|
||
{
|
||
Player.Run = false;
|
||
}
|
||
else if (action == InputDef.Player.ToBag)
|
||
{
|
||
//取消手持物品
|
||
Log.Info($"取消手持物品");
|
||
Player.UnUseItem();
|
||
// Game.Instance.StartCoroutine(UnUseItem());
|
||
}
|
||
else if (action.StartsWith(InputDef.Player.QuickStarts))
|
||
{
|
||
var index = int.Parse(action.Replace(InputDef.Player.QuickStarts, string.Empty));
|
||
Log.Info($"快速使用===={index}");
|
||
var item = RoleModel.Instance.GetSlotItem(index - 1);
|
||
if (item != null)
|
||
{
|
||
Player.UseItem(item);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void OnPlayerValueCanceled(InputAction.CallbackContext context)
|
||
{
|
||
var actionName = context.action.name;
|
||
if (actionName == InputDef.Player.Move)
|
||
{
|
||
Player.MoveInput = Vector2.zero;
|
||
}
|
||
}
|
||
|
||
private void OnPlayerValuePerformed(InputAction.CallbackContext context)
|
||
{
|
||
var actionName = context.action.name;
|
||
if (actionName == InputDef.Player.Move)
|
||
{
|
||
var v2 = context.ReadValue<Vector2>();
|
||
Player.MoveInput = v2;
|
||
}
|
||
else if (actionName == InputDef.Player.Look)
|
||
{
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Move
|
||
|
||
private Quaternion _lastRotation;
|
||
|
||
private void UpdateMove()
|
||
{
|
||
UpdateGrounded();
|
||
ProcessMoveStates();
|
||
UpdateLookInput();
|
||
}
|
||
|
||
private void ProcessMoveStates()
|
||
{
|
||
{
|
||
var num2 = Player.Run ? 7 : 5;
|
||
Vector3 vector2 = View.Unity.FirstPerson.GetRightVector() * Player.MoveInput.x * num2;
|
||
vector2 += View.Unity.FirstPerson.GetForwardVector() * Player.MoveInput.y * num2;
|
||
// if (checkWaterBound)
|
||
// {
|
||
// SetMovementDirectionWithRaycastCheck(vector2);
|
||
// }
|
||
// else
|
||
{
|
||
View.Unity.FirstPerson.SetMovementDirection(vector2);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void UpdateGrounded()
|
||
{
|
||
Player.IsGrounded = View.Unity.FirstPerson.IsGrounded();
|
||
Player.Speed = View.Unity.FirstPerson.velocity.magnitude;
|
||
|
||
Quaternion rotation = View.Unity.FirstPerson.transform.rotation;
|
||
|
||
// 计算当前帧与上一帧的旋转差异
|
||
Quaternion rotationDelta = rotation * Quaternion.Inverse(_lastRotation);
|
||
|
||
// 将四元数转换为角度轴表示
|
||
rotationDelta.ToAngleAxis(out float angle, out Vector3 axis);
|
||
|
||
// 确保角度在0-360范围内
|
||
if (angle > 180f) angle -= 360f;
|
||
|
||
// 获取Y轴旋转分量(归一化处理)
|
||
float yRotation = 0f;
|
||
if (Mathf.Abs(angle) > 0.001f && Mathf.Abs(axis.y) > 0.1f)
|
||
{
|
||
// 计算Y轴方向的旋转角度(考虑旋转轴方向)
|
||
yRotation = angle * Mathf.Sign(axis.y);
|
||
}
|
||
|
||
float maxTurnSpeed = 180f; // 度/秒
|
||
// 转换为角速度并归一化到[-1, 1]
|
||
float angularSpeed = yRotation / Time.deltaTime;
|
||
float turnValue = Mathf.Clamp(angularSpeed / maxTurnSpeed, -1f, 1f);
|
||
|
||
|
||
Player.RotationSpeed = turnValue;
|
||
|
||
_lastRotation = rotation;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Look
|
||
|
||
private void UpdateLookInput()
|
||
{
|
||
Vector2 value = InputManager.GetLookInput();
|
||
var u3d = View.Unity;
|
||
u3d.FirstPerson.AddControlYawInput(value.x * u3d.MouseSensitivity);
|
||
u3d.FirstPerson.AddControlPitchInput((u3d.invertLook ? 0f - value.y : value.y) * u3d.MouseSensitivity,
|
||
u3d.minPitch, u3d.maxPitch);
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
} |