Unity 触摸控制模型移动时未面向行进方向的朝向异常问题
触摸移动朝向错误的根因与修正方案
原代码核心问题
- 射线检测传参错误:
Camera.main.ScreenPointToRay()需要传入触摸的屏幕绝对坐标才能正确生成指向世界空间的射线,原代码传入的touch.deltaPosition是相邻两帧的手指位置差(即滑动步长),数值通常仅为几到几十像素,根本不是有效屏幕坐标,计算得到的targetPos偏差极大。 - 移动与朝向逻辑脱节:原代码直接根据触摸增量修改角色位置,但转头就强制角色看向上述错误逻辑算出的
targetPos,完全没有把角色朝向和实际移动方向绑定,才会出现向上滑动时角色不面向前进方向、反而盯着错误近点的问题。 - 冗余参数未生效:代码中声明的
speed公开变量全程没有参与位置计算,实际移动速度没有做合理缩放,容易出现角色位移过快的问题。
正确实现逻辑
核心需求是角色移动时自动面向行进方向,根本不需要额外计算触摸点对应的世界坐标作为朝向目标。只需要把本帧生成的世界空间移动向量提取出来,让角色平滑对齐这个向量即可。
修正后可直接运行的代码
private Touch touch; public float speed = 5f; public Animator animator; // 存储本帧实际移动方向,用于朝向判断 private Vector3 moveDir; void Start() { // 初始状态保持自身位置,无多余初始化逻辑 } void Update() { if (Input.touchCount > 0) { touch = Input.GetTouch(0); if (touch.phase == TouchPhase.Moved) { // 把触摸的屏幕方向增量转换为世界空间移动向量 float moveX = touch.deltaPosition.x * Time.deltaTime; float moveZ = touch.deltaPosition.y * Time.deltaTime; moveDir = new Vector3(moveX, 0f, moveZ).normalized; // 应用带速度缩放的位置移动 transform.position += moveDir * speed * Time.deltaTime; // 仅当存在有效位移时才调整朝向,避免静止时朝向抖动 if (moveDir.magnitude > 0.01f) { // 计算水平方向的目标朝向,保持角色不会歪倒 Quaternion targetRotation = Quaternion.LookRotation(moveDir, Vector3.up); // 平滑过渡转身,避免生硬跳变 transform.rotation = Quaternion.Lerp( transform.rotation, targetRotation, Time.deltaTime * 10f ); } // 可在此处接入动画逻辑,例如把移动速度传给Animator触发奔跑状态 // animator.SetFloat("MoveSpeed", moveDir.magnitude * speed); } else { // 手指停止滑动时清空移动方向,触发停驻动画 moveDir = Vector3.zero; } } }
补充说明
- 已删除原代码中无意义的平面碰撞、射线检测逻辑:这套逻辑本身是为“点哪走哪”的设计服务的,和当前“滑动移动、面朝行进方向”的需求完全不匹配,留着只会引入bug。
- 转身逻辑加了位移幅度判断和Lerp平滑处理,解决了小幅度滑动时角色朝向频繁抖动、生硬转向的问题。
- 把之前遗漏的
speed参数接入了位移计算,可直接在Inspector面板调整移动快慢,不用修改代码。
内容的提问来源于stack exchange,提问作者noobtrynalearn
相关产品推荐
相关产品推荐

