Unity3D中如何通过脚本创建贝塞尔曲线并让物体沿其运动?
问题描述
我想通过脚本根据给定的点创建Bezier曲线,让物体沿该路径运动。使用Sebastian Lague的Path Creator插件尝试后,运行时物体会直接飞离场景,我的代码如下:
using PathCreation; using System.Collections; using System.Collections.Generic; using UnityEngine; public class PathCreator : MonoBehaviour { VertexPath path; Vector3[] points = new Vector3[5]; public EndOfPathInstruction end; public float speed; float dstTravelled; void Start() { points[0] = new Vector3(0f, 0f, 0f); points[1] = new Vector3(0f, 0f, 1f); points[2] = new Vector3(0f, 0f, 2f); points[3] = new Vector3(1f, 0f, 3f); points[4] = new Vector3(2f, 0f, 3f); path = GeneratePath(points, true); } void Update() { dstTravelled += speed * Time.deltaTime; transform.position = path.GetPointAtDistance(dstTravelled, end); transform.rotation = path.GetRotationAtDistance(dstTravelled, end); } VertexPath GeneratePath(Vector3[] points, bool closedPath) { BezierPath bezierPath = new BezierPath(points, closedPath, PathSpace.xyz); return new VertexPath(bezierPath, transform, 0.1f); } }
问题分析与修复
你的代码存在两个核心问题导致物体飞离:
- 类名冲突:自定义脚本的类名
PathCreator和插件自带的PathCreator类重名,导致命名空间混乱,路径生成逻辑异常。 - 空间变换错误:创建
VertexPath时传入了当前物体的transform,插件会将路径点转换为物体局部空间坐标,但你定义的是世界空间点,导致路径被错误偏移/缩放。
修正后的代码如下:
using PathCreation; using UnityEngine; // 修改类名避免和插件类冲突 public class PathMovementController : MonoBehaviour { VertexPath path; Vector3[] points = new Vector3[5]; // 给参数设置默认值,避免未赋值异常 public EndOfPathInstruction end = EndOfPathInstruction.Loop; public float speed = 2f; float dstTravelled; void Start() { points[0] = new Vector3(0f, 0f, 0f); points[1] = new Vector3(0f, 0f, 1f); points[2] = new Vector3(0f, 0f, 2f); points[3] = new Vector3(1f, 0f, 3f); points[4] = new Vector3(2f, 0f, 3f); path = GeneratePath(points, true); } void Update() { // 避免路径未生成时的空引用报错 if (path == null) return; dstTravelled += speed * Time.deltaTime; transform.position = path.GetPointAtDistance(dstTravelled, end); transform.rotation = path.GetRotationAtDistance(dstTravelled, end); } VertexPath GeneratePath(Vector3[] points, bool closedPath) { // 明确使用世界空间创建Bezier路径 BezierPath bezierPath = new BezierPath(points, closedPath, PathSpace.World); // 传入null让路径使用世界空间,不绑定到物体局部变换 return new VertexPath(bezierPath, null, 0.1f); } }
额外说明:
- 替换类名后,确保挂载脚本的物体上没有插件自带的
PathCreator组件,避免混淆。 - 如果需要路径跟随物体局部空间,可以将
PathSpace.World改为PathSpace.Local,同时把路径点调整为物体局部坐标。
内容的提问来源于stack exchange,提问作者Tom Lightfoot
相关产品推荐
相关产品推荐

