很久没有写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相关推荐

  1. Unity3D游戏开发中的人工智能AI 简单实例

          今天我想说的是游戏中的人工智能.人工智能这个东西在游戏中是非常重要的,人工智能说简单了就是根据随机的数字让敌人执行一些动作或逻辑,说难了TA需要一个非常复杂的算法,本文我主要说说Unity ...

  2. 游戏开发中的人工智能(五):以势函数实现移动

    接上文: 游戏开发中的人工智能(四):群聚 本文内容:靠势能移动在游戏 AI 程序中还算相当新颖.这个方法的最优越的地方在于可以同时处理追逐.闪躲.成群结队和避免碰撞等行为.我们专门研究的这个势函数叫 ...

  3. 游戏开发中的人工智能(十三):不确定状态下的决策:贝叶斯技术

    接上文 游戏开发中的人工智能(十二):概率概论 本文内容:贝叶斯技术是概率技术,本章解释如何运用,以便在游戏中做决策并适应游戏. 不确定状态下的决策:贝叶斯技术 本章要介绍贝叶斯推论和贝叶斯网络,教你 ...

  4. 游戏开发中的人工智能(十四):神经网络

    接上文 游戏开发中的人工智能(十三):不确定状态下的决策:贝叶斯技术 本文内容:"神经网络"技术让游戏具有学习和适应的能力.事实上,从决策判断到预测玩家的行为,都可以应用.我们会详 ...

  5. 游戏开发中的人工智能(六):基本路径寻找及航点应用

    接上文:游戏开发中的人工智能(五):以势函数实现移动 本文内容:游戏开发人员使用很多技术在游戏环境中寻找路径.本章要谈几种方法,包括航点应用. 基本路径寻找及航点应用 寻找路径的问题有很多不同类型.没 ...

  6. 游戏开发中的人工智能(二):追逐和闪躲

    接上文 游戏开发中的人工智能(一):游戏人工智能简介 本文内容:讨论基本的追逐和闪躲技术,以及进级的拦截技术.我们也谈及这些技术在砖块环境和连续环境中的变化. 追逐和闪躲 本章的焦点是追逐和闪躲,这是 ...

  7. 游戏开发中的人工智能(十一):规则式 AI

    接上文 游戏开发中的人工智能(十):模糊逻辑 本文内容:技术上而言,有限状态机和模糊逻辑都落在基于规则的方法这个大伞之下.本章将谈这些方法,以及其他变化的方法. 规则式 AI 本章我们要研讨基于规则的 ...

  8. 游戏开发中的人工智能(一):游戏人工智能简介

    本系列文章对<游戏开发中的人工智能>David M.Bourg / Glenn Seemann 一书进行解读. 这本书谈了很多游戏软件 AI 的主题,内容深度适合初涉开发人员.所以,无论你 ...

  9. 游戏开发中的人工智能

    前言 今天非常开心,观看cocos官方直播居然在几千人中中奖,可以买彩票了. 言归正传,所谓的人工智能,也就是大家常说的AI(Artificial Intelligence).一说到AI可能就会让人觉 ...

最新文章

  1. 如何处理Entity Framework中的DbUpdateConcurrencyException异常
  2. TortoiseSVN搭载
  3. 学长毕业日记 :本科毕业论文写成博士论文的神操作20170316
  4. layui upload 后台获取不到值
  5. Mybatis源码研究5:数据源的实现
  6. 鹤岗一中2021年高考成绩查询,2021鹤岗市地区高考成绩排名查询,鹤岗市高考各高中成绩喜报榜单...
  7. pytorch 创建神经网络
  8. php字长是什么,计算机的字长是指什么
  9. 没有UITableViewController的UIRefreshControl
  10. python实现递归和非递归求两个数最大公约数、最小公倍数
  11. Windows字体拯救计划(雅黑+monaco+mactype)
  12. java,Hash冲突及解决办法
  13. mapinfo professional 学习资料
  14. 腾讯云网站域名备案帮助说明文档
  15. 蚂蚁区块链BaaS平台应用开发指南(四):JavaSDK的接入
  16. 【Shader特效10】体积雾特效的使用
  17. tplink控制上网设备_tplink路由器如何控制小孩的使用上网时间
  18. 智能网联汽车激光雷达工作原理、性能比较与安全性分析
  19. CSS3健身男孩平板卧推js特效
  20. 将Spring Boot应用程序注册成为系统服务

热门文章

  1. caxa实体设计2020教程|caxa3d实体设计2020安装教程
  2. 解决AttributeError: module ‘win32com.gen_py.00020813-0000-0000-C000-000000000046x0x1x9‘ has no attribu
  3. 漏洞复现-electron RCE命令执行CVE-2018-1000006
  4. sw2urdf使用探索
  5. 推荐个NodeJS的入门教程 — Node入门/nodebeginner
  6. Quectel BC28-CNV 多频段、高性能、低功耗 LTE Cat NB2 无线通信模块[移远通信]
  7. C语言中%d等的作用(格式字符)
  8. 模仿360安全卫士项目笔记9
  9. 档案馆中温湿度要求的数据 资料分享
  10. 高通:推出全新5G基站