using System; using NBC; using RootMotion.FinalIK; using UnityEngine; namespace NBF { public class FPlayerMainSync : MonoBehaviour { public FirstPersonController firstPersonController; [HideInInspector] public int nextShowSlotIndex = -1; private float walkingSpeed = 1f; private float runningSpeed = 2f; private FPlayer _player; private bool _isRun; public LookAtIK lookAtIK; // 挂在背部上的 LookAtIK 脚本 public float aimDistance = 1.5f; // 目标点离相机多远 private Transform lookTarget; // 实际目标点 [Header("限制角度(单位:度)")] public float maxUpAngle = 20f; // 相机抬头最多20° public float maxDownAngle = 40f; // 相机低头最多40° public LayerMask interactableLayer; private void Start() { firstPersonController = GetComponent(); walkingSpeed = firstPersonController.m_WalkSpeed; runningSpeed = firstPersonController.m_RunSpeed; _player = GetComponent(); transform.position = _player.Data.position; transform.rotation = _player.Data.rotation; Timer.Once(1f, this, EnableFirstPersonController); // App.Inst.SetMouseCurrsor(false); // InputManager.OnQuickIndexAction += OnQuickIndexAction; // InputManager.OnUseTorchAction += OnUseTorchAction; // InputManager.OnUseTelescopeAction += OnUseTelescopeAction; InputManager.OnPlayerCanceled += OnPlayerCanceled; InputManager.OnPlayerPerformed += OnPlayerPerformed; lookAtIK = GetComponent(); lookTarget = new GameObject("SpineLookTarget").transform; lookTarget.SetParent(_player.transform); interactableLayer = LayerMask.GetMask("Interactive"); } private void OnDestroy() { InputManager.OnPlayerCanceled -= OnPlayerCanceled; InputManager.OnPlayerPerformed -= OnPlayerPerformed; // InputManager.OnQuickIndexAction -= OnQuickIndexAction; // InputManager.OnUseTorchAction -= OnUseTorchAction; // InputManager.OnUseTelescopeAction -= OnUseTelescopeAction; } private void OnPlayerPerformed(string action) { if (action == "Run") { // Sprint(); _isRun = true; } } private void OnPlayerCanceled(string action) { if (action == "Run") { _isRun = false; // StopSprinting(); } else if (action.StartsWith("Quick")) { nextShowSlotIndex = int.Parse(action.Substring("Quick".Length)); } else if (action == "UseTorch") { _player.Data.openLight = !_player.Data.openLight; } else if (action == "UseTelescope") { _player.Data.openTelescope = !_player.Data.openTelescope; _player.ToggleTelescope(); } } private void EnableFirstPersonController() { firstPersonController.enabled = true; } private void Update() { var movementAxis = InputManager.GetMovementInput(); if (movementAxis != Vector2.zero) { // Debug } firstPersonController.horizontal = movementAxis.x; firstPersonController.vertical = movementAxis.y; // firstPersonController.isJumping = InputManager.IsJumping; firstPersonController.isRuning = _isRun; // firstPersonController.m_MouseLook.ControllerHandMode = GameManager.Instance._playerData // .Player[GameManager.Instance._playerData.currentPlayerProfileIndex].controllerSetup; if (firstPersonController.isWater) { firstPersonController.m_WalkSpeed = walkingSpeed - Mathf.Abs(transform.position.y - 1f); firstPersonController.m_RunSpeed = firstPersonController.m_WalkSpeed; firstPersonController.m_WalkSpeed = Mathf.Clamp(firstPersonController.m_WalkSpeed, 0.7f, 2f); firstPersonController.m_RunSpeed = Mathf.Clamp(firstPersonController.m_RunSpeed, 0.8f, 2f); } else { firstPersonController.m_WalkSpeed = walkingSpeed; firstPersonController.m_RunSpeed = runningSpeed; } if (_player.CanChangeGear()) { if (nextShowSlotIndex > 0) { Debug.LogError("切换钓组========="); var data = Fishing.Inst.Datasource; data.SetSelfTestGear(nextShowSlotIndex); nextShowSlotIndex = -1; } } UpdatePlayerHandView(); } private void FixedUpdate() { if (_player.MainArm) { // _player.MainArm.Shoulder.SetCameraEulerAngleX(BaseCamera.Main.transform.localEulerAngles.x); } } #region 肩膀控制 private void UpdatePlayerHandView() { var cameraTransform = BaseCamera.Main.transform; Vector3 cameraForward = cameraTransform.forward; Vector3 flatForward = Vector3.ProjectOnPlane(cameraForward, Vector3.up).normalized; // 获取相机 pitch 角度(负值是上看,正值是下看) float pitchAngle = Vector3.SignedAngle(flatForward, cameraForward, cameraTransform.right); // 限制 pitch 角度 pitchAngle = Mathf.Clamp(pitchAngle, -maxUpAngle, maxDownAngle); // 重新构造限制后的目标方向 Quaternion limitedPitch = Quaternion.AngleAxis(pitchAngle, cameraTransform.right); Vector3 limitedDirection = limitedPitch * flatForward; // 设置目标点 lookTarget.position = cameraTransform.position + limitedDirection * aimDistance; lookAtIK.solver.target = lookTarget; } #endregion } }