作者:随风2502891175 | 来源:互联网 | 2024-12-03 17:44
为了实现物体沿贝塞尔曲线的平滑移动,我们首先创建了一个辅助工具类 BezierUtil
,用于计算给定三个点之间的所有贝塞尔曲线位置。
using UnityEngine;
public class BezierUtil {
///
/// 计算贝塞尔曲线上对应于参数 t 的点
///
/// 参数值
/// 起点
/// 控制点
/// 终点
/// 贝塞尔曲线上的点
private static Vector3 CalculateBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2) {
float u = 1 - t;
float tt = t * t;
float uu = u * u;
Vector3 p = uu * p0;
p += 2 * u * t * p1;
p += tt * p2;
return p;
}
///
/// 获取贝塞尔曲线上的点数组
///
/// 起点
/// 控制点
/// 终点
/// 分割段数
/// 贝塞尔曲线上的点数组
public static Vector3[] GetBezierPoints(Vector3 startPoint, Vector3 controlPoint, Vector3 endPoint, int segments) {
Vector3[] points = new Vector3[segments];
for (int i = 0; i float t = (float)i / segments;
points[i] = CalculateBezierPoint(t, startPoint, controlPoint, endPoint);
}
return points;
}
}
接下来,我们创建了一个名为 BezierMover
的类,用于控制物体沿贝塞尔曲线路径移动。
using UnityEngine;
public delegate void OnMoveComplete();
public class BezierMover : MonoBehaviour {
private int _segmentCount = 100;
private Vector3[] _pathPoints;
private float _moveSpeed = 10f;
private int _currentIndex = 0;
private Transform _targetObject;
private bool _isMoving = false;
public void Initialize(Vector3 start, Vector3 control, Vector3 end, Transform target, float speed, int segments = 100) {
_targetObject = target;
_moveSpeed = speed;
_segmentCount = segments;
_pathPoints = BezierUtil.GetBezierPoints(start, control, end, _segmentCount);
_isMoving = true;
}
public void Move(OnMoveComplete OnComplete= null) {
if (_pathPoints == null || _pathPoints.Length == 0) {
Debug.LogError("未初始化贝塞尔曲线路径点");
return;
}
if (_isMoving) {
if (Vector3.Distance(_targetObject.position, _pathPoints[_currentIndex]) <= 0.1f) {
_currentIndex++;
if (_currentIndex >= _segmentCount) {
_currentIndex = _segmentCount - 1;
if (onComplete != null) {
onComplete();
}
_isMoving = false;
}
} else {
_targetObject.position = Vector3.Lerp(_targetObject.position, _pathPoints[_currentIndex], _moveSpeed * Time.deltaTime);
}
}
}
}
最后,我们创建了一个测试脚本 TestBezier
来演示如何使用上述类。
using UnityEngine;
public class TestBezier : MonoBehaviour {
public Transform StartPosition;
public Transform ControlPosition;
public Transform EndPosition;
public Transform TargetObject;
public float MoveSpeed = 10f;
private BezierMover _mover;
private void Start() {
_mover = GetComponent();
_mover.Initialize(StartPosition.position, ControlPosition.position, EndPosition.position, TargetObject, MoveSpeed);
}
private void Update() {
_mover.Move(OnMoveComplete);
}
private void OnMoveComplete() {
Debug.Log("移动完成");
}
}
在Unity编辑器中,可以通过设置 TestBezier
组件的各个字段来指定起点、控制点、终点以及移动的目标对象。运行场景后,目标对象将沿贝塞尔曲线平滑移动到终点。