本人是一名刚从事游戏行业不久的菜鸟,最近在看《Unity3D人工智能编程精萃》这本书,个人觉得浅显易懂,很适合入门。因此把本人的学习经历和心得纪录下来,还请各路大神多多指教。
1.视线追逐
视线法原理主要是让追击者沿着猎物的前进方向前进,让追击者永远面对着猎物当前的位置追击,当猎物站立不动时,追击者所走的路径是直的,但如果猎物移动时,路径就可能时弯弯曲曲的了。如下图所示:
下面就用Unity3D实现这部分的功能。
编程中主要涉及到3个类Vehicle类,AILocomotion类和Steering类。
Vehicle类实现
using UnityEngine;
using System.Collections;
public class Vehicle : MonoBehaviour {
// 操控行为类;
private Steering steerings;
// 物体能达到的最大速度;
public float maxSpeed = 10;
// 施加到物体上力的最大值
public float maxForce = 100;
protected float sqrMaxSpeed;
// 物体的质量
public float mass = 1;
// 速度
public Vector3 velocity;
// 转向速度
public float damping = 0.9f;
// 更新频率
public float computeInterval = 0.2f;
// 最后计算得到的控制力
private Vector3 steeringForce = new Vector3(0,0,0);
// 加速度
protected Vector3 acceleration;
// 计时器
private float timer = 0;
protected void Init()
{
steeringForce = new Vector3 (0, 0, 0);
sqrMaxSpeed = maxSpeed * maxSpeed;
timer = 0;
steerings = GetComponent<Steering> ();
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
timer += Time.deltaTime;
steeringForce = new Vector3 (0, 0, 0);
if (timer > computeInterval) {
steeringForce += steerings.Force () * steerings.weight;
steeringForce = Vector3.ClampMagnitude (steeringForce, maxForce);
acceleration = steeringForce / mass;
timer = 0;
}
}
}
AILocomotion类
<pre name="code" class="csharp">using UnityEngine;
using System.Collections;
public class AILocomotion : Vehicle {
private CharacterController controller;
private Rigidbody theRigidbody;
private Vector3 moveDistance;
public Animator anim;
private AnimatorStateInfo currentBaseState;
// Use this for initialization
void Start () {
controller = GetComponent<CharacterController> ();
theRigidbody = GetComponent<Rigidbody> ();
moveDistance = new Vector3 (0, 0, 0);
currentBaseState = anim.GetCurrentAnimatorStateInfo (0);
base.Init ();
}
void FixedUpdate()
{
velocity += acceleration * Time.fixedDeltaTime;
if (velocity.sqrMagnitude > sqrMaxSpeed)
velocity = velocity.normalized * maxSpeed;
moveDistance = velocity * Time.fixedDeltaTime;
velocity.y = 0;
moveDistance.y = 0;
if (controller != null)
controller.SimpleMove (velocity);
else if (theRigidbody == null || theRigidbody.isKinematic)
transform.position += moveDistance;
else
theRigidbody.MovePosition (theRigidbody.position + moveDistance);
if (velocity.sqrMagnitude > 0.00001) {
Vector3 newForward = Vector3.Slerp (transform.forward, velocity, damping * Time.deltaTime);
newForward.y = 0;
transform.forward = newForward;
}
anim.SetFloat("Forward", maxSpeed, 0.1f, Time.fixedDeltaTime);
}
}
Steering类
using UnityEngine;
using System.Collections;
public abstract class Steering : MonoBehaviour {
public float weight = 1;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public virtual Vector3 Force()
{
return new Vector3 (0, 0, 0);
}
}
(1)目标静止的情况
编写SteeringForSeek类
using UnityEngine;
using System.Collections;
public class SteeringForSeek : Steering {
public GameObject target;
private Vector3 desiredVelocity;
private Vehicle m_vehicle;
private float maxSpeed;
// Use this for initialization
void Start () {
m_vehicle = GetComponent<Vehicle> ();
maxSpeed = m_vehicle.maxSpeed;
}
public override Vector3 Force ()
{
desiredVelocity = (target.transform.position - transform.position).normalized * maxSpeed;
desiredVelocity.y = 0;
return (desiredVelocity - m_vehicle.velocity);
}
// Update is called once per frame
void Update () {
}
}
运行程序,为物体加上Character Controller组件、AILocomotion以及SteeringForSeek脚本。游戏运行如下:
程序中使用的人物模型是Standard Assets中的Ethan模型。
工程可以在这里下载到点击打开链接