打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Unity3D研究院之游戏开发中的人工智能AI(三十八) | 雨松MOMO程序研究院

         很久没有写Unity3D相关的东西了,是因为这段时间我深陷一款IOS的软件开发中。不过以后我还是会回归Unity3D游戏开发的。什么语言都在用,生活与工作都挺给力的嚯嚯。今天还是打开了久违的Unity3D编辑器,那我就写点东西吧,今天我想说的是游戏中的人工智能。人工智能这个东西在游戏中是非常重要的,人工智能说简单了就是根据随机的数字让敌人执行一些动作或逻辑,说难了TA需要一个非常复杂的算法,本文我主要说说Unity3D中人工智能的脚本如何来编写。

        首先你应该搞清楚的一点AI脚本属于一个工具类脚本,工具类脚本的含义就是他应当是由策划人员来绑定游戏对象使用的。也就是说AI脚本程序员应当写的非常的灵活,策划人员可以通过修改脚本对外的变量数值接口就能控制其中的敌人AI。接着创建一个c#脚本AI.CS ,如下图所示,目前脚本对外留出枚举接口变量,策划人员在使用这条脚本时选择对应敌人类型即可。(注:这里仅仅是示例,细致的话还可以将很多敌人详细的信息写入,如:攻击速度、技能类型、移动速度、命中率、攻击百分比、等等,但是一定要让你的脚本写的比较灵活,策划人员在外面选择即可完成)因为目前是一个示例,所以我在这里只简单的区分的敌人类型。

 

 

下面时这段简单AI的脚本

