Unity3D有提供人工智能AI空间,不过要专业版的才能使用,这里我们就来自己手动写自己的AI。博主写的很简单,请别嫌弃,能学到东西就好。
首先我们创建若干个Cube和Shape,分别作为敌人,和玩家。这里的蓝色代表有AI效果的敌人,而蓝色代表没有AI效果的敌人。
我们先来写怎么控制玩家代码如下。
void Update () {
if (Input.GetKey(KeyCode.W))
{
transform.Translate(new Vector3(0, 0, -0.4f));
}
if (Input.GetKey(KeyCode.S))
{
transform.Translate(new Vector3(0, 0, 0.4f));
}
if (Input.GetKey(KeyCode.A))
{
transform.Translate(new Vector3(-0.4f, 0, 0.0f));
}
if (Input.GetKey(KeyCode.D))
{
transform.Translate(new Vector3(0.4f, 0, 0.0f));
}
}
将脚本拖到shape上。
接着我们来写AI。
这里我们先介绍一些API.
Physics.Raycast 光线投射
Raycast (origin : Vector3, direction : Vector3, distance : float = Mathf.Infinity, layerMask : int = kDefaultRaycastLayers) : bool
Parameters参数
origin: 在世界坐标,射线的起始点。
direction: 射线的方向。
distance: 射线的长度。
layerMask: 只选定Layermask层内的碰撞器,其它层内碰撞器忽略。
当光线投射与任何碰撞器交叉时为真,否则为假。
在场景中投下可与所有碰撞器碰撞的一条光线。
Raycast可以放出一条射线,然后如果射线与物体碰撞后就会返回真,否则为假。origin为射线的发射起点,direction为方向,distance为射线长度。假设我们这样写
<span style="font-size:18px;">Vector3 fwd = transform.TransformDirection(Vector3.forward)
</span>
<span style="font-size:18px;">Physics.Raycast(transform.position, fwd, out hit, 10);</span>
这就代表着射线从本身开始向前延长10长度,只要某个物体碰到这条射线,Raycast就会返回真。
Debug.DrawRay 绘制射线
从start起始位置到dir位置和方向,绘制一条color颜色的线。
Vector3.Distance 距离。返回a和b之间的距离。 Vector3.Distance(a,b) 等同于(a-b).magnitude 。
RaycastHit:光线投射碰撞。用来获取从raycast函数中得到的信息反馈的结构。
<span style="font-size:18px;">
</span>
接下来看具体代码。我们创建2个脚本,自己取适当的名字。博主这里分别为asi,BlueAI.
再asi中代码如下
void Update()
{
<span style="white-space:pre"> </span>RaycastHit hit;// 用来获取从raycast函数中得到的信息反馈的结构,获取与射线碰撞的物体信息
Vector3 fwd = transform.TransformDirection(Vector3.forward);//射线发射方向
bool f = Physics.Raycast(transform.position, fwd, out hit, 10);//10是代表射线的长度,由transform.position出发向forward延伸10长度
if (f)
{
Debug.DrawLine(transform.position, hit.point);
hit.transform.Translate(new Vector3(0, 0, 0.3f));
}
}
将脚本给玩家。
接着在BlueAI里这样写。
private GameObject gameUser;
private float fx, fz;
private static int iFrameCount;
// Use this for initialization
void Start () {
gameUser = GameObject.Find("Prefab");
iFrameCount = 0;
}
// Update is called once per frame
void Update () {
iFrameCount++;
float dist=Vector3.Distance(transform.position,gameUser.transform.position);
print(dist);
if (iFrameCount>120)//代表120帧执行一次
{
if (dist<10)
{
float fMoverX = transform.position.x-gameUser.transform.position.x;
float fMoverZ = transform.position.z - gameUser.transform.position.z;
transform.Translate(new Vector3(-fMoverX, 0, -fMoverZ));
}
else
{
iFrameCount = 0;
int r = Random.Range(0, 3);
int k = Random.Range(-3, 4);
switch (r)
{
case 0: transform.Translate(new Vector3(k, 0, 0));
break;
case 1: transform.Translate(new Vector3(0, 0, k));
break;
default:
transform.Translate(new Vector3(k, 0, k));
break;
}
}
}
}
将脚本托给蓝色的Cube。
运行,你会发现蓝色的Cube会自己在上面乱跑。如果我们移动玩家,并且向前靠近里面的任何物体你就会发现物体会自己跑掉,并且画出一条白线。
当你接近蓝色Cube的时候你也会发现他会自己跑到你的位置。