aboutsummaryrefslogtreecommitdiff
path: root/Assets/Scripts
diff options
context:
space:
mode:
authorSmallFox <2806143047@qq.com>2026-05-31 17:42:01 +0800
committerSmallFox <2806143047@qq.com>2026-05-31 17:42:01 +0800
commitff1e4698f877ead17ee723ff465f26fad58cd0a0 (patch)
tree14a97ffbf7e360c8676ba81037d582b9c0aaaec6 /Assets/Scripts
parentdca6ed8a79a1b4df00720a02f5ae96b2ec9e7283 (diff)
合并最新分支,重构Roll,增加了Step_Back,有点手感问题后面调
Diffstat (limited to 'Assets/Scripts')
-rw-r--r--Assets/Scripts/AnimatorHandler.cs31
-rw-r--r--Assets/Scripts/CameraHandler.cs16
-rw-r--r--Assets/Scripts/InputHandler.cs18
-rw-r--r--Assets/Scripts/InputSystem/PlayerControls.cs100
-rw-r--r--Assets/Scripts/InputSystem/PlayerControls.inputactions39
-rw-r--r--Assets/Scripts/PlayerLocomotion.cs112
-rw-r--r--Assets/Scripts/PlayerManager.cs17
-rw-r--r--Assets/Scripts/ResetIsInteracting.cs15
-rw-r--r--Assets/Scripts/ResetIsInteracting.cs.meta11
9 files changed, 277 insertions, 82 deletions
diff --git a/Assets/Scripts/AnimatorHandler.cs b/Assets/Scripts/AnimatorHandler.cs
index 16f0f67..775ffc4 100644
--- a/Assets/Scripts/AnimatorHandler.cs
+++ b/Assets/Scripts/AnimatorHandler.cs
@@ -13,11 +13,12 @@ namespace DS
{
[Header("绑定")]
public Transform rootMotionRotation; // 将模型旋转绑定到 RootMotion
- public InputHandler inputHandler;
-
+
+
[Header("组件引用")]
public PlayerLocomotion playerLocomotion; // 玩家移动控制器引用,用于传递根运动数据
public Animator animator; // 动画器组件引用
+ public InputHandler inputHandler;
[Header("动画参数哈希")]
private int _vertical; // "Vertical" 动画参数的哈希值,用于高效设置动画参数
@@ -26,6 +27,8 @@ namespace DS
[Header("旋转状态")]
public bool canRotate; // 是否允许角色旋转,在动画事件中控制
+
+
/// <summary>
/// 初始化函数 - 获取 Animator 组件并计算动画参数的哈希值。
@@ -35,6 +38,8 @@ namespace DS
{
// 获取当前 GameObject 上的 Animator 组件
animator = GetComponent<Animator>();
+ inputHandler = GetComponentInParent<InputHandler>();
+ playerLocomotion = GetComponentInParent<PlayerLocomotion>();
// 使用 Animator.StringToHash 将字符串参数名转换为整数哈希值
// 这样在 SetFloat 时使用哈希值比使用字符串更高效
@@ -117,6 +122,14 @@ namespace DS
animator.SetFloat(_horizontal, h, 0.1f, Time.deltaTime);
}
+ public void PlayerTargetAnimation(string targetAnim, bool isInteractions)
+ {
+ Debug.Log($"尝试播放动画: {targetAnim}");
+ animator.applyRootMotion = isInteractions;
+ animator.SetBool("isInteracting",isInteractions);
+ animator.CrossFade(targetAnim,0.2f);
+ }
+
/// <summary>
/// 触发动画的翻滚
/// </summary>
@@ -157,6 +170,20 @@ namespace DS
// 将根运动数据传递给 PlayerLocomotion 组件
// PlayerLocomotion 会将这些位移应用到角色控制器上
playerLocomotion.rootMotion = rootMotion;
+
+ if (inputHandler.isInteracting == false)
+ {
+ return;
+ }
+
+ //更改刚体速度方案
+ // float delta = Time.deltaTime;
+ // playerLocomotion.rigidbody.drag = 0;
+ // Vector3 deltaPosition = animator.deltaPosition;
+ // deltaPosition.y = 0;
+ // Vector3 velocity = deltaPosition / delta;
+ // playerLocomotion.rigidbody.velocity = velocity;
+
}
/// <summary>
diff --git a/Assets/Scripts/CameraHandler.cs b/Assets/Scripts/CameraHandler.cs
index a1cd569..0e4a5e9 100644
--- a/Assets/Scripts/CameraHandler.cs
+++ b/Assets/Scripts/CameraHandler.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Mathematics;
+using UnityEditor;
using UnityEngine;
namespace DS
@@ -154,7 +155,6 @@ namespace DS
// 计算从枢轴指向摄像机的方向向量
Vector3 direction = cameraTransform.position - cameraPivotTransform.position;
direction.Normalize();
-
// 从枢轴位置沿 direction 方向进行 SphereCast 检测
// 检测距离为 _targetPosition 的绝对值
if (Physics.SphereCast(
@@ -167,10 +167,19 @@ namespace DS
{
// 计算枢轴到碰撞点的实际距离
float dis = Vector3.Distance(cameraPivotTransform.position, hit.point);
- // 摄像机应位于碰撞点前方 cameraCollisionOffSet 处
- _targetPosition = -(dis - cameraCollisionOffSet);
+
+ float newPos = -(dis - cameraCollisionOffSet);
+ _targetPosition = Mathf.Clamp(newPos, _defaultPosition, -minimumCollisionOffSet);
+
+ // // 摄像机应位于碰撞点前方 cameraCollisionOffSet 处
+ // _targetPosition = -(dis - cameraCollisionOffSet);
+ } else
+ {
+ // 无碰撞时,确保相机回到默认位置,但也要限制一下,防止超出
+ _targetPosition = Mathf.Clamp(_defaultPosition, _defaultPosition, -minimumCollisionOffSet);
}
+
// 如果计算出的目标距离绝对值太小,强制使用最小值防止视觉异常
if (Mathf.Abs(_targetPosition) < minimumCollisionOffSet)
{
@@ -186,5 +195,6 @@ namespace DS
// 应用位置
cameraTransform.localPosition = _cameraTransformPosition;
}
+
}
}
diff --git a/Assets/Scripts/InputHandler.cs b/Assets/Scripts/InputHandler.cs
index 9d2ab72..e1c70d0 100644
--- a/Assets/Scripts/InputHandler.cs
+++ b/Assets/Scripts/InputHandler.cs
@@ -28,6 +28,10 @@ namespace DS
[Tooltip("鼠标或右摇杆的垂直移动增量")]
public float mouseY;
+ public bool b_Input;
+ public bool rollFlag;
+ public bool isInteracting;
+
[Header("其他操作输入")]
[Tooltip("翻滚是否触发")]
public bool rollTriggered;
@@ -81,9 +85,6 @@ namespace DS
_inputActions.PlayerMovement.Camera.performed +=
ctx => _cameraInput = ctx.ReadValue<Vector2>();
- // 增加翻滚行为
- _inputActions.PlayerMovement.Roll.performed +=
- ctx => rollTriggered = ctx.ReadValueAsButton();
}
// 启用输入动作监听
@@ -107,6 +108,7 @@ namespace DS
public void TickInput(float delta)
{
MoveInput(delta);
+ HandleRollInput(delta);
}
// ===== 私有输入处理逻辑 =====
@@ -128,5 +130,15 @@ namespace DS
mouseX = _cameraInput.x;
mouseY = _cameraInput.y;
}
+
+ private void HandleRollInput(float delta)
+ {
+ b_Input = _inputActions.PlayerActions.Roll.phase == UnityEngine.InputSystem.InputActionPhase.Performed;
+ Debug.Log(b_Input);
+ if (b_Input)
+ {
+ rollFlag = true;
+ }
+ }
}
}
diff --git a/Assets/Scripts/InputSystem/PlayerControls.cs b/Assets/Scripts/InputSystem/PlayerControls.cs
index c77acf2..128521d 100644
--- a/Assets/Scripts/InputSystem/PlayerControls.cs
+++ b/Assets/Scripts/InputSystem/PlayerControls.cs
@@ -44,15 +44,6 @@ public partial class @PlayerControls: IInputActionCollection2, IDisposable
""processors"": """",
""interactions"": """",
""initialStateCheck"": true
- },
- {
- ""name"": ""Roll"",
- ""type"": ""Button"",
- ""id"": ""5e423815-95ec-43c1-9718-224f86c8f24e"",
- ""expectedControlType"": ""Button"",
- ""processors"": """",
- ""interactions"": """",
- ""initialStateCheck"": false
}
],
""bindings"": [
@@ -132,10 +123,38 @@ public partial class @PlayerControls: IInputActionCollection2, IDisposable
""action"": ""Camera"",
""isComposite"": false,
""isPartOfComposite"": false
+ }
+ ]
+ },
+ {
+ ""name"": ""Player Actions"",
+ ""id"": ""e698248c-d44d-4c32-9308-df1fb8952042"",
+ ""actions"": [
+ {
+ ""name"": ""Roll"",
+ ""type"": ""Button"",
+ ""id"": ""b5381d00-a598-472a-96b6-e7a5ed618a96"",
+ ""expectedControlType"": ""Button"",
+ ""processors"": """",
+ ""interactions"": """",
+ ""initialStateCheck"": false
+ }
+ ],
+ ""bindings"": [
+ {
+ ""name"": """",
+ ""id"": ""8af511c9-0a47-4f49-b1e0-a98500b70c9d"",
+ ""path"": ""<Gamepad>/buttonEast"",
+ ""interactions"": """",
+ ""processors"": """",
+ ""groups"": """",
+ ""action"": ""Roll"",
+ ""isComposite"": false,
+ ""isPartOfComposite"": false
},
{
""name"": """",
- ""id"": ""4690e573-c6d7-4c20-bbee-ba5d11ca8a18"",
+ ""id"": ""a76c6730-3d6e-4609-a3fb-450fe20ef6e2"",
""path"": ""<Keyboard>/space"",
""interactions"": """",
""processors"": """",
@@ -153,7 +172,9 @@ public partial class @PlayerControls: IInputActionCollection2, IDisposable
m_PlayerMovement = asset.FindActionMap("Player Movement", throwIfNotFound: true);
m_PlayerMovement_Movement = m_PlayerMovement.FindAction("Movement", throwIfNotFound: true);
m_PlayerMovement_Camera = m_PlayerMovement.FindAction("Camera", throwIfNotFound: true);
- m_PlayerMovement_Roll = m_PlayerMovement.FindAction("Roll", throwIfNotFound: true);
+ // Player Actions
+ m_PlayerActions = asset.FindActionMap("Player Actions", throwIfNotFound: true);
+ m_PlayerActions_Roll = m_PlayerActions.FindAction("Roll", throwIfNotFound: true);
}
public void Dispose()
@@ -217,14 +238,12 @@ public partial class @PlayerControls: IInputActionCollection2, IDisposable
private List<IPlayerMovementActions> m_PlayerMovementActionsCallbackInterfaces = new List<IPlayerMovementActions>();
private readonly InputAction m_PlayerMovement_Movement;
private readonly InputAction m_PlayerMovement_Camera;
- private readonly InputAction m_PlayerMovement_Roll;
public struct PlayerMovementActions
{
private @PlayerControls m_Wrapper;
public PlayerMovementActions(@PlayerControls wrapper) { m_Wrapper = wrapper; }
public InputAction @Movement => m_Wrapper.m_PlayerMovement_Movement;
public InputAction @Camera => m_Wrapper.m_PlayerMovement_Camera;
- public InputAction @Roll => m_Wrapper.m_PlayerMovement_Roll;
public InputActionMap Get() { return m_Wrapper.m_PlayerMovement; }
public void Enable() { Get().Enable(); }
public void Disable() { Get().Disable(); }
@@ -240,9 +259,6 @@ public partial class @PlayerControls: IInputActionCollection2, IDisposable
@Camera.started += instance.OnCamera;
@Camera.performed += instance.OnCamera;
@Camera.canceled += instance.OnCamera;
- @Roll.started += instance.OnRoll;
- @Roll.performed += instance.OnRoll;
- @Roll.canceled += instance.OnRoll;
}
private void UnregisterCallbacks(IPlayerMovementActions instance)
@@ -253,9 +269,6 @@ public partial class @PlayerControls: IInputActionCollection2, IDisposable
@Camera.started -= instance.OnCamera;
@Camera.performed -= instance.OnCamera;
@Camera.canceled -= instance.OnCamera;
- @Roll.started -= instance.OnRoll;
- @Roll.performed -= instance.OnRoll;
- @Roll.canceled -= instance.OnRoll;
}
public void RemoveCallbacks(IPlayerMovementActions instance)
@@ -273,10 +286,59 @@ public partial class @PlayerControls: IInputActionCollection2, IDisposable
}
}
public PlayerMovementActions @PlayerMovement => new PlayerMovementActions(this);
+
+ // Player Actions
+ private readonly InputActionMap m_PlayerActions;
+ private List<IPlayerActionsActions> m_PlayerActionsActionsCallbackInterfaces = new List<IPlayerActionsActions>();
+ private readonly InputAction m_PlayerActions_Roll;
+ public struct PlayerActionsActions
+ {
+ private @PlayerControls m_Wrapper;
+ public PlayerActionsActions(@PlayerControls wrapper) { m_Wrapper = wrapper; }
+ public InputAction @Roll => m_Wrapper.m_PlayerActions_Roll;
+ public InputActionMap Get() { return m_Wrapper.m_PlayerActions; }
+ public void Enable() { Get().Enable(); }
+ public void Disable() { Get().Disable(); }
+ public bool enabled => Get().enabled;
+ public static implicit operator InputActionMap(PlayerActionsActions set) { return set.Get(); }
+ public void AddCallbacks(IPlayerActionsActions instance)
+ {
+ if (instance == null || m_Wrapper.m_PlayerActionsActionsCallbackInterfaces.Contains(instance)) return;
+ m_Wrapper.m_PlayerActionsActionsCallbackInterfaces.Add(instance);
+ @Roll.started += instance.OnRoll;
+ @Roll.performed += instance.OnRoll;
+ @Roll.canceled += instance.OnRoll;
+ }
+
+ private void UnregisterCallbacks(IPlayerActionsActions instance)
+ {
+ @Roll.started -= instance.OnRoll;
+ @Roll.performed -= instance.OnRoll;
+ @Roll.canceled -= instance.OnRoll;
+ }
+
+ public void RemoveCallbacks(IPlayerActionsActions instance)
+ {
+ if (m_Wrapper.m_PlayerActionsActionsCallbackInterfaces.Remove(instance))
+ UnregisterCallbacks(instance);
+ }
+
+ public void SetCallbacks(IPlayerActionsActions instance)
+ {
+ foreach (var item in m_Wrapper.m_PlayerActionsActionsCallbackInterfaces)
+ UnregisterCallbacks(item);
+ m_Wrapper.m_PlayerActionsActionsCallbackInterfaces.Clear();
+ AddCallbacks(instance);
+ }
+ }
+ public PlayerActionsActions @PlayerActions => new PlayerActionsActions(this);
public interface IPlayerMovementActions
{
void OnMovement(InputAction.CallbackContext context);
void OnCamera(InputAction.CallbackContext context);
+ }
+ public interface IPlayerActionsActions
+ {
void OnRoll(InputAction.CallbackContext context);
}
}
diff --git a/Assets/Scripts/InputSystem/PlayerControls.inputactions b/Assets/Scripts/InputSystem/PlayerControls.inputactions
index f3edee9..0878606 100644
--- a/Assets/Scripts/InputSystem/PlayerControls.inputactions
+++ b/Assets/Scripts/InputSystem/PlayerControls.inputactions
@@ -22,15 +22,6 @@
"processors": "",
"interactions": "",
"initialStateCheck": true
- },
- {
- "name": "Roll",
- "type": "Button",
- "id": "5e423815-95ec-43c1-9718-224f86c8f24e",
- "expectedControlType": "Button",
- "processors": "",
- "interactions": "",
- "initialStateCheck": false
}
],
"bindings": [
@@ -110,10 +101,38 @@
"action": "Camera",
"isComposite": false,
"isPartOfComposite": false
+ }
+ ]
+ },
+ {
+ "name": "Player Actions",
+ "id": "e698248c-d44d-4c32-9308-df1fb8952042",
+ "actions": [
+ {
+ "name": "Roll",
+ "type": "Button",
+ "id": "b5381d00-a598-472a-96b6-e7a5ed618a96",
+ "expectedControlType": "Button",
+ "processors": "",
+ "interactions": "",
+ "initialStateCheck": false
+ }
+ ],
+ "bindings": [
+ {
+ "name": "",
+ "id": "8af511c9-0a47-4f49-b1e0-a98500b70c9d",
+ "path": "<Gamepad>/buttonEast",
+ "interactions": "",
+ "processors": "",
+ "groups": "",
+ "action": "Roll",
+ "isComposite": false,
+ "isPartOfComposite": false
},
{
"name": "",
- "id": "4690e573-c6d7-4c20-bbee-ba5d11ca8a18",
+ "id": "a76c6730-3d6e-4609-a3fb-450fe20ef6e2",
"path": "<Keyboard>/space",
"interactions": "",
"processors": "",
diff --git a/Assets/Scripts/PlayerLocomotion.cs b/Assets/Scripts/PlayerLocomotion.cs
index 5203432..5952325 100644
--- a/Assets/Scripts/PlayerLocomotion.cs
+++ b/Assets/Scripts/PlayerLocomotion.cs
@@ -110,7 +110,9 @@ namespace DS
// ============================================================
private void Update()
{
- UpdateCharacterMovement();
+ float delta = Time.deltaTime; // 获取帧时间
+ UpdateCharacterMovement(delta);
+ HandleRollingAndSpringting(delta);
}
// ============================================================
@@ -121,14 +123,56 @@ namespace DS
// 当前未在此处处理逻辑
// 若需要基于物理的移动,可将 rigidbody.velocity 赋值移到这里
}
+
+ // ============================================================
+ // 移动与旋转相关方法
+ // ============================================================
+ #region Movement
+ /// <summary>
+ /// 处理角色旋转逻辑。
+ /// 根据输入方向和摄像机朝向,平滑旋转角色面向移动方向。
+ /// </summary>
+ /// <param name="delta">帧时间(秒)</param>
+ private void HandleRotation(float delta)
+ {
+ Vector3 targetDir = Vector3.zero; // 目标朝向向量
+ // 注意:当前未使用 moveOverride,保留备用
+ float moveOverride = _inputHandler.moveAmount;
+
+ // ----------------------------------------------------------
+ // 1. 根据输入计算目标朝向
+ // ----------------------------------------------------------
+ // 目标朝向 = 摄像机正方向 * 垂直输入 + 摄像机右方向 * 水平输入
+ targetDir = _cameraObject.forward * _inputHandler.vertical;
+ targetDir += _cameraObject.right * _inputHandler.horizontal;
+
+ // 归一化并置平 Y 轴
+ targetDir.Normalize();
+ targetDir.y = 0;
+
+ // 如果没有输入(目标方向为零向量),则保持当前面向不变
+ if (targetDir == Vector3.zero)
+ {
+ targetDir = myTransform.forward;
+ }
+
+ // ----------------------------------------------------------
+ // 2. 通过 Slerp 平滑旋转至目标方向
+ // ----------------------------------------------------------
+ float rs = rotationSpeed; // 旋转速度
+ Quaternion tr = Quaternion.LookRotation(targetDir); // 目标旋转四元数
+ // 使用球形插值(Slerp)实现平滑旋转
+ Quaternion targetRotation = Quaternion.Slerp(myTransform.rotation, tr, rs * delta);
+
+ // 应用旋转
+ myTransform.rotation = targetRotation;
+ }
// ============================================================
// 角色移动更新(核心逻辑)
// ============================================================
- private void UpdateCharacterMovement()
+ private void UpdateCharacterMovement(float delta)
{
- float delta = Time.deltaTime; // 获取帧时间
-
// 处理输入(读取水平/垂直输入值)
_inputHandler.TickInput(delta);
@@ -190,51 +234,31 @@ namespace DS
}
}
- // ============================================================
- // 移动与旋转相关方法
- // ============================================================
- #region Movement
-
- /// <summary>
- /// 处理角色旋转逻辑。
- /// 根据输入方向和摄像机朝向,平滑旋转角色面向移动方向。
- /// </summary>
- /// <param name="delta">帧时间(秒)</param>
- private void HandleRotation(float delta)
+ private void HandleRollingAndSpringting(float delta)
{
- Vector3 targetDir = Vector3.zero; // 目标朝向向量
- // 注意:当前未使用 moveOverride,保留备用
- float moveOverride = _inputHandler.moveAmount;
-
- // ----------------------------------------------------------
- // 1. 根据输入计算目标朝向
- // ----------------------------------------------------------
- // 目标朝向 = 摄像机正方向 * 垂直输入 + 摄像机右方向 * 水平输入
- targetDir = _cameraObject.forward * _inputHandler.vertical;
- targetDir += _cameraObject.right * _inputHandler.horizontal;
-
- // 归一化并置平 Y 轴
- targetDir.Normalize();
- targetDir.y = 0;
-
- // 如果没有输入(目标方向为零向量),则保持当前面向不变
- if (targetDir == Vector3.zero)
+ if (animatorHandler.animator.GetBool("isInteracting"))
{
- targetDir = myTransform.forward;
+ return;
}
- // ----------------------------------------------------------
- // 2. 通过 Slerp 平滑旋转至目标方向
- // ----------------------------------------------------------
- float rs = rotationSpeed; // 旋转速度
- Quaternion tr = Quaternion.LookRotation(targetDir); // 目标旋转四元数
- // 使用球形插值(Slerp)实现平滑旋转
- Quaternion targetRotation = Quaternion.Slerp(myTransform.rotation, tr, rs * delta);
-
- // 应用旋转
- myTransform.rotation = targetRotation;
+ if (_inputHandler.rollFlag)
+ {
+ _moveDirection = _cameraObject.forward * _inputHandler.vertical;
+ _moveDirection += _cameraObject.right * _inputHandler.horizontal;
+
+ if (_inputHandler.moveAmount > 0)
+ {
+ animatorHandler.PlayerTargetAnimation("Roll",true);
+ _moveDirection.y = 0;
+ Quaternion rollRotation = Quaternion.LookRotation(_moveDirection);
+ myTransform.rotation = rollRotation;
+ }
+ else
+ {
+ animatorHandler.PlayerTargetAnimation("step_back",true);
+ }
+ }
}
-
#endregion
}
diff --git a/Assets/Scripts/PlayerManager.cs b/Assets/Scripts/PlayerManager.cs
index 46a2894..1acd8e4 100644
--- a/Assets/Scripts/PlayerManager.cs
+++ b/Assets/Scripts/PlayerManager.cs
@@ -1,8 +1,23 @@
+using System;
using System.Collections;
using System.Collections.Generic;
+using DS;
using UnityEngine;
public class PlayerManager : MonoBehaviour
{
- public Animator animator;
+ private InputHandler _inputHandler;
+ private Animator _animator;
+
+ private void Start()
+ {
+ _inputHandler = GetComponent<InputHandler>();
+ _animator = GetComponentInChildren<Animator>();
+ }
+
+ private void Update()
+ {
+ _inputHandler.isInteracting = _animator.GetBool("isInteracting");
+ _inputHandler.rollFlag = false;
+ }
}
diff --git a/Assets/Scripts/ResetIsInteracting.cs b/Assets/Scripts/ResetIsInteracting.cs
new file mode 100644
index 0000000..a587a68
--- /dev/null
+++ b/Assets/Scripts/ResetIsInteracting.cs
@@ -0,0 +1,15 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class ResetIsInteracting : StateMachineBehaviour
+{
+
+ // OnStateExit is called when a transition ends and the state machine finishes evaluating this state
+ override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
+ {
+ animator.SetBool("isInteracting", false);
+ }
+}
+
+
diff --git a/Assets/Scripts/ResetIsInteracting.cs.meta b/Assets/Scripts/ResetIsInteracting.cs.meta
new file mode 100644
index 0000000..1a66f6c
--- /dev/null
+++ b/Assets/Scripts/ResetIsInteracting.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c1eaee900a90ae44d8ea71f8887cfcd2
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: