1. 程式人生 > >使用Unity畫一條平滑曲線(貝塞爾曲線)並使小球沿曲線運動

使用Unity畫一條平滑曲線(貝塞爾曲線)並使小球沿曲線運動

這裡直接講解在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; } } }