Unity3D研究院之游戏开发中的人工智能AI
很久没有写Unity3D相关的东西了,是因为这段时间我深陷一款IOS的软件开发中。不过以后我还是会回归Unity3D游戏开发的。什么语言都在用,生活与工作都挺给力的嚯嚯。今天还是打开了久违的Unity3D编辑器,那我就写点东西吧,今天我想说的是游戏中的人工智能。人工智能这个东西在游戏中是非常重要的,人工智能说简单了就是根据随机的数字让敌人执行一些动作或逻辑,说难了TA需要一个非常复杂的算法,本文我主要说说Unity3D中人工智能的脚本如何来编写。
首先你应该搞清楚的一点AI脚本属于一个工具类脚本,工具类脚本的含义就是他应当是由策划人员来绑定游戏对象使用的。也就是说AI脚本程序员应当写的非常的灵活,策划人员可以通过修改脚本对外的变量数值接口就能控制其中的敌人AI。接着创建一个c#脚本AI.CS ,如下图所示,目前脚本对外留出枚举接口变量,策划人员在使用这条脚本时选择对应敌人类型即可。(注:这里仅仅是示例,细致的话还可以将很多敌人详细的信息写入,如:攻击速度、技能类型、移动速度、命中率、攻击百分比、等等,但是一定要让你的脚本写的比较灵活,策划人员在外面选择即可完成)因为目前是一个示例,所以我在这里只简单的区分的敌人类型。
下面时这段简单AI的脚本
AI.CS
001
|
using UnityEngine;
|
002
|
using System.Collections;
|
003
|
004
|
//这里是枚举选择敌人类型
|
005
|
public enum EnemyType
|
006
|
{
|
007
|
Enemy0,
|
008
|
Enemy1
|
009
|
}
|
010
|
011
|
public class AI : MonoBehaviour {
|
012
|
013
|
//敌人类型枚举 有策划人员选择
|
014
|
public EnemyType enemyType = EnemyType.Enemy0;
|
015
|
016
|
//主角游戏对象
|
017
|
public GameObject player;
|
018
|
019
|
//敌人状态 普通状态 旋转状态 奔跑状态 追击主角状态 攻击主角状态
|
020
|
private const int EMEMY_NORMAL=0;
|
021
|
private const int EMEMY_ROTATION=1;
|
022
|
private const int EMEMY_RUN = 2;
|
023
|
private const int EMEMY_CHASE = 3;
|
024
|
private const int EMEMY_ATTACK = 4;
|
025
|
026
|
//记录当前敌人状态 根据不同类型 敌人播放不同动画
|
027
|
private int state;
|
028
|
//旋转状态,敌人自身旋转
|
029
|
private int rotation_state;
|
030
|
//记录敌人上一次思考时间
|
031
|
private float aiThankLastTime;
|
032
|
033
|
void Start ()
|
034
|
{
|
035
|
//初始话标志敌人状态 以及动画为循环播放
|
036
|
state = EMEMY_NORMAL;
|
037
|
this .animation.wrapMode = WrapMode.Loop;
|
038
|
}
|
039
|
040
|
void Update ()
|
041
|
{
|
042
|
//根据策划选择的敌人类型 这里面会进行不同的敌人AI
|
043
|
switch (enemyType)
|
044
|
{
|
045
|
case EnemyType.Enemy0:
|
046
|
updateEnemyType0();
|
047
|
break ;
|
048
|
case EnemyType.Enemy1:
|
049
|
updateEnemyType1();
|
050
|
break ;
|
051
|
}
|
052
|
}
|
053
|
054
|
//更新第一种敌人的AI
|
055
|
void updateEnemyType0()
|
056
|
{
|
057
|
//这个AI比较简单, 当主角与他的距离小于10米时,他将始终朝向这主角
|
058
|
if (Vector3.Distance(player.transform.position, this .transform.position) <= 10)
|
059
|
{
|
060
|
this .transform.LookAt(player.transform);
|
061
|
}
|
062
|
}
|
063
|
064
|
//更新第二种敌人的AI
|
065
|
void updateEnemyType1()
|
066
|
{
|
067
|
068
|
//判断敌人是否开始思考
|
069
|
if (isAIthank())
|
070
|
{
|
071
|
//敌人开始思考
|
072
|
AIthankEnemyState(3);
|
073
|
} else
|
074
|
{
|
075
|
//更新敌人状态
|
076
|
UpdateEmenyState();
|
077
|
}
|
078
|
}
|
079
|
080
|
int getRandom( int count)
|
081
|
{
|
082
|
083
|
return new System.Random().Next(count);
|
084
|
085
|
}
|
086
|
087
|
bool isAIthank()
|
088
|
{
|
089
|
//这里表示敌人每3秒进行一次思考
|
090
|
if (Time.time - aiThankLastTime >=3.0f)
|
091
|
{
|
092
|
aiThankLastTime = Time.time;
|
093
|
return true ;
|
094
|
095
|
}
|
096
|
return false ;
|
097
|
}
|
098
|
099
|
//敌人在这里进行思考
|
100
|
void AIthankEnemyState( int count)
|
101
|
{
|
102
|
//开始随机数字。
|
103
|
int d = getRandom(count);
|
104
|
105
|
switch (d)
|
106
|
{
|
107
|
case 0:
|
108
|
//设置敌人为站立状态
|
109
|
setEmemyState(EMEMY_NORMAL);
|
110
|
break ;
|
111
|
case 1:
|
112
|
//设置敌人为旋转状态
|
113
|
setEmemyState(EMEMY_ROTATION);
|
114
|
break ;
|
115
|
case 2:
|
116
|
//设置敌人为奔跑状态
|
117
|
setEmemyState(EMEMY_RUN);
|
118
|
break ;
|
119
|
}
|
120
|
121
|
}
|
122
|
123
|
void setEmemyState( int newState)
|
124
|
{
|
125
|
if (state == newState)
|
126
|
return ;
|
127
|
state = newState;
|
128
|
129
|
string animName = "Idle" ;
|
130
|
switch (state)
|
131
|
{
|
132
|
case EMEMY_NORMAL:
|
133
|
animName = "Idle" ;
|
134
|
break ;
|
135
|
case EMEMY_RUN:
|
136
|
animName = "Run" ;
|
137
|
break ;
|
138
|
case EMEMY_ROTATION:
|
139
|
animName = "Run" ;
|
140
|
//当敌人为旋转时, 开始随机旋转的角度系数
|
141
|
rotation_state = getRandom(4);
|
142
|
break ;
|
143
|
case EMEMY_CHASE:
|
144
|
animName = "Run" ;
|
145
|
//当敌人进入追击状态时,将面朝主角方向奔跑
|
146
|
this .transform.LookAt(player.transform);
|
147
|
break ;
|
148
|
case EMEMY_ATTACK:
|
149
|
animName = "Attack" ;
|
150
|
//当敌人进入攻击状态时,继续朝向主角开始攻击砍人动画
|
151
|
this .transform.LookAt(player.transform);
|
152
|
break ;
|
153
|
}
|
154
|
155
|
//避免重复播放动画,这里进行判断
|
156
|
if (! this .animation.IsPlaying(animName))
|
157
|
{
|
158
|
//播放动画
|
159
|
this .animation.Play(animName);
|
160
|
}
|
161
|
162
|
}
|
163
|
164
|
//在这里更新敌人状态
|
165
|
void UpdateEmenyState()
|
166
|
{
|
167
|
//判断敌人与主角之间的距离
|
168
|
float distance = Vector3.Distance(player.transform.position, this .transform.position);
|
169
|
//当敌人与主角的距离小于10 敌人将开始面朝主角追击
|
170
|
if (distance <= 10)
|
171
|
{
|
172
|
//当敌人与主角的距离小与3 敌人将开始面朝主角攻击
|
173
|
if (distance <= 3)
|
174
|
{
|
175
|
setEmemyState(EMEMY_ATTACK);
|
176
|
} else
|
177
|
{
|
178
|
//否则敌人将开始面朝主角追击
|
179
|
setEmemyState(EMEMY_CHASE);
|
180
|
}
|
181
|
182
|
} else
|
183
|
{
|
184
|
//敌人攻击主角时 主角迅速奔跑 当它们之间的距离再次大于10的时候 敌人将再次进入正常状态 开始思考
|
185
|
if (state == EMEMY_CHASE || state == EMEMY_ATTACK)
|
186
|
{
|
187
|
setEmemyState(EMEMY_NORMAL);
|
188
|
}
|
189
|
190
|
}
|
191
|
192
|
switch (state)
|
193
|
{
|
194
|
case EMEMY_ROTATION:
|
195
|
//旋转状态时 敌人开始旋转, 旋转时间为1秒 这样更加具有惯性
|
196
|
transform.rotation = Quaternion.Lerp (transform.rotation, Quaternion.Euler(0,rotation_state * 90,0), Time.deltaTime * 1);
|
197
|
break ;
|
198
|
case EMEMY_RUN:
|
199
|
//奔跑状态,敌人向前奔跑
|
200
|
transform.Translate(Vector3.forward *0.02f);
|
201
|
break ;
|
202
|
case EMEMY_CHASE:
|
203
|
//追击状态 敌人向前开始追击
|
204
|
transform.Translate(Vector3.forward *0.02f);
|
205
|
break ;
|
206
|
case EMEMY_ATTACK:
|
207
|
208
|
break ;
|
209
|
}
|
210
|
211
|
}
|
212
|
}
|
如下图所示,我们在游戏世界中添加两个敌人,此时给敌人们都绑定上AI的脚本,编辑器中设置不同的敌人类型,敌人执行各自的生命周期,当你控制主角与接近敌人时,敌人开始追击你并且向你展开攻击。
demo仅仅是一个示例,主要希望大家明白一个道理。在编写Unity游戏脚本时,一定要想想这条脚本和对象的生命周期,切记每一条脚本只管和自己有关的东西,和自己无关的东西一概不要管。不然你会发现你的脚本会越写越乱,下一篇文章我会写点我平时在Unity3D开发中时如何搭建架构的,希望大家多多讨论,互相学习。
下载地址:http://vdisk.weibo.com/s/hmJUs
Unity3D研究院之游戏开发中的人工智能AI相关推荐
- Unity3D游戏开发中的人工智能AI 简单实例
今天我想说的是游戏中的人工智能.人工智能这个东西在游戏中是非常重要的,人工智能说简单了就是根据随机的数字让敌人执行一些动作或逻辑,说难了TA需要一个非常复杂的算法,本文我主要说说Unity ...
- 游戏开发中的人工智能(五):以势函数实现移动
接上文: 游戏开发中的人工智能(四):群聚 本文内容:靠势能移动在游戏 AI 程序中还算相当新颖.这个方法的最优越的地方在于可以同时处理追逐.闪躲.成群结队和避免碰撞等行为.我们专门研究的这个势函数叫 ...
- 游戏开发中的人工智能(十三):不确定状态下的决策:贝叶斯技术
接上文 游戏开发中的人工智能(十二):概率概论 本文内容:贝叶斯技术是概率技术,本章解释如何运用,以便在游戏中做决策并适应游戏. 不确定状态下的决策:贝叶斯技术 本章要介绍贝叶斯推论和贝叶斯网络,教你 ...
- 游戏开发中的人工智能(十四):神经网络
接上文 游戏开发中的人工智能(十三):不确定状态下的决策:贝叶斯技术 本文内容:"神经网络"技术让游戏具有学习和适应的能力.事实上,从决策判断到预测玩家的行为,都可以应用.我们会详 ...
- 游戏开发中的人工智能(六):基本路径寻找及航点应用
接上文:游戏开发中的人工智能(五):以势函数实现移动 本文内容:游戏开发人员使用很多技术在游戏环境中寻找路径.本章要谈几种方法,包括航点应用. 基本路径寻找及航点应用 寻找路径的问题有很多不同类型.没 ...
- 游戏开发中的人工智能(二):追逐和闪躲
接上文 游戏开发中的人工智能(一):游戏人工智能简介 本文内容:讨论基本的追逐和闪躲技术,以及进级的拦截技术.我们也谈及这些技术在砖块环境和连续环境中的变化. 追逐和闪躲 本章的焦点是追逐和闪躲,这是 ...
- 游戏开发中的人工智能(十一):规则式 AI
接上文 游戏开发中的人工智能(十):模糊逻辑 本文内容:技术上而言,有限状态机和模糊逻辑都落在基于规则的方法这个大伞之下.本章将谈这些方法,以及其他变化的方法. 规则式 AI 本章我们要研讨基于规则的 ...
- 游戏开发中的人工智能(一):游戏人工智能简介
本系列文章对<游戏开发中的人工智能>David M.Bourg / Glenn Seemann 一书进行解读. 这本书谈了很多游戏软件 AI 的主题,内容深度适合初涉开发人员.所以,无论你 ...
- 游戏开发中的人工智能
前言 今天非常开心,观看cocos官方直播居然在几千人中中奖,可以买彩票了. 言归正传,所谓的人工智能,也就是大家常说的AI(Artificial Intelligence).一说到AI可能就会让人觉 ...
最新文章
- 如何处理Entity Framework中的DbUpdateConcurrencyException异常
- TortoiseSVN搭载
- 学长毕业日记 :本科毕业论文写成博士论文的神操作20170316
- layui upload 后台获取不到值
- Mybatis源码研究5:数据源的实现
- 鹤岗一中2021年高考成绩查询,2021鹤岗市地区高考成绩排名查询,鹤岗市高考各高中成绩喜报榜单...
- pytorch 创建神经网络
- php字长是什么,计算机的字长是指什么
- 没有UITableViewController的UIRefreshControl
- python实现递归和非递归求两个数最大公约数、最小公倍数
- Windows字体拯救计划(雅黑+monaco+mactype)
- java,Hash冲突及解决办法
- mapinfo professional 学习资料
- 腾讯云网站域名备案帮助说明文档
- 蚂蚁区块链BaaS平台应用开发指南(四):JavaSDK的接入
- 【Shader特效10】体积雾特效的使用
- tplink控制上网设备_tplink路由器如何控制小孩的使用上网时间
- 智能网联汽车激光雷达工作原理、性能比较与安全性分析
- CSS3健身男孩平板卧推js特效
- 将Spring Boot应用程序注册成为系统服务
热门文章
- caxa实体设计2020教程|caxa3d实体设计2020安装教程
- 解决AttributeError: module ‘win32com.gen_py.00020813-0000-0000-C000-000000000046x0x1x9‘ has no attribu
- 漏洞复现-electron RCE命令执行CVE-2018-1000006
- sw2urdf使用探索
- 推荐个NodeJS的入门教程 — Node入门/nodebeginner
- Quectel BC28-CNV 多频段、高性能、低功耗 LTE Cat NB2 无线通信模块[移远通信]
- C语言中%d等的作用(格式字符)
- 模仿360安全卫士项目笔记9
- 档案馆中温湿度要求的数据 资料分享
- 高通:推出全新5G基站