Unity2D中Pac-Man自动沿路径移动出现左右往复异常的问题求助
Unity2D中Pac-Man自动沿路径移动出现左右往复异常的问题求助
看起来你遇到的自动游走循环问题很典型,我帮你分析下代码里的核心问题,再给你调整方案~
问题根源
你的HandleAutoInputDirection函数现在的逻辑是每次按固定优先级(右→上→左→下)找第一个可行的非反向方向,但当Pac-Man走到通道尽头时,moveDir会被置为zero,这时候反向判断(dir == -moveDir)就失效了(因为-zero还是zero,所有方向都不会被跳过)。举个例子:
- 当Pac-Man走到最右侧墙,
moveDir被设为zero - 下一次调用自动寻路时,第一个检查的方向是右(不可行),然后是上(不可行),接着是左(可行),于是选左
- 走到最左侧墙后,
moveDir又被设为zero - 下一次寻路时,第一个检查的方向是右(可行),直接选右,如此往复就形成了左右撞墙的循环
另外,你的逻辑没有优先保持当前前进方向,哪怕当前方向还能走,也会按固定优先级重新选方向,这也会导致不必要的转向。
修复方案
我们调整自动寻路逻辑,让Pac-Man优先沿着当前方向走到底,只有当当前方向走不通时,再找其他可行的非反向方向,如果需要更自然的游走,还可以在岔路口随机选方向(可选)。
1. 重构自动寻路函数
先把方向选择拆分成“优先保持当前方向”和“寻找备选方向”两部分,代码更清晰:
void HandleAutoInputDirection() { // 优先尝试继续沿着当前方向前进 if (moveDir != Vector2Int.zero) { Vector2Int nextGrid = currentGrid + moveDir; if (IsWalkable(nextGrid)) { // 当前方向还能走,就继续用这个方向 nextDir = moveDir; } else { // 当前方向走不通了,找其他可行方向 FindValidAlternativeDirections(); } } else { // 没有当前移动方向(刚起步或刚撞墙),直接找可行方向 FindValidAlternativeDirections(); } // 只有当静止且下一个方向可行时,才启动移动 if (moveDir == Vector2Int.zero && IsWalkable(currentGrid + nextDir)) { moveDir = nextDir; targetPos = GridToWorld(currentGrid + moveDir); UpdateFacingDirection(); } } // 寻找可行的备选方向(排除反向) void FindValidAlternativeDirections() { // 收集所有可行的非反向方向 List<Vector2Int> validDirs = new List<Vector2Int>(); Vector2Int[] directions = new Vector2Int[] { Vector2Int.right, Vector2Int.up, Vector2Int.left, Vector2Int.down }; foreach (var dir in directions) { // 跳过反向(只有当前有移动方向时才判断) if (moveDir != Vector2Int.zero && dir == -moveDir) continue; Vector2Int nextGrid = currentGrid + dir; if (IsWalkable(nextGrid)) { validDirs.Add(dir); } } // 从可行方向里选一个:如果要固定优先级就取第一个,要随机游走就随机选 if (validDirs.Count > 0) { // 可选:用Random.Range(0, validDirs.Count)实现随机游走 nextDir = validDirs[0]; // nextDir = validDirs[Random.Range(0, validDirs.Count)]; } }
2. 调整Update中的方向切换逻辑
在你Update函数里,当Pac-Man到达目标点后的方向切换逻辑,可以简化下,确保和自动寻路逻辑对齐:
// 到达目标点后的处理 if (Vector3.Distance(transform.position, targetPos) < 0.001f) { currentGrid += moveDir; textCurrentGridValue.text = currentGrid.ToString(); // 隧道包裹逻辑(保留你的原有代码) int width = layout[0].Length; if (currentGrid.x <= 0) { currentGrid.x = width - 1; transform.position = GridToWorld(currentGrid); targetPos = GridToWorld(currentGrid + moveDir); } else if (currentGrid.x >= width - 1) { currentGrid.x = 0; transform.position = GridToWorld(currentGrid); targetPos = GridToWorld(currentGrid + moveDir); } // 检查当前方向是否还能走,不能走就清空moveDir,让下一次Update的自动寻路找新方向 Vector2Int nextStep = currentGrid + moveDir; if (!IsWalkable(nextStep)) { moveDir = Vector2Int.zero; } else { // 还能走就更新目标点 targetPos = GridToWorld(nextStep); UpdateFacingDirection(); } }
额外优化建议
如果想让自动游走更真实,可以把FindValidAlternativeDirections里的nextDir = validDirs[0]改成随机选一个可行方向(就是注释里的那行),这样Pac-Man遇到岔路口会随机选路,不会每次走同一条固定路线。
你可以先试试上面的基础修复,应该就能解决左右往复的问题啦~
内容来源于stack exchange
相关产品推荐
相关产品推荐

