1. 程式人生 > >【Unity】【C#】《U3d人工智慧程式設計精粹》學習心得--------操縱行為--路徑跟隨

【Unity】【C#】《U3d人工智慧程式設計精粹》學習心得--------操縱行為--路徑跟隨

增加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人工智慧程式設計精粹》 王洪源等著