如何让Unity对象沿X轴在两点间无限往复移动?
解决Unity对象X轴无限往复移动的问题
你的代码存在两个核心问题:
- 浮点数精度问题:直接用
transform.position == secondPosition判断到达目标点不可靠,Vector3.MoveTowards可能因帧率或速度设置,让物体位置无法完全等于目标点,导致切换逻辑失效。 - 目标点丢失:直接将
secondPosition替换为firstPosition,没有保留原始的两个目标位置,导致物体到达反向点后,无法再切换回初始目标。
下面提供两种可靠的实现方式:
方法一:基于目标点切换的Update实现
保留原始的两个位置,用临时变量存储当前目标,通过距离判断是否到达,到达后切换目标:
using UnityEngine; public class MovingTarget : MonoBehaviour { [SerializeField] private Vector3 firstPosition = new Vector3(-14f, 2.5f, 17f); [SerializeField] private Vector3 secondPosition = new Vector3(14f, 2.5f, 17f); public float speed = 10f; private Vector3 _currentTarget; void Start() { transform.position = firstPosition; _currentTarget = secondPosition; } void Update() { // 向当前目标移动 transform.position = Vector3.MoveTowards(transform.position, _currentTarget, Time.deltaTime * speed); // 用距离判断是否到达目标(避免浮点数精度问题) if (Vector3.Distance(transform.position, _currentTarget) < 0.01f) { // 切换目标点 _currentTarget = _currentTarget == firstPosition ? secondPosition : firstPosition; } } }
方法二:用Mathf.PingPong实现平滑往复
如果仅需沿X轴移动,Mathf.PingPong可以更简洁地实现无限往复效果,无需手动判断目标点:
using UnityEngine; public class MovingTarget : MonoBehaviour { [SerializeField] private float startX = -14f; [SerializeField] private float endX = 14f; [SerializeField] private float y = 2.5f; [SerializeField] private float z = 17f; public float speed = 10f; private float _totalDistance; void Start() { _totalDistance = endX - startX; transform.position = new Vector3(startX, y, z); } void Update() { // PingPong返回0到_totalDistance之间的往复值 float xPos = startX + Mathf.PingPong(Time.time * speed, _totalDistance); transform.position = new Vector3(xPos, y, z); } }
补充说明
- 方法一适合需要精确控制目标点的场景,支持任意Vector3位置的往复;
- 方法二更适合单轴往复的简单场景,代码简洁,移动平滑无卡顿;
- 避免直接比较Vector3相等,始终用
Vector3.Distance或Vector3.sqrMagnitude(性能更优)来判断是否到达目标。
内容的提问来源于stack exchange,提问作者Leila Woźniak
相关产品推荐
相关产品推荐

