using ECM2; using ECM2.Examples.FirstPerson; using Fantasy.Entitas; using Fantasy.Entitas.Interface; using UnityEngine; using UnityEngine.InputSystem; namespace NBF.Fishing2 { public class CharacterMovementComponent : Entity { public bool IsSelf; public bool Run; private Vector2 _moveInput; public MapUnit MapUnit; private FirstPersonCharacter _Character; private Quaternion lastRotation; #region System public class MovementComponentDestroySystem : DestroySystem { protected override void Destroy(CharacterMovementComponent self) { // self.characterController = null; self.IsSelf = false; self.Run = false; var mapUnit = self.Parent as MapUnit; if (mapUnit.IsSelf()) { var inputComponent = self.Scene.GetComponent(); if (inputComponent != null) { inputComponent.OnPlayerPerformed -= self.OnPlayerCanceled; inputComponent.OnPlayerPerformed -= self.OnPlayerPerformed; inputComponent.OnPlayerValueCanceled -= self.OnPlayerValueCanceled; inputComponent.OnPlayerValuePerformed -= self.OnPlayerValuePerformed; } } // self.PlayerAsset = null; } } public class MovementComponentAwakeSystem : AwakeSystem { protected override void Awake(CharacterMovementComponent self) { var unitUnityComponent = self.Parent.GetComponent(); self._Character = unitUnityComponent.FirstPerson; var mapUnit = self.Parent as MapUnit; self.MapUnit = mapUnit; if (mapUnit.IsSelf()) { self.IsSelf = true; var inputComponent = self.Scene.GetComponent(); inputComponent.OnPlayerPerformed += self.OnPlayerCanceled; inputComponent.OnPlayerPerformed += self.OnPlayerPerformed; inputComponent.OnPlayerValueCanceled += self.OnPlayerValueCanceled; inputComponent.OnPlayerValuePerformed += self.OnPlayerValuePerformed; } } } public class MovementComponentUpdateSystem : UpdateSystem { protected override void Update(CharacterMovementComponent self) { self.UpdateGrounded(); self.UpdateWater(); self.ProcessMoveStates(); } } #endregion #region Input private void OnPlayerPerformed(string action) { if (action == InputDef.Player.Run) { Run = true; } } private void OnPlayerCanceled(string action) { if (action == InputDef.Player.Run) { Run = false; } } private void OnPlayerValueCanceled(InputAction.CallbackContext context) { var name = context.action.name; if (name == InputDef.Player.Move) { // var v2 = context.ReadValue(); _moveInput = Vector2.zero; // SendMoveMessage(v2, true); } } private void OnPlayerValuePerformed(InputAction.CallbackContext context) { // var mapUnit = Parent as MapUnit; // Log.Info($"OnPlayerValuePerformed IsSelf={mapUnit.IsSelf()} id={mapUnit.Id}"); var name = context.action.name; if (name == InputDef.Player.Move) { var v2 = context.ReadValue(); _moveInput = v2; // SendMoveMessage(v2, false); } else if (name == InputDef.Player.Look) { var v2 = context.ReadValue(); // UpdatePlayerRotation(v2); } } #endregion #region Move private void UpdateGrounded() { MapUnit.IsGrounded = _Character.IsGrounded(); MapUnit.Speed = _Character.velocity.magnitude; Quaternion rotation = _Character.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); MapUnit.RotationSpeed = turnValue; lastRotation = rotation; } private void UpdateWater() { // SceneSettings.Instance.Water.w } private void ProcessMoveStates() { // if (CameraView.Value == CameraViewType.TPP) // { // float num = (IsRunPressed.Value ? MovementSpeed.Value : (MovementSpeed.Value * 0.5f)); // num = (IsFlyModeEnabled ? (num * (float)FlySpeed) : num); // Vector3 zero = Vector3.zero; // zero += Vector3.right * MovementDirection.Value.x; // zero += Vector3.forward * MovementDirection.Value.y; // zero = zero.relativeTo(_CameraTPPTarget, _Character.GetUpVector()); // _Character.RotateTowards(zero, Time.deltaTime * _RotateTPPSpeed); // float value = Vector3.Dot(_Character.GetForwardVector(), zero); // Vector3 vector = _Character.GetForwardVector() * Mathf.Clamp01(value) * num; // if (checkWaterBound) // { // SetMovementDirectionWithRaycastCheck(vector); // } // else // { // _Character.SetMovementDirection(vector); // } // } // else { float num2 = Run ? 7 : 5; //(IsRunPressed.Value ? MovementSpeed.Value : (MovementSpeed.Value * 0.5f)); // num2 = (IsFlyModeEnabled ? (num2 * (float)FlySpeed) : num2); Vector3 vector2 = _Character.GetRightVector() * _moveInput.x * num2; vector2 += _Character.GetForwardVector() * _moveInput.y * num2; // if (checkWaterBound) // { // SetMovementDirectionWithRaycastCheck(vector2); // } // else { _Character.SetMovementDirection(vector2); } } } #endregion } }