Unity 炉石传说---引导线的实现思路: “贝塞尔曲线Bezier“和“球形差值Slerp“的对比

"贝塞尔曲线Bezier"和"球形差值Slerp"的对比

鼓捣了一中午, 对比一下这2种弧形:

↓Slerp的图是这样的, 注意她的上边那个角, 那些角度是被平分的
Unity 炉石传说---引导线的实现思路: “贝塞尔曲线Bezier“和“球形差值Slerp“的对比_第1张图片
Unity 炉石传说---引导线的实现思路: “贝塞尔曲线Bezier“和“球形差值Slerp“的对比_第2张图片

↓贝塞尔的图是这样的, B站有视频讲的很好: https://www.bilibili.com/video/BV1X7411F744?p=11
Unity 炉石传说---引导线的实现思路: “贝塞尔曲线Bezier“和“球形差值Slerp“的对比_第3张图片
嗯, 显然贝塞尔更像是炉石的引导线, 球形差值可能更适合做巡航导弹之类的弧形轨迹

上代码, (只是提供一个思路, 代码懒的优化了)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//贝塞尔曲线: Bezier
public class Bezier : MonoBehaviour
{
     
    Vector3 posAdd = new Vector3(100, 0, 0);
    Vector3 zero = Vector3.zero;
    public int pointNum = 10;
    List<Transform> points = new List<Transform>();
    void Start()
    {
     
        for (int i = 0; i < pointNum; i++)
        {
     
            GameObject gameObject = new GameObject();
            gameObject.transform.parent = transform;
            points.Add(gameObject.transform);
        }
    }

    void Update()
    {
     
        Vector3 endPos = Input.mousePosition + posAdd;
        for (int i = 0; i < pointNum; i++)
        {
     
            Vector3 a = Vector3.Lerp(zero, endPos, 1f / pointNum * i);
            Vector3 b = Vector3.Lerp(endPos, Input.mousePosition, 1f / pointNum * (i + 1));
            Debug.DrawLine(a, b, Color.red);
            Vector3 point = Vector3.Lerp(a, b, 1f / pointNum * i);
            points[i].position = point;
        }
        for (int i = 0; i < points.Count - 1; i++)
        {
     
            Debug.DrawLine(points[i].position, points[i + 1].position);
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// 球形插值: Slerp
public class Slerp : MonoBehaviour
{
     
    Vector3 posAdd = new Vector3(0.01f, 0, 0);
    Vector3 zero = Vector3.zero;
    public int pointNum = 3;
    List<Transform> points = new List<Transform>();
    void Start()
    {
     
        for (int i = 0; i < pointNum + 1; i++)
        {
     
            GameObject gameObject = new GameObject();
            gameObject.transform.parent = transform;
            points.Add(gameObject.transform);
        }
    }

    void Update()
    {
     
        Vector3 mousePos = Input.mousePosition;
        for (int i = 0; i < pointNum + 1; i++)
        {
     
            Vector3 a = Vector3.Slerp(-mousePos, posAdd, 1f / pointNum * i) + mousePos;
            Debug.DrawLine(mousePos, a, Color.red);
            points[i].position = a;
        }
        for (int i = 0; i < points.Count - 1; i++)
        {
     
            Debug.DrawLine(points[i].position, points[i + 1].position);
        }
    }
}

//对了, 网上的Slerp一般是以坐标原点为平分点的(上图)(大肚子在下)
//我这个Slerp是反着写的(大肚子在上), 是以mousePos为起始点的, 可能不大好理解
//思路就是先做了个图b, 再移动到图a(下图)
//你要是学Slerp的话, 别拿我这个代码学, 可能会误导你
Unity 炉石传说---引导线的实现思路: “贝塞尔曲线Bezier“和“球形差值Slerp“的对比_第4张图片

你可能感兴趣的:(游戏开发,Unity,unity,unity3d)