【Unity】【C#】《U3d人工智慧程式設計精粹》學習心得--------操縱行為--路徑跟隨
阿新 • • 發佈:2019-02-07
增加Steering的派生類
----SteeringForFollowPath類 路徑跟隨行為類
路徑跟隨行為類解讀:
行為準備:
①記錄全部路徑點,統計路徑點數。
②獲取下一個路徑點,並獲取當前是幾號路徑點。(用來標誌是否為終點)
準備是否到達目標點的條件:
①與路徑點的距離小於某個值,判斷為已經到達路點 arriveDistance sqrArriveDistance
通過判斷是否到達進行切換下一個路徑點
通過判斷是否是否到達最終點來判斷是否執行靠近行為或抵達行為
產生疑問:
Vector3.magnitude 與 Vector3.sqrMagnitude 的運算速度問題
在官方文件說用SqrMagnitude比較速度會比較快.
可是我在Unity中測試這兩個方法,花費時間還是相同的。
(沒空測試,這裡留白,一切還是按官方文件的)
測試程式碼如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Diagnostics; using System; public class TestSqr : MonoBehaviour { public Vector3 v3 = new Vector3(1, 2, 3); // Use this for initialization void Start () { Stopwatch sw = new Stopwatch(); sw.Start(); //for(int i = 0; i < 1000000000; i++) //{ // float sqr = v3.sqrMagnitude; //} sw.Stop(); TimeSpan time2 = sw.Elapsed; print(time2); Stopwatch sw2 = new Stopwatch(); sw2.Start(); //for (int i = 0; i < 1000000000; i++) //{ // float v = v3.magnitude; //} sw2.Stop(); TimeSpan time3 = sw.Elapsed; print(time3); } }
案例程式碼:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class SteeringForFollowPath : Steering { //節點陣列來表示路徑 public GameObject[] waypoints; //目標點 private Transform target; //當前路點 private int currentNode; //與路點的距離小於這個值時,認為已經到達,可以向下一個路點觸發 private float arriveDistance; private float sqrArriveDistance; //路點的數量 private int numberOfNodes; //操控力 private Vector3 force; //預期速度 private Vector3 desiredVelocity; private Vehicle m_vehicle; private float maxSpeed; private bool isPlanar; //當與目標小於這個距離時,開始減速 public float slowDownDistance; // Use this for initialization void Start () { numberOfNodes = waypoints.Length; m_vehicle = GetComponent<Vehicle>(); maxSpeed = m_vehicle.maxSpeed; isPlanar = m_vehicle.isPlanar; //設定當前路點為第0個路點 currentNode = 0; //設定當前路點為目標點 target = waypoints[currentNode].transform; arriveDistance = 1.0f; sqrArriveDistance = arriveDistance * arriveDistance; } public override Vector3 Force() { force = new Vector3(0, 0, 0); Vector3 dist = target.position - transform.position; if (isPlanar) dist.y = 0; //如果當前路點已經是最後一個路點了 if (currentNode == numberOfNodes - 1) { //如果與當前路點的距離大於減速距離 if (dist.magnitude > slowDownDistance) { //求出預期速度 desiredVelocity = dist.normalized * maxSpeed; //計算操控向量 force = desiredVelocity - m_vehicle.velocity; } else { //與當前路點距離小於減速距離,開始減速,計算操控向量 desiredVelocity = dist - m_vehicle.velocity; force = desiredVelocity - m_vehicle.velocity; } } else { //不是最後一個路點 if (dist.sqrMagnitude < sqrArriveDistance) { //如果與當前路點距離的平方小於到達距離的平方 //可以開始靠近下一個路點,將下一個路點設定為目標點 currentNode++; target = waypoints[currentNode].transform; } //計算預期速度和操控向量 desiredVelocity = dist.normalized * maxSpeed; force = desiredVelocity - m_vehicle.velocity; } return force; } }
參考書籍:《unity3d人工智慧程式設計精粹》 王洪源等著