AI.CS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
using UnityEngine;
using System.Collections;
//这里是枚举选择敌人类型
public enum EnemyType
{
Enemy0,
Enemy1
}
public class AI : MonoBehaviour {
//敌人类型枚举 有策划人员选择
public EnemyType enemyType = EnemyType.Enemy0;
//主角游戏对象
public GameObject player;
//敌人状态 普通状态 旋转状态 奔跑状态 追击主角状态 攻击主角状态
private const int EMEMY_NORMAL=0;
private const int EMEMY_ROTATION=1;
private const int EMEMY_RUN = 2;
private const int EMEMY_CHASE = 3;
private const int EMEMY_ATTACK = 4;
//记录当前敌人状态 根据不同类型 敌人播放不同动画
private int state;
//旋转状态,敌人自身旋转
private int rotation_state;
//记录敌人上一次思考时间
private float aiThankLastTime;
void Start ()
{
//初始话标志敌人状态 以及动画为循环播放
state = EMEMY_NORMAL;
this.animation.wrapMode = WrapMode.Loop;
}
void Update ()
{
//根据策划选择的敌人类型 这里面会进行不同的敌人AI
switch(enemyType)
{
case EnemyType.Enemy0:
updateEnemyType0();
break;
case EnemyType.Enemy1:
updateEnemyType1();
break;
}
}
//更新第一种敌人的AI
void updateEnemyType0()
{
//这个AI比较简单, 当主角与他的距离小于10米时,他将始终朝向这主角
if(Vector3.Distance(player.transform.position,this.transform.position) <= 10)
{
this.transform.LookAt(player.transform);
}
}
//更新第二种敌人的AI
void updateEnemyType1()
{
//判断敌人是否开始思考
if(isAIthank())
{
//敌人开始思考
AIthankEnemyState(3);
}else
{
//更新敌人状态
UpdateEmenyState();
}
}
int getRandom(int count)
{
return new System.Random().Next(count);
}
bool isAIthank()
{
//这里表示敌人每3秒进行一次思考
if(Time.time - aiThankLastTime >=3.0f)
{
aiThankLastTime = Time.time;
return true;
}
return false;
}
//敌人在这里进行思考
void AIthankEnemyState(int count)
{
//开始随机数字。
int d = getRandom(count);
switch(d)
{
case 0:
//设置敌人为站立状态
setEmemyState(EMEMY_NORMAL);
break;
case 1:
//设置敌人为旋转状态
setEmemyState(EMEMY_ROTATION);
break;
case 2:
//设置敌人为奔跑状态
setEmemyState(EMEMY_RUN);
break;
}
}
void setEmemyState(int newState)
{
if(state == newState)
return;
state = newState;
string animName = "Idle";
switch(state)
{
case EMEMY_NORMAL:
animName  =  "Idle";
break;
case EMEMY_RUN:
animName  =  "Run";
break;
case EMEMY_ROTATION:
animName  =  "Run";
//当敌人为旋转时, 开始随机旋转的角度系数
rotation_state = getRandom(4);
break;
case EMEMY_CHASE:
animName  =  "Run";
//当敌人进入追击状态时,将面朝主角方向奔跑
this.transform.LookAt(player.transform);
break;
case EMEMY_ATTACK:
animName  =  "Attack";
//当敌人进入攻击状态时,继续朝向主角开始攻击砍人动画
this.transform.LookAt(player.transform);
break;
}
//避免重复播放动画,这里进行判断
if(!this.animation.IsPlaying(animName))
{
//播放动画
this.animation.Play(animName);
}
}
//在这里更新敌人状态
void UpdateEmenyState()
{
//判断敌人与主角之间的距离
float distance = Vector3.Distance(player.transform.position,this.transform.position);
//当敌人与主角的距离小于10 敌人将开始面朝主角追击
if(distance <= 10)
{
//当敌人与主角的距离小与3 敌人将开始面朝主角攻击
if(distance <= 3)
{
setEmemyState(EMEMY_ATTACK);
}else
{
    //否则敌人将开始面朝主角追击
setEmemyState(EMEMY_CHASE);
}
}else
{
//敌人攻击主角时 主角迅速奔跑 当它们之间的距离再次大于10的时候 敌人将再次进入正常状态 开始思考
if(state == EMEMY_CHASE || state == EMEMY_ATTACK)
{
setEmemyState(EMEMY_NORMAL);
}
}
switch(state)
{
case EMEMY_ROTATION:
//旋转状态时 敌人开始旋转, 旋转时间为1秒 这样更加具有惯性
transform.rotation = Quaternion.Lerp (transform.rotation, Quaternion.Euler(0,rotation_state * 90,0),  Time.deltaTime * 1);
break;
case EMEMY_RUN:
//奔跑状态,敌人向前奔跑
transform.Translate(Vector3.forward *0.02f);
break;
case EMEMY_CHASE:
//追击状态 敌人向前开始追击
transform.Translate(Vector3.forward *0.02f);
break;
case EMEMY_ATTACK:
break;
}
}
}

 

 

如下图所示,我们在游戏世界中添加两个敌人,此时给敌人们都绑定上AI的脚本,编辑器中设置不同的敌人类型,敌人执行各自的生命周期,当你控制主角与接近敌人时,敌人开始追击你并且向你展开攻击。

 

 

         demo仅仅是一个示例,主要希望大家明白一个道理。在编写Unity游戏脚本时,一定要想想这条脚本和对象的生命周期,切记每一条脚本只管和自己有关的东西,和自己无关的东西一概不要管。不然你会发现你的脚本会越写越乱,下一篇文章我会写点我平时在Unity3D开发中时如何搭建架构的,希望大家多多讨论,互相学习。

下载地址:http://vdisk.weibo.com/s/hmJUs

MOMO与MO嫂提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!

1

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Unity 内的敌人AI 或者 有限状态机FSM实现AI
[Unity3D]预设Prefab与实例Instantiate的基本使用
[Unity3D]Unity3D游戏开发之自由视角下的角色控制
Unity实战篇 |制作一个跟随鼠标转向的 简易箭头指示标,包括 UI指向 和 3D指向标
Unity3d之Quaternion 学习与应用旋转四元数
[Unity3D插件系列] A pathfinding project
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服