角色控制
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@ namespace EasyPeasyFirstPersonController
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
public partial class FirstPersonController : MonoBehaviour
|
||||
public class FirstPersonController : MonoBehaviour
|
||||
{
|
||||
[Range(0, 100)] public float mouseSensitivity = 25f;
|
||||
[Range(0f, 200f)] private float snappiness = 100f;
|
||||
@@ -55,7 +55,6 @@ namespace EasyPeasyFirstPersonController
|
||||
private Camera cam;
|
||||
private AudioSource slideAudioSource;
|
||||
private float bobTimer;
|
||||
private float defaultPosY;
|
||||
private Vector3 recoil = Vector3.zero;
|
||||
private bool isLook = true, isMove = true;
|
||||
private float currentCameraHeight;
|
||||
@@ -67,15 +66,13 @@ namespace EasyPeasyFirstPersonController
|
||||
private float currentTiltAngle;
|
||||
private float tiltVelocity;
|
||||
|
||||
public float CurrentCameraHeight => isCrouching || isSliding ? crouchCameraHeight : originalCameraParentHeight;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
characterController = GetComponent<CharacterController>();
|
||||
cam = playerCamera.GetComponent<Camera>();
|
||||
originalHeight = characterController.height;
|
||||
originalCameraParentHeight = cameraParent.localPosition.y;
|
||||
defaultPosY = cameraParent.localPosition.y;
|
||||
// defaultPosY = cameraParent.localPosition.y;
|
||||
slideAudioSource = gameObject.AddComponent<AudioSource>();
|
||||
slideAudioSource.playOnAwake = false;
|
||||
slideAudioSource.loop = false;
|
||||
@@ -118,10 +115,11 @@ namespace EasyPeasyFirstPersonController
|
||||
transform.rotation = Quaternion.Euler(0f, xVelocity, 0f);
|
||||
}
|
||||
|
||||
HandleHeadBob();
|
||||
// HandleHeadBob();
|
||||
|
||||
bool wantsToCrouch = canCrouch && Input.GetKey(KeyCode.LeftControl) && !isSliding;
|
||||
Vector3 point1 = transform.position + characterController.center - Vector3.up * (characterController.height * 0.5f);
|
||||
Vector3 point1 = transform.position + characterController.center -
|
||||
Vector3.up * (characterController.height * 0.5f);
|
||||
Vector3 point2 = point1 + Vector3.up * characterController.height * 0.6f;
|
||||
float capsuleRadius = characterController.radius * 0.95f;
|
||||
float castDistance = isSliding ? originalHeight + 0.2f : originalHeight - crouchHeight + 0.2f;
|
||||
@@ -130,6 +128,7 @@ namespace EasyPeasyFirstPersonController
|
||||
{
|
||||
postSlideCrouchTimer = 0.3f;
|
||||
}
|
||||
|
||||
if (postSlideCrouchTimer > 0)
|
||||
{
|
||||
postSlideCrouchTimer -= Time.deltaTime;
|
||||
@@ -144,7 +143,9 @@ namespace EasyPeasyFirstPersonController
|
||||
{
|
||||
isSliding = true;
|
||||
slideTimer = slideDuration;
|
||||
slideDirection = moveInput.magnitude > 0.1f ? (transform.right * moveInput.x + transform.forward * moveInput.y).normalized : transform.forward;
|
||||
slideDirection = moveInput.magnitude > 0.1f
|
||||
? (transform.right * moveInput.x + transform.forward * moveInput.y).normalized
|
||||
: transform.forward;
|
||||
currentSlideSpeed = sprintSpeed;
|
||||
}
|
||||
|
||||
@@ -156,6 +157,7 @@ namespace EasyPeasyFirstPersonController
|
||||
{
|
||||
isSliding = false;
|
||||
}
|
||||
|
||||
float targetSlideSpeed = slideSpeed * Mathf.Lerp(0.7f, 1f, slideProgress);
|
||||
currentSlideSpeed = Mathf.SmoothDamp(currentSlideSpeed, targetSlideSpeed, ref slideSpeedVelocity, 0.2f);
|
||||
characterController.Move(slideDirection * currentSlideSpeed * Time.deltaTime);
|
||||
@@ -165,7 +167,9 @@ namespace EasyPeasyFirstPersonController
|
||||
characterController.height = Mathf.Lerp(characterController.height, targetHeight, Time.deltaTime * 10f);
|
||||
characterController.center = new Vector3(0f, characterController.height * 0.5f, 0f);
|
||||
|
||||
float targetFov = isSprinting ? sprintFov : (isSliding ? sprintFov + (slideFovBoost * Mathf.Lerp(0f, 1f, 1f - slideProgress)) : normalFov);
|
||||
float targetFov = isSprinting
|
||||
? sprintFov
|
||||
: (isSliding ? sprintFov + (slideFovBoost * Mathf.Lerp(0f, 1f, 1f - slideProgress)) : normalFov);
|
||||
currentFov = Mathf.SmoothDamp(currentFov, targetFov, ref fovVelocity, 1f / fovChangeSpeed);
|
||||
cam.fieldOfView = currentFov;
|
||||
|
||||
@@ -174,7 +178,8 @@ namespace EasyPeasyFirstPersonController
|
||||
|
||||
private void HandleHeadBob()
|
||||
{
|
||||
Vector3 horizontalVelocity = new Vector3(characterController.velocity.x, 0f, characterController.velocity.z);
|
||||
Vector3 horizontalVelocity =
|
||||
new Vector3(characterController.velocity.x, 0f, characterController.velocity.z);
|
||||
bool isMovingEnough = horizontalVelocity.magnitude > 0.1f;
|
||||
|
||||
float targetBobOffset = isMovingEnough ? Mathf.Sin(bobTimer) * bobbingAmount : 0f;
|
||||
@@ -190,7 +195,8 @@ namespace EasyPeasyFirstPersonController
|
||||
currentCameraHeight + currentBobOffset,
|
||||
cameraParent.localPosition.z);
|
||||
recoil = Vector3.zero;
|
||||
cameraParent.localRotation = Quaternion.RotateTowards(cameraParent.localRotation, Quaternion.Euler(recoil), recoilReturnSpeed * Time.deltaTime);
|
||||
cameraParent.localRotation = Quaternion.RotateTowards(cameraParent.localRotation,
|
||||
Quaternion.Euler(recoil), recoilReturnSpeed * Time.deltaTime);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -218,14 +224,16 @@ namespace EasyPeasyFirstPersonController
|
||||
recoil = Vector3.zero;
|
||||
}
|
||||
|
||||
cameraParent.localRotation = Quaternion.RotateTowards(cameraParent.localRotation, Quaternion.Euler(recoil), recoilReturnSpeed * Time.deltaTime);
|
||||
cameraParent.localRotation = Quaternion.RotateTowards(cameraParent.localRotation, Quaternion.Euler(recoil),
|
||||
recoilReturnSpeed * Time.deltaTime);
|
||||
}
|
||||
|
||||
private void HandleMovement()
|
||||
{
|
||||
moveInput.x = Input.GetAxis("Horizontal");
|
||||
moveInput.y = Input.GetAxis("Vertical");
|
||||
isSprinting = canSprint && Input.GetKey(KeyCode.LeftShift) && moveInput.y > 0.1f && isGrounded && !isCrouching && !isSliding;
|
||||
isSprinting = canSprint && Input.GetKey(KeyCode.LeftShift) && moveInput.y > 0.1f && isGrounded &&
|
||||
!isCrouching && !isSliding;
|
||||
|
||||
float currentSpeed = isCrouching ? crouchSpeed : (isSprinting ? sprintSpeed : walkSpeed);
|
||||
if (!isMove) currentSpeed = 0f;
|
||||
@@ -256,27 +264,5 @@ namespace EasyPeasyFirstPersonController
|
||||
characterController.Move(moveDirection * Time.deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetControl(bool newState)
|
||||
{
|
||||
SetLookControl(newState);
|
||||
SetMoveControl(newState);
|
||||
}
|
||||
|
||||
public void SetLookControl(bool newState)
|
||||
{
|
||||
isLook = newState;
|
||||
}
|
||||
|
||||
public void SetMoveControl(bool newState)
|
||||
{
|
||||
isMove = newState;
|
||||
}
|
||||
|
||||
public void SetCursorVisibility(bool newVisibility)
|
||||
{
|
||||
Cursor.lockState = newVisibility ? CursorLockMode.None : CursorLockMode.Locked;
|
||||
Cursor.visible = newVisibility;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4635,7 +4635,7 @@ MonoBehaviour:
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5559475303044247694}
|
||||
m_Enabled: 0
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 776adaaacdc5c4e8ab0395120a6e972b, type: 3}
|
||||
m_Name:
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using NBC;
|
||||
using System;
|
||||
using NBC;
|
||||
using RootMotion.FinalIK;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
@@ -16,9 +18,20 @@ namespace NBF
|
||||
|
||||
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<FirstPersonController>();
|
||||
@@ -41,6 +54,11 @@ namespace NBF
|
||||
|
||||
InputManager.OnPlayerCanceled += OnPlayerCanceled;
|
||||
InputManager.OnPlayerPerformed += OnPlayerPerformed;
|
||||
|
||||
lookAtIK = GetComponent<LookAtIK>();
|
||||
lookTarget = new GameObject("SpineLookTarget").transform;
|
||||
lookTarget.SetParent(_player.transform);
|
||||
interactableLayer = LayerMask.GetMask("Interactive");
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
@@ -87,7 +105,7 @@ namespace NBF
|
||||
{
|
||||
firstPersonController.enabled = true;
|
||||
}
|
||||
|
||||
|
||||
private void Update()
|
||||
{
|
||||
var movementAxis = InputManager.GetMovementInput();
|
||||
@@ -130,8 +148,11 @@ namespace NBF
|
||||
nextShowSlotIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
UpdatePlayerHandView();
|
||||
}
|
||||
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (_player.MainArm)
|
||||
@@ -139,5 +160,31 @@ namespace NBF
|
||||
// _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
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -30,10 +30,10 @@ EditorUserSettings:
|
||||
value: 550007565c005e0858575d23497a5c441516417d7a7171347c794931b6b1313c
|
||||
flags: 0
|
||||
RecentlyUsedSceneGuid-7:
|
||||
value: 500606050702510d0e570876137a09441516197b782925632e2a4d64b3b16169
|
||||
value: 515250075c0c595e5f5a5e71122159444e4e4a2f7a7d7f602f284d66b4b76661
|
||||
flags: 0
|
||||
RecentlyUsedSceneGuid-8:
|
||||
value: 515250075c0c595e5f5a5e71122159444e4e4a2f7a7d7f602f284d66b4b76661
|
||||
value: 500606050702510d0e570876137a09441516197b782925632e2a4d64b3b16169
|
||||
flags: 0
|
||||
RecentlyUsedSceneGuid-9:
|
||||
value: 5505015f5c515a085f5b092149760f441716407a787d7564287b1b36e7e1366e
|
||||
|
||||
Reference in New Issue
Block a user