Unity实现两个立方体循环相向靠近、反向远离的自动开关门效果
问题根源
- 无状态控制逻辑:仅实现了关门时的相向移动逻辑,未加入开门阶段的反向移动逻辑,也没有标记当前门处于开/关过程的变量
- 距离检测逻辑有缺陷:先检测距离再执行移动,单帧移动量过大时会直接穿过阈值,无法触发状态切换
- 缺少开门终止判定条件:没有记录门完全打开时的位置作为切换回关门状态的依据
修复后完整代码
using UnityEngine; public class Gate : MonoBehaviour { public Transform[] gateParts; public float speed = 2f; // 关门停止的间距阈值 public float stopCloseDist = 0.1f; // 标记当前是否处于关门阶段 private bool isClosing = true; // 记录两个门部件的初始位置(完全打开的位置) private Vector3 gate0InitPos; private Vector3 gate1InitPos; // 完全打开的最大间距 private float openMaxDist; void Start() { gate0InitPos = gateParts[0].position; gate1InitPos = gateParts[1].position; openMaxDist = Vector3.Distance(gate0InitPos, gate1InitPos); } void Update() { float currentDist = Vector3.Distance(gateParts[0].position, gateParts[1].position); if (isClosing) { // 关门阶段:两部分相向移动 gateParts[0].position = Vector3.MoveTowards(gateParts[0].position, gateParts[1].position, Time.deltaTime * speed); gateParts[1].position = Vector3.MoveTowards(gateParts[1].position, gateParts[0].position, Time.deltaTime * speed); // 间距小于等于阈值,切换为开门状态 if (currentDist <= stopCloseDist) { isClosing = false; } } else { // 开门阶段:两部分回到初始打开位置 gateParts[0].position = Vector3.MoveTowards(gateParts[0].position, gate0InitPos, Time.deltaTime * speed); gateParts[1].position = Vector3.MoveTowards(gateParts[1].position, gate1InitPos, Time.deltaTime * speed); // 间距回到初始最大值,切换为关门状态 if (currentDist >= openMaxDist) { isClosing = true; } } } }
注意事项
- 可以根据场景需求调整
speed和stopCloseDist的数值,控制开关门速度和关门的贴合程度 - 如果需要开关门完成后停顿一段时间再执行下一个动作,可以在切换
isClosing状态的位置加入协程延迟赋值即可
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

