-----------------------------------------------------------------
Steering 類別(功能: 各種行為)
-----------------------------------------------------------------
using UnityEngine;
using System.Collections;
public abstract class Steering : MonoBehaviour {
public float weight = 1; // 表示每個控制力的權數
// 計算操控力的方法,由衍生類別實現
public virtual Vector3 Force() {
return new Vector3(0,0,0);
}
}
-----------------------------------------------------------------
Vehicle 類別(功能: AI 設定)
-----------------------------------------------------------------
using UnityEngine;
using System.Collections;
public class Vehicle : MonoBehaviour {
private Steering[] steerings; // AI 操作行為類表
public float maxSpeed = 10; // AI 最大速度
public float maxForce = 100; // AI 最大力量
protected float sqrMaxSpeed; // 最大平方速度
public float mass = 1; // AI 品質
public Vector3 velocity; // AI速度
public float damping = 0.9f; // 轉制轉向時的速度
public float computeInterval = 0.2f; // 操作力的計算時間
public bool isPlanar = true; // 是否在二維平面上,如果是計算兩個遊戲物件的距離
private Vector3 steeringForce; // 計算獲得操作力
protected Vector3 acceleration; // AI 加速度
private float timer; // 計時器
protected void Start() {
steeringForce = new Vector3(0,0,0);
sqrMaxSpeed = maxSpeed * maxSpeed;
timer = 0;
// 獲得AI包含操作行為列表
steerings = GetComponents<Steering>();
}
void Update() {
timer += Time.deltaTime;
steeringForce = new Vector3(0, 0, 0);
// 如果距離上次計算控制力的時間大於computeInterval
if (timer > computeInterval) {
// 操作行為列表中的所有控制行為對應的操作力進行代權數的求和
foreach (Steering s in steerings) {
if (s.enabled)
steeringForce += s.Force() * s.weight;
}
// 操作力不大於maxForce
steeringForce = Vector3.ClampMagnitude(steeringForce, maxForce);
// 加速度 = 力 除 品質
acceleration = steeringForce / mass;
timer = 0;
}
}
}
-----------------------------------------------------------------
AILocomotion 類別(功能: 移動)
-----------------------------------------------------------------
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CharacterController))]
public class AILocomotion : Vehicle {
private CharacterController controller; // AI 角色控制器
private Rigidbody theRigidbody; // AI Rigidbody
private Vector3 moveDiestance; // AI 每次移動距離
void Start() {
controller = GetComponent<CharacterController>();
theRigidbody = GetComponent<Rigidbody>();
moveDiestance = new Vector3(0, 0, 0);
base.Start();
}
void FixedUpdate() {
// 計算數度
velocity += acceleration * Time.fixedDeltaTime;
// 限制速度,要低於最大速度
if (velocity.sqrMagnitude > sqrMaxSpeed)
velocity = velocity.normalized * maxSpeed;
// 計算AI移動距離
moveDiestance = velocity * Time.fixedDeltaTime;
// 如果AI平面上,Y將為0
if (isPlanar) {
velocity.y = 0;
moveDiestance.y = 0;
}
// 如果 AI 增加角色控制器,那麼利用角色控制器使其移動
if (controller != null)
controller.SimpleMove(velocity);
// AI角色沒有Rigidbody || 但是要由動力學的方式控制它的運動
else if (theRigidbody.Equals(null) || theRigidbody.isKinematic)
transform.position += moveDiestance;
// 用Rigidbody控制AI角色的運動
else
theRigidbody.MovePosition(theRigidbody.position + moveDiestance);
//更新朝向,如果速度大於一個設定值(為了防止抖動)
if (velocity.sqrMagnitude > 0.00001f) {
// 透過目前朝向與速度方向的內插,計算新的朝向
Vector3 newForward = Vector3.Slerp(transform.forward, velocity, damping * Time.deltaTime);
// 將y設定為0
if (isPlanar) {
newForward.y = 0;
}
}
}
}
-----------------------------------------------------------------
結果圖:
-----------------------------------------------------------------