如何实现玩家按A/D键平滑移动到左右下一个Transform点位?
嘿,我懂你要做的这种点位式左右移动功能,用协程来处理平滑过渡确实是很合适的方案。我来给你整理一套完整的实现代码,顺便把容易踩的坑给你标出来:
核心实现思路
- 首先得维护一个当前点位的索引,这样每次按A/D时能直接定位到下一个目标,不用每次遍历数组浪费性能
- 必须加个移动状态标记,防止玩家连续按键触发多个协程,导致角色移动逻辑混乱
- 协程里用逐帧插值的方式实现平滑移动,保证移动过程自然流畅
完整代码示例
using UnityEngine; using System.Collections; public class CharacterWaypointMovement : MonoBehaviour { // 在Inspector面板中拖拽赋值的移动点位数组 public Transform[] moveWaypoints; // 移动速度,可根据需求调节 public float moveSpeed = 4f; // 当前所在点位的索引 private int currentWaypointIndex = 0; // 标记是否正在移动,避免重复触发协程 private bool isMoving = false; void Update() { // 仅当不在移动状态时,响应A/D按键 if (Input.GetKeyDown(KeyCode.A) && !isMoving) { StartCoroutine(MoveToTargetWaypoint(-1)); // -1对应向左切换点位 } if (Input.GetKeyDown(KeyCode.D) && !isMoving) { StartCoroutine(MoveToTargetWaypoint(1)); // 1对应向右切换点位 } } IEnumerator MoveToTargetWaypoint(int direction) { isMoving = true; // 更新目标点位索引,同时处理边界情况 currentWaypointIndex += direction; // 这里做了循环边界处理(比如最左按A跳到最右),不需要的话可以替换成Clamp if (currentWaypointIndex < 0) { currentWaypointIndex = moveWaypoints.Length - 1; } else if (currentWaypointIndex >= moveWaypoints.Length) { currentWaypointIndex = 0; } Transform targetWaypoint = moveWaypoints[currentWaypointIndex]; // 逐帧移动直到到达目标点位附近 while (Vector3.Distance(transform.position, targetWaypoint.position) > 0.01f) { // MoveTowards实现匀速移动,想要缓动效果可以换成Vector3.Lerp transform.position = Vector3.MoveTowards(transform.position, targetWaypoint.position, moveSpeed * Time.deltaTime); yield return null; // 等待下一帧再继续执行 } // 最后精准定位到目标点位,避免微小偏移 transform.position = targetWaypoint.position; isMoving = false; } }
关键细节提示
- 移动状态锁
isMoving:这是最容易忽略的点!如果没有这个标记,玩家快速按A/D会同时启动多个协程,角色会出现瞬移或者来回抖动的问题,一定要在协程启动时设为true,结束时设为false - 边界逻辑自定义:代码里的边界是循环的,如果你希望到最左/最右后按键不再响应,把索引更新后的判断换成
currentWaypointIndex = Mathf.Clamp(currentWaypointIndex, 0, moveWaypoints.Length - 1)即可 - 移动效果调整:用
Vector3.MoveTowards是匀速移动,想要更柔和的缓入缓出效果,可以改用Vector3.Lerp,不过需要注意调整moveSpeed的数值,避免移动过慢或者过快 - 点位顺序:在Inspector里给
moveWaypoints赋值时,要保证数组的顺序和你预期的左右顺序一致,不然移动方向会出错
内容的提问来源于stack exchange,提问作者Wp3Dev
相关产品推荐
相关产品推荐

