使用Unity畫一條平滑曲線(貝塞爾曲線)並使小球沿曲線運動
阿新 • • 發佈:2019-02-10
這裡直接講解在U3D中的實現方式
直接拿三階貝塞爾曲線為例,首先觀察下圖:
從圖中可以看出,只有四個點是保持不變的,分別是P0,P1,P2,P3,這四個點兩兩相連得到三個線段
(1)在上四點構成的三個線段中,p0-p1上有到一個點,p1-p2上有到一個點,p2-p3上有到一個點,這三個點分別這在上三個線段做差值運算。現在以上三個點分別取名為A1,A2,A3,這三點兩兩相連得到綠色線
(2)繼續觀察可看出,上面得到的三個點構成二個線段,A1-A2上得到一點,A2-A2上有一個點。這兩點分別在這二個線段上做差值運算,現將這兩點分別為B1,B2。這兩點相連得到藍色線
(3)再觀察藍色線上可看出,有一點在這做差值運算,最終軌跡畫成曲線。
//實現程式碼如下:(這裡我比上面多添加了一個點,最外層有5個點,依次4個,3個,2個)
//並添加了一個小球,沒沿曲線上運動
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class DrawLine : MonoBehaviour {
public List<Transform> gameOjbet_tran = new List<Transform>();
private List<Vector3> point = new List<Vector3>();
public GameObject ball;
public float Speed = 1;
public float Time1 = 2f;
private float Timer = 0;
int i = 1;
// Use this for initialization
void Init()
{
point = new List<Vector3>();
for (int i = 0; i < 200; 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;
ball.transform.localPosition = Vector3.Lerp(point[i - 1], point[i], 1f);
i++;
if (i >= point.Count) i = 1;
}
}
}