From 5360e988fa7c47da8d58ee3a25a7ed92fd700a57 Mon Sep 17 00:00:00 2001 From: Weicao-CatilGrass <1992414357@qq.com> Date: Fri, 22 May 2026 12:40:52 +0800 Subject: 让DeepSeek添加详尽的注释 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Scripts/AnimatorHandler.cs | 124 +++++++++++++++++++++++++++++--------- 1 file changed, 96 insertions(+), 28 deletions(-) (limited to 'Assets/Scripts/AnimatorHandler.cs') diff --git a/Assets/Scripts/AnimatorHandler.cs b/Assets/Scripts/AnimatorHandler.cs index df1f1f1..deae0ac 100644 --- a/Assets/Scripts/AnimatorHandler.cs +++ b/Assets/Scripts/AnimatorHandler.cs @@ -5,107 +5,175 @@ using UnityEngine; namespace DS { + /// + /// 动画处理器 - 负责管理角色动画参数的更新、根运动(Root Motion)的提取, + /// 以及角色旋转状态的控制。 + /// public class AnimatorHandler : MonoBehaviour { - public PlayerLocomotion playerLocomotion; - public Animator animator; - private int _vertical; - private int _horizontal; - public bool canRotate; + [Header("组件引用")] + public PlayerLocomotion playerLocomotion; // 玩家移动控制器引用,用于传递根运动数据 + public Animator animator; // 动画器组件引用 + [Header("动画参数哈希")] + private int _vertical; // "Vertical" 动画参数的哈希值,用于高效设置动画参数 + private int _horizontal; // "Horizontal" 动画参数的哈希值 + + [Header("旋转状态")] + public bool canRotate; // 是否允许角色旋转,在动画事件中控制 + + /// + /// 初始化函数 - 获取 Animator 组件并计算动画参数的哈希值。 + /// 哈希值用于替代字符串名称,提高性能。 + /// public void Initialize() { + // 获取当前 GameObject 上的 Animator 组件 animator = GetComponent(); + + // 使用 Animator.StringToHash 将字符串参数名转换为整数哈希值 + // 这样在 SetFloat 时使用哈希值比使用字符串更高效 _vertical = Animator.StringToHash("Vertical"); _horizontal = Animator.StringToHash("Horizontal"); } + /// + /// 更新动画参数值 - 将输入的移动数值映射为动画混合树使用的离散值。 + /// 输入值范围通常为 -1 到 1,将其量化为 -1, -0.5, 0, 0.5, 1 五个档位, + /// 以实现从慢走到快跑的平滑过渡。 + /// + /// 垂直方向的移动输入(前进/后退),范围 -1 ~ 1 + /// 水平方向的移动输入(左移/右移),范围 -1 ~ 1 public void UpdateAnimatorValues(float verticalMovement, float horizontalMovement) { - #region Vertical + #region Vertical — 垂直方向(前进/后退)的动画参数处理 - float v = 0; + float v = 0; // 存储映射后的垂直动画参数值 + // 判断垂直移动输入,将其量化为几档: + // 0~0.55 之间视为慢速行走(0.5),大于 0.55 视为奔跑(1) + // 负值同理,处理后退动作 if (verticalMovement > 0 && verticalMovement < 0.55f) { - v = 0.5f; + v = 0.5f; // 慢速前进 } else if(verticalMovement > 0.55f) { - v = 1; + v = 1; // 快速前进/奔跑 } else if (verticalMovement < 0 && verticalMovement > -0.55f) { - v = -0.5f; + v = -0.5f; // 慢速后退 } else if(verticalMovement < -0.55f) { - v = -1; + v = -1; // 快速后退 } else { - v = 0; + v = 0; // 无输入或死区范围内,保持静止 } - + #endregion - - #region Horizontal - float h = 0; + #region Horizontal — 水平方向(左/右)的动画参数处理 + + float h = 0; // 存储映射后的水平动画参数值 + // 同样将水平移动输入量化为几档,用于控制侧移或转身动画 if (horizontalMovement > 0 && horizontalMovement < 0.55f) { - h = 0.5f; + h = 0.5f; // 慢速向右 } else if(horizontalMovement > 0.55f) { - h = 1; + h = 1; // 快速向右 } else if (horizontalMovement < 0 && horizontalMovement > -0.55f) { - h = -0.5f; + h = -0.5f; // 慢速向左 } else if(horizontalMovement < -0.55f) { - h = -1; + h = -1; // 快速向左 } else { - h = 0; + h = 0; // 无输入或死区范围内,保持静止 } - + #endregion - - animator.SetFloat(_vertical,v,0.1f,Time.deltaTime); - animator.SetFloat(_horizontal,h,0.1f,Time.deltaTime); + + // 将计算后的参数值设置到 Animator 中 + // 第三个参数 dampTime 为 0.1f,表示在 0.1 秒内平滑过渡到目标值 + // 第四个参数 deltaTime 用于确保平滑速度与帧率无关 + animator.SetFloat(_vertical, v, 0.1f, Time.deltaTime); + animator.SetFloat(_horizontal, h, 0.1f, Time.deltaTime); } + /// + /// 动画事件回调 - 允许角色在动画的特定帧开始旋转。 + /// 通常在动画的某个时间点(如转身动画的起始帧)由动画事件调用。 + /// public void CanRotate() { - canRotate = true; + canRotate = true; // 启用旋转 } + /// + /// 动画事件回调 - 停止角色的旋转。 + /// 通常在动画的某个时间点(如转身动画的结束帧)由动画事件调用, + /// 防止角色在不需要旋转时继续旋转。 + /// public void StopRotation() { - canRotate = false; + canRotate = false; // 禁用旋转 } + /// + /// MonoBehaviour 生命周期函数 - 在 Animator 更新动画时每帧调用。 + /// 用于处理根运动(Root Motion)数据,将动画驱动的位移传递给 PlayerLocomotion。 + /// 需要勾选 Animator 组件的"Apply Root Motion"选项才能触发此回调。 + /// private void OnAnimatorMove() { + // 获取当前帧的根运动位移向量 var rootMotion = GetRootMotion(); + + // 输出调试日志,用于查看根运动数据 Debug.Log(rootMotion); + + // 将根运动数据传递给 PlayerLocomotion 组件 + // PlayerLocomotion 会将这些位移应用到角色控制器上 playerLocomotion.rootMotion = rootMotion; } + /// + /// 编辑器辅助函数 - 在 Scene 视图中绘制调试线条, + /// 可视化显示根运动的方向和大小(放大 2 倍以便观察)。 + /// 仅在编辑器中有效,不会影响运行时性能。 + /// private void OnDrawGizmos() { + // 从角色当前位置绘制一条线到 当前位置 + 根运动方向 * 2 Gizmos.DrawLine(transform.position, transform.position + GetRootMotion() * 2f); } + /// + /// 提取根运动向量 - 从 Animator 的当前速度中提取水平方向上的位移, + /// 忽略垂直方向(Y 轴)的运动。 + /// 这样可以防止动画中的微小垂直位移影响角色位置(如地面抖动)。 + /// + /// 返回一个 Vector3,表示投影到水平平面上的根运动位移 private Vector3 GetRootMotion() { - // 我们先假定 地板永远是朝上的 + // 假定地面法线始终朝上(即世界坐标的 Y 轴方向) + // 注意:如果角色在斜坡上运动,此处需要根据地面法线动态调整 var normalVector = Vector3.up; + + // 将 animator.velocity(动画驱动的速度向量)投影到法线定义的平面上 + // Vector3.ProjectOnPlane 会去除向量中沿法线方向的分量 + // 这样只保留水平方向的位移,避免 Y 轴上的微小波动影响角色位置 return Vector3.ProjectOnPlane(animator.velocity, normalVector); } } -- cgit