unity中 使用贝塞尔曲线飞行

使用贝塞尔曲线来实现对象在Unity中的飞行是一种常见的方法。这种方法可以用来制作各种平滑的移动路径,比如子弹轨迹、角色运动路径等。下面是介绍两种方法,展示如何在Unity中使用贝塞尔曲线让对象沿着一条路径飞行。 

第一种:在update里面动态改变坐标

1.创建贝塞尔曲线

using UnityEngine;

public static class BezierCurve
{
    // 二次贝塞尔曲线公式
    public static Vector3 GetQuadraticPoint(Vector3 p0, Vector3 p1, Vector3 p2, float t)
    {
        return Mathf.Pow(1 - t, 2) * p0 + 2 * (1 - t) * t * p1 + Mathf.Pow(t, 2) * p2;
    }

    // 三次贝塞尔曲线公式
    public static Vector3 GetCubicPoint(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
    {
        return Mathf.Pow(1 - t, 3) * p0 +
               3 * Mathf.Pow(1 - t, 2) * t * p1 +
               3 * (1 - t) * Mathf.Pow(t, 2) * p2 +
               Mathf.Pow(t, 3) * p3;
    }
}

2. 飞行脚本

我们编写一个脚本,将对象沿着贝塞尔曲线飞行。我们将允许用户设置起点、中间控制点和终点。

为了更好地调整和可视化贝塞尔曲线,编写一个Gizmos绘制函数,在编辑模式下显示整个曲线:

using UnityEngine;

[ExecuteInEditMode]
public class BezierFly : MonoBehaviour
{
    public Transform point0;
    public Transform point1;
    public Transform point2;
    public Transform point3;

    public float duration = 5f;
    private float timeElapsed;

    void Update()
    {
        if (!Application.isPlaying)
        {
            return;
        }

        timeElapsed += Time.deltaTime;
        float t = timeElapsed / duration;
        
        if (t > 1)
        {
            t = 1;
        }

        if (point3 != null)
        {
            transform.position = BezierCurve.GetCubicPoint(point0.position, point1.position, point2.position, point3.position, t);
        }
        else
        {
            transform.position = BezierCurve.GetQuadraticPoint(point0.position, point1.position, point2.position, t);
        }

        if (t >= 1)
        {
            // 结束逻辑
        }
    }

    void OnDrawGizmos()
    {
        Gizmos.color = Color.green;
        DrawBezierCurve(20);
    }

    private void DrawBezierCurve(int segments)
    {
        Vector3[] points;
        if (point3 != null)
        {
            points = new Vector3[segments + 1];
            for (int i = 0; i <= segments; i++)
            {
                float t = i / (float)segments;
                points[i] = BezierCurve.GetCubicPoint(point0.position, point1.position, point2.position, point3.position, t);
            }
        }
        else
        {
            points = new Vector3[segments + 1];
            for (int i = 0; i <= segments; i++)
            {
                float t = i / (float)segments;
                points[i] = BezierCurve.GetQuadraticPoint(point0.position, point1.position, point2.position, t);
            }
        }

        for (int i = 0; i < segments; i++)
        {
            Gizmos.DrawLine(points[i], points[i + 1]);
        }
    }
}

3.使用

a. 将这个脚本 BezierFly 附加到你希望沿曲线飞行的对象上。
b. 创建四个空物体作为贝塞尔曲线的控制点,并将它们的 Transform 分别赋值给 point0, point1, point2, 和可选的 point3。

第二种:结合 DoTween 来做飞行

对上面BezierFly进行微改即可

using UnityEngine;

[ExecuteInEditMode]
public class BezierFly : MonoBehaviour
{
    public Transform point0;
    public Transform point1;
    public Transform point2;
    public Transform point3;

    public float duration = 5f;

    void Start()
    {
        if (!Application.isPlaying) return;

        if (point3 != null)
        {
            DOVirtual.Float(0, 1, duration, t =>
            {
                transform.position = BezierCurve.GetCubicPoint(point0.position, point1.position, point2.position, point3.position, t);
            }).SetEase(Ease.Linear).OnComplete(OnComplete);
        }
        else
        {
            DOVirtual.Float(0, 1, duration, t =>
            {
                transform.position = BezierCurve.GetQuadraticPoint(point0.position, point1.position, point2.position, t);
            }).SetEase(Ease.Linear).OnComplete(OnComplete);
        }
    }

    private void OnComplete()
    {
        Debug.Log("Animation Complete");
    }

    void OnDrawGizmos()
    {
        Gizmos.color = Color.green;
        DrawBezierCurve(20);
    }

    private void DrawBezierCurve(int segments)
    {
        Vector3[] points;
        if (point3 != null)
        {
            points = new Vector3[segments + 1];
            for (int i = 0; i <= segments; i++)
            {
                float t = i / (float)segments;
                points[i] = BezierCurve.GetCubicPoint(point0.position, point1.position, point2.position, point3.position, t);
            }
        }
        else
        {
            points = new Vector3[segments + 1];
            for (int i = 0; i <= segments; i++)
            {
                float t = i / (float)segments;
                points[i] = BezierCurve.GetQuadraticPoint(point0.position, point1.position, point2.position, t);
            }
        }

        for (int i = 0; i < segments; i++)
        {
            Gizmos.DrawLine(points[i], points[i + 1]);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值