You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
    }
}

额外说明:

  1. 替换类名后,确保挂载脚本的物体上没有插件自带的PathCreator组件,避免混淆。
  2. 如果需要路径跟随物体局部空间,可以将PathSpace.World改为PathSpace.Local,同时把路径点调整为物体局部坐标。

内容的提问来源于stack exchange,提问作者Tom Lightfoot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 07:17:31