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 { protected override void Awake(PlayerInput self) { self.Player = self.GetParent(); self.View = self.Player.GetComponent(); self.AddInputEvent(); } } public class PlayerViewUpdateSystem : UpdateSystem { protected override void Update(PlayerInput self) { self.UpdateMove(); } } public class PlayerViewDestroySystem : DestroySystem { 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(); 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 } }