如何修改Unity Enemy脚本使其沿弧线往复移动?
实现敌人往复弧线移动逻辑修改
问题分析
- 原代码用
Mathf.PingPong同时控制X、Y轴偏移,无法实现你需要的「Y到上限后X继续正向、Y反向;Y回起点后沿弧线返回」的独立方向逻辑 - 直接判断
y == range会因为浮点数精度误差失效,必须用范围判断 - 用
CompareTag("Ground")触发方向反转逻辑不准确,应该直接检测Y轴是否回到起始位置
修改后的代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Enemy : Enemy_Damage { [SerializeField] private float range; // Y轴移动上限范围 [SerializeField] private float speed; // 移动速度 [SerializeField] private float arcFactor = 1f; // 弧线弯曲系数,值越大弧线越陡 private Vector3 startPosition; private bool isGoingUp = true; // 是否处于上升阶段 private bool isReturning = false; // 是否处于返回起始点阶段 private float journeyProgress = 0f; // 移动进度(0到1) private void Start() { startPosition = transform.position; } private void Update() { if (!isReturning) { // 正常移动阶段:上升→下降 if (isGoingUp) { journeyProgress += Time.deltaTime * speed / range; journeyProgress = Mathf.Clamp01(journeyProgress); // 计算弧线位置:X随进度线性增加,Y用二次曲线模拟弧线 float xOffset = journeyProgress * range; float yOffset = arcFactor * journeyProgress * (2 - journeyProgress) * range; transform.position = startPosition + new Vector3(xOffset, yOffset, 0); // 判断是否到达Y轴上限(用范围避免浮点数精度问题) if (journeyProgress >= 1f) { isGoingUp = false; } } else { journeyProgress -= Time.deltaTime * speed / range; journeyProgress = Mathf.Clamp01(journeyProgress); // 下降阶段:X继续增加,Y随进度下降 float xOffset = journeyProgress * range + range; float yOffset = arcFactor * journeyProgress * (2 - journeyProgress) * range; transform.position = startPosition + new Vector3(xOffset, yOffset, 0); // 判断是否回到地面(Y轴起始位置) if (journeyProgress <= 0f) { isReturning = true; journeyProgress = 0f; } } } else { // 返回起始点阶段:沿对称弧线返回 journeyProgress += Time.deltaTime * speed / (range * 2); journeyProgress = Mathf.Clamp01(journeyProgress); // 计算返回的弧线位置,与去程对称 float xOffset = range * 2 * (1 - journeyProgress); float yOffset = arcFactor * (1 - journeyProgress) * (1 + journeyProgress) * range; transform.position = startPosition + new Vector3(xOffset, yOffset, 0); // 判断是否回到起始点 if (journeyProgress >= 1f) { isReturning = false; isGoingUp = true; journeyProgress = 0f; } } } }
关键逻辑说明
- 用
journeyProgress(0-1范围)跟踪移动阶段,彻底避免浮点数直接比较的精度问题 - 将移动拆分为三个阶段:上升(X+、Y+)→下降(X+、Y-)→返回起始点(X-、Y先+后-),通过布尔变量切换阶段
- 用二次曲线模拟弧线运动,调整
arcFactor可以改变弧线的弯曲程度 - 所有阶段切换都用进度范围判断(
journeyProgress >=1或<=0),逻辑更稳定
内容的提问来源于stack exchange,提问作者BNK
相关产品推荐
相关产品推荐

