Unity3D游戏开发之怪物AI - 推酷
Unity3D游戏开发之怪物AI
& & & & 在上一篇文章中,我们基本上实现了一个小地图的功能,今天呢,我们来实现怪物AI,所谓怪物AI就是指我们为怪物编写一定的算法,使其可以具备一定程度的智能化,以增强游戏的可玩性。在一般的RPG游戏中,怪物通常在一个游戏设定的范围内巡逻,当玩家进入怪物的警戒范围时,怪物就会由巡逻状态转变为攻击状态,向玩家进行攻击,那么,我们今天就来实现一个简单的怪物AI吧,下面我们一起来看代码:
using UnityE
using System.C
public class AI : MonoBehaviour {
//定义怪物的四种状态:站立、行走、奔跑、无所事事
public const int STATE_STAND=0;
public const int STATE_WALK=1;
public const int STATE_RUN=2;
//怪物当前状态
private int NowS
//游戏角色
public GameObject H
//怪物思考时间
public const int AI_THINK_TIME=2;
//触发怪物攻击的临界距离
public const int AI_ATTACT_DISTANCE=10;
//上一次思考的时间
private float LastThinkT
void Start ()
void Update ()
//当敌人与怪物间的距离小于攻击范围半径的时候
if(Vector3.Distance(transform.position,Hero.transform.position)&AI_ATTACT_DISTANCE)
//敌人开始奔跑
this.GetComponent&Animation&().Play(&run&);
//敌人进入奔跑状态
NowState=STATE_RUN;
//使敌人面向角色
transform.LookAt(Hero.transform);
//向玩家靠近
transform.Translate(Vector3.forward*Time.deltaTime * 5);
//当当前时间与上一次思考时间的差值大于怪物的思考时间时怪物开始思考
if(Time.time-LastThinkTime&AI_THINK_TIME)
//开始思考
LastThinkTime=Time.
//获取0-3之间的随机数字
int Rnd=Random.Range(0,2);
//根据随机数值为怪物赋予不同的状态行为
switch(Rnd)
//站立状态
this.GetComponent&Animation&().Play(&idle&);
NowState=STATE_STAND;
//行走状态
//使怪物旋转以完成行走动作
Quaternion mRotation=Quaternion.Euler(0,Random.Range(1,5)*90,0);
transform.rotation=Quaternion.Slerp(transform.rotation,mRotation,Time.deltaTime*1000);
//播放动画
this.GetComponent&Animation&().Play(&walk&);
//改变位置
transform.Translate(Vector3.forward*Time.deltaTime * 3);
NowState=STATE_WALK;
//奔跑状态
this.GetComponent&Animation&().Play(&run&);
transform.Translate(Vector3.forward*Time.deltaTime * 5);
NowState=STATE_RUN;
} & & & & & 在上面的代码中,能够触发怪物状态发生变化的有两个条件,第一,是玩家进入了怪物的警范围,此时怪物将面向玩家奔跑靠近;第二,当前时间与怪物上一次思考的时间之差大于怪物的思考时间,此时,怪物将随机作出反应。
& & & & & 好,下面我们回到游戏界面当中来。
& & & & 如图,博主事先从官方资源商店里下载了一个人物模型。在这个模型中,设计者已经为我们设计好了人物动画,我们将这个模型拖放到场景中,调整到合适的位置,并将人物默认动画设置为idle,下面我们将刚才写好的脚本拖放到此模型上,并设置Hero为我们的玩家对象,在这里我们使用了官方提供的第三人称角色控制器组件,最终实现的效果如下 :
& & & &可以看到,在不同的时刻,怪物可以自己执行不同的状态动作,当玩家靠近怪物的时候,会被敌人追击,这就是今天的内容啦,谢谢大家!
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致中国领先的IT技术网站
51CTO旗下网站
Unity3D基础教程:简单AI编写
开发环境:Window7、Unity3D
3.4.1、MB525defy、Android 2.2.1。将给大家介绍简单AI的编写。
作者:U3D来源:Unity3D教程手册| 08:49
&1.&& Unity简单AI编写
由于这次介绍的AI很简单,代码直接贴上,AI分成四个状态:思考,转身,移动,攻击,这里只是初步实现,所以想实现简单点的操作,就像自动范围内随机移动,锁敌攻击,超出距离复位,近距离察觉等。
Enemy_AI.js&&private&var&Regression&:&Vector3;&public&var&Player_Prefab&:&T&public&var&Enemy_State&:&S&public&var&Doing&:&boolean&=&true;&public&var&Range&:&float&=&4.0;&public&var&Bullet&:&T&public&var&Bullet_Prefab&:&T&&function&Start()&{&transform.localEulerAngles.y&=&Random.value&*&360;&Regression&=&transform.&}&&public&var&Thinking&:&boolean&=&true;&public&var&Thinking_Time&:&float&=&1.0;&private&var&relativePos&:&Vector3;&private&var&rotation&:&Q&public&var&Facing&:&boolean&=&false;&public&var&Facing_Time&:&float&&=&2.0;&public&var&Facing_Speed&:&float&=&2.0;&public&var&Moving&:&boolean&=&false;&public&var&Moving_Speed&:&float&=&0.5;&public&var&Moving_Time&:&float&=&4.0;&public&var&Moving_Back&:&boolean&=&false;&public&var&Attacking&:&boolean&=&false;&private&var&Bullet_DO&:&boolean&=&true;&public&var&Bullet_CD&:&float&=&0.2;&&private&var&R_Position&:&Vector3;&function&Update&()&{&if(Attacking)&{&Enemy_State&=&&Attacking&;&Facing&=&true;&Moving&=&true;&&Thinking&=&false;&var&dist2&=&Vector3.Distance(Regression,&transform.position);&if(dist2&&&20)&{&relativePos&=&Regression&-&transform.&rotation&=&Quaternion.LookRotation(relativePos);&Attacking&=&false;&Moving_Back&=&true;&}&}&if(!Moving_Back)&{&var&dist&=&Vector3.Distance(Player_Prefab.position,&transform.position);&if(dist&&&100)&{&Attacking&=&false;&return;&}&else&if(dist&&&5)&{&Attacking&=&true;&}&RayJudge();&}&transform.localEulerAngles.x&=&0;&transform.localEulerAngles.z&=&0;&if(Thinking&&&&!Attacking&&&&!Moving_Back)&{&Enemy_State&=&&Thinking&;&if(Doing)&{&StartCoroutine(Think(Thinking_Time));&Doing&=&false;&}&}&if(Facing)&{&Enemy_State&=&&Facing&;&if(Attacking)&{&relativePos&=&Player_Prefab.position&-&transform.&rotation&=&Quaternion.LookRotation(relativePos);&transform.rotation&=&Quaternion.Slerp(transform.rotation,&rotation,&Time.deltaTime&*&Facing_Speed&*&4);&}&else&if(Moving_Back)&{&transform.rotation&=&Quaternion.Slerp(transform.rotation,&rotation,&Time.deltaTime&*&Facing_Speed&*&4);&}&else&{&transform.rotation&=&Quaternion.Slerp(transform.rotation,&rotation,&Time.deltaTime&*&Facing_Speed);&if(Doing)&{&StartCoroutine(Face(Facing_Time));&Doing&=&false;&}&}&}&if(Moving)&{&Enemy_State&=&&Moving&;&if(Moving_Back)&{&transform.Translate(Vector3.forward&*&Time.deltaTime&*&Moving_Speed&*&6);&}&else&if(dist&&&2)&{&if(Attacking)&{&transform.Translate(Vector3.forward&*&Time.deltaTime&*&Moving_Speed&*&4);&}&else&{&transform.Translate(Vector3.forward&*&Time.deltaTime&*&Moving_Speed);&}&}&if(Doing&&&&!Attacking)&{&StartCoroutine(Move(Moving_Time));&Doing&=&false;&}&}&}&&function&RayJudge()&{&var&layerMask&=&1&&&&2;&layerMask&=&~layerM&var&hit&:&RaycastH&if(Physics.Raycast&(transform.position,&transform.TransformDirection(Vector3.forward),&hit,&20,layerMask))&{&var&distanceToForward&=&hit.&if(hit.transform.tag&==&&Player&)&{&Attacking&=&true;&if(Bullet_DO)&{&var&Create&=&Instantiate&(Bullet_Prefab,&Bullet.position,&Quaternion.identity);&Create.rigidbody.AddForce&(Bullet.forward&*&1000);&StartCoroutine(Wait(Bullet_CD));&Bullet_DO&=&false;&}&}&}&}&function&Wait(waitTime&:&float)&{&yield&WaitForSeconds&(waitTime);&Bullet_DO&=&true;&}&function&Move(waitTime&:&float)&{&print(&Move&);&if(Moving_Back)&{&yield&WaitForSeconds&(waitTime&*&0.4);&}&else&{&yield&WaitForSeconds&(waitTime&+&Random.value&*&2);&}&Thinking&=&true;&Moving_Back&=&false;&Moving&=&false;&Facing&=&false;&Doing&=&true;&}&function&Face(waitTime&:&float)&{&print(&Face&);&yield&WaitForSeconds&(waitTime&+&Random.value);&Facing&=&false;&Thinking&=&false;&Moving&=&true;&Doing&=&true;&}&function&Think(waitTime&:&float)&{&print(&Thinking&);&yield&WaitForSeconds&(waitTime&+&Random.value);&R_Position&=&Regression&+&Random.insideUnitSphere&*&R&R_Position.y&=&Regression.y;&relativePos&=&R_Position&-&transform.&rotation&=&Quaternion.LookRotation(relativePos);&Thinking&=&false;&Moving&=&false;&Facing&=&true;&Doing&=&true;&}&
工程截图(这里是9个拿***的敌人- - 蓝色为控制角色,WASD控制行动)
2.Unity学习过程中的一些细节分析
1.获取位置坐标:当你translate.position获取的不是物体在世界的坐标时可以试试translate. localRotation
2.改变旋转角度:这里多半是用translate.localRotation= Quaternion.Euler(x,y,z);
3.如何更改鼠标指针图片,这也是羽化以后可能遇到的问题,这里只能简单分析下,首先把鼠标默认指针隐藏掉Screen.showCursor=flase;再用个粒子或者图片代替,具体位置可以用Camera.main.ScreenToWorldPoint()和Input.mousePosition获得。但有个问题就产生了,UI会遮挡鼠标,鼠标图片用UI代替总感觉不妥。。。所以羽化还没想出解决方法- -
4.有关过场Loading的制作,一张图片还好说,换个Scene或者写个UI都能解决,动态Loading的是用Application.LoadLevelAsync可以达到效果,或者是预加载,具体可以看看羽化无缝地图研究博文里面的一个别墅例子。
5.也许有一天你也会遇到脚本用C#编写时遇到一些莫名其妙的错误,所以这里羽化建议动态脚本命令最好用js写。
原文链接:
【责任编辑: TEL:(010)】
大家都在看猜你喜欢
原创外电外电头条专题
24H热文一周话题本月最赞
讲师:1人学习过
讲师:35人学习过
讲师:0人学习过
精选博文论坛热帖下载排行
本书详细介绍脚本语言Groovy,首先介绍Groovy语言的基本特性,包括讨论Groovy方法、程序闭包、列表、映射以及对类和继承的支持,然后介绍如...
订阅51CTO邮刊unity&3D将一个物体成为自己的子物体
今天想要写一个怪物从右边走向左边然后举起宝物带走的效果,于是用C#写了个demo。
怪物的AI代码:
& public T//定义宝物
public bool iswork =//定义怪物是否取得宝物
void Update () {
//怪物初始行动 从右边走到左边,目标是宝物
if (iswork == false){
transform.position = Vector3.MoveTowards(transform.position,
target.position, Time.deltaTime * 3);
&//怪物获取宝物后往回走
transform.Translate(Vector3.right*3*Time.deltaTime);
void OnCollisionEnter(Collision collision) {
& &//将碰到的东西成为怪物的子物体
collision.transform.parent = this.
& &//将宝物的位置放置于怪物的头顶
collision.transform.localPosition = Vector3.
& &//状态改为已经获取宝物
iswork = !
-------------------以后再想子物体脱离的情况----------
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。