Unity中的制作贝塞尔弧线动画

Unity中的制作贝塞尔弧线动画Unity中的制作贝塞尔弧线动画 

1、场景创建空物体,添加组件“LineRenderer”,并添加材质到组件上


Unity中的制作贝塞尔弧线动画 
2、再写贝塞尔曲线代码,分了两种方式去表现:
a、DrawLine :这曲线动画利用差值方式运算的
 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
  
/// <summary>
/// 贝塞尔曲线
/// </summary>
public class DrawLine : MonoBehaviour
{
    public int SectionDetail = 100;//段数 
    public List<Transform> gameOjbet_tran = new List<Transform>();
    private List<Vector3> point = new List<Vector3>();
    private LineRenderer line;
    public GameObject ball;
    public float Speed = 1;
    public float Time1 = 2f;
    private float Timer = 0;
    private int i = 1;
    // Use this for initialization
    void Init()
    {
        line = GetComponent<LineRenderer>();    
        point = new List<Vector3>();
        for (int i = 0; i < SectionDetail; i++)
        {
            //第一球
            Vector3 pos1 = Vector3.Lerp(gameOjbet_tran[0].position, gameOjbet_tran[1].position, i / 100f);
            Vector3 pos2 = Vector3.Lerp(gameOjbet_tran[1].position, gameOjbet_tran[2].position, i / 100f);
            Vector3 pos3 = Vector3.Lerp(gameOjbet_tran[2].position, gameOjbet_tran[3].position, i / 100f);
            Vector3 pos4 = Vector3.Lerp(gameOjbet_tran[3].position, gameOjbet_tran[4].position, i / 100f);
  
            //第二球
            var pos1_0 = Vector3.Lerp(pos1, pos2, i / 100f);
            var pos1_1 = Vector3.Lerp(pos2, pos3, i / 100f);
            var pos1_2 = Vector3.Lerp(pos3, pos4, i / 100f);
  
            //第三球
            var pos2_0 = Vector3.Lerp(pos1_0, pos1_1, i / 100f);
            var pos2_1 = Vector3.Lerp(pos1_1, pos1_2, i / 100f);
  
            //第四球
            Vector3 find = Vector3.Lerp(pos2_0, pos2_1, i / 100f);
  
            point.Add(find);
        }
  
    }
  
     
    //void OnDrawGizmos()//画线
    //{
    //    //Init();
    //    Gizmos.color = Color.yellow;
    //    for (int i = 0; i < point.Count - 1; i++)
    //    {
    //        Gizmos.DrawLine(point[i], point[i + 1]);
  
    //    }
    //}
    //------------------------------------------------------------------------------  
    //使小球没曲线运动
    //这里不能直接在for里以Point使用差值运算,看不到小球运算效果
    //定义一个计时器,在相隔时间内进行一次差值运算。
    void Awake()
    {
        Init();
    }
  
    void Update()
    {
        
       
        Timer += Time.deltaTime;
        if (Timer > Time1)
        {
            Timer = 0;
            
            line.positionCount = i;
            line.SetPosition(i-1, point[i]);
            ball.transform.localPosition = Vector3.Lerp(point[i - 1], point[i], 1f);
            i++;
  
            if (i >= point.Count)
            {//结束
                i = 1;
            }
  
        }
  
    }
  
}


b、BesselLine 运用贝塞尔曲线公式实现的
 
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
  
public class BesselLine : MonoBehaviour {
  
    public List<Transform> gameOjbet_tran = new List<Transform>();
    private List<Vector3> point = new List<Vector3>();
    public GameObject ball;
    public int SectionDetail = 100;//段数
    private LineRenderer line;
    public Color StartColor = Color.yellow;
    public Color EndColor = Color.red;
    public float StartSize = 1.0f;//开始大小
    public float EndSize = 1.0f;//结束大小
    public float Speed = 1;
    public float Time1 = 2f;
    private float Timer = 0;  
    private int i = 1;
    void Start ()
    {
        line = GetComponent<LineRenderer>();
        for (int j = 0; j < SectionDetail; j++)
        {
            float node = (float)j / SectionDetail;
            point.Add(Cala(node, gameOjbet_tran[0].position, gameOjbet_tran[1].position, gameOjbet_tran[2].position, gameOjbet_tran[3].position));
        }
        
    }
// Update is called once per frame
void Update () {
  
        //大小
        line.startWidth = StartSize;
        line.endWidth = EndSize;
        //颜色
        line.startColor = StartColor;
        line.endColor = EndColor;
        if (SectionDetail < 2)
        {
            SectionDetail = 2;
        }
        Timer += Time.deltaTime;
            if (Timer > Time1)
            {
                Timer = 0;
  
                line.positionCount = i;
                line.SetPosition(i - 1, point[i]);
               // ball.transform.localPosition = Vector3.Lerp(point[i - 1], point[i], 1f);
                i++;
  
                if (i >= point.Count)
                {//结束
                    i = 1;
                }
  
            }
         
         
         
    }
    /// <summary>
    /// 线性的贝塞尔曲线
    /// </summary>
    /// <param name="t"></param>
    /// <param name="p0"></param>
    /// <param name="p1"></param>
    /// <returns></returns>
    Vector3 Cala(float t, Vector3 p0, Vector3 p1)
    {//P = P0+ t (P1 - P0),0 <= t <= 1
        return p0 + t*(p1 - p0);
    }
    /// <summary>
    /// 二次贝塞尔曲线动
    /// </summary>
    /// <param name="t"></param>
    /// <param name="p0"></param>
    /// <param name="p1"></param>
    /// <param name="p2"></param>
    /// <returns></returns>
    Vector3 Cala(float t, Vector3 p0, Vector3 p1, Vector3 p2)
    {//  B(t) = (1-t)^2P0+ 2(1-t)tP1 + t^2P2,   0 <= t <= 1
        float u = 1 - t;
        float tt = t * t;
        float uu = u * u;
        float uuu = uu * u;
        float ttt = tt * t;
  
        Vector3 p = uu * p0;
        p += 2 * u * t * p1;
        p +=  tt * p2;     
        return p;
    }
    /// <summary>
    /// 三次贝塞尔曲线
    /// </summary>
    /// <param name="t"></param>
    /// <param name="p0"></param>
    /// <param name="p1"></param>
    /// <param name="p2"></param>
    /// <param name="p3"></param>
    /// <returns></returns>
    Vector3 Cala(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
    {
        float u = 1 - t;
        float tt = t * t;
        float uu = u * u;
        float uuu = uu * u;
        float ttt = tt * t;
  
        Vector3 p = uuu * p0;
        p += 3 * uu * t * p1;
        p += 3 * u * tt * p2;
        p += ttt * p3;
  
        return p;
    }
    //void OnDrawGizmos()//画线
    //{
    //    //Init();
    //    Gizmos.color = Color.yellow;
    //    for (int i = 0; i < point.Count - 1; i++)
    //    {
    //        Gizmos.DrawLine(point[i], point[i + 1]);
  
    //    }
    //}
}

3、把上面其中一段代码添加到空物体上面(我这里就放了一个代码)


Unity中的制作贝塞尔弧线动画 

4、创建4个标志点,然后拖拽到代码“GameObject_Item”里面,运行效果