ai unity3d
2013-05-13 16:49:31 sgnyyy 阅读数 1097
http://blog.csdn.net/libeifs/article/details/6820754
2014-05-22 11:03:32 u010293396 阅读数 2531

大家好,欢迎大家关注由我为大家带来的Unity3D游戏开发系列文章,我的博客地址为:http://blog.csdn.net/qinyuanpei。

       在上一篇文章中,我们基本上实现了一个小地图的功能,今天呢,我们来实现怪物AI,所谓怪物AI就是指我们为怪物编写一定的算法,使其可以具备一定程度的智能化,以增强游戏的可玩性。在一般的RPG游戏中,怪物通常在一个游戏设定的范围内巡逻,当玩家进入怪物的警戒范围时,怪物就会由巡逻状态转变为攻击状态,向玩家进行攻击,那么,我们今天就来实现一个简单的怪物AI吧,下面我们一起来看代码:

  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class AI : MonoBehaviour {  
  5.   
  6.     //定义怪物的四种状态:站立、行走、奔跑、无所事事  
  7.     public const int STATE_STAND=0;  
  8.     public const int STATE_WALK=1;  
  9.     public const int STATE_RUN=2;  
  10.       
  11.     //怪物当前状态  
  12.     private int NowState;  
  13.     //游戏角色  
  14.     public GameObject Hero;  
  15.     //怪物思考时间  
  16.     public const int AI_THINK_TIME=2;  
  17.     //触发怪物攻击的临界距离  
  18.     public const int AI_ATTACT_DISTANCE=10;  
  19.       
  20.     //上一次思考的时间  
  21.     private float LastThinkTime;  
  22.       
  23.     void Start ()   
  24.     {  
  25.           
  26.     }  
  27.       
  28.     void Update ()   
  29.     {  
  30.        //当敌人与怪物间的距离小于攻击范围半径的时候  
  31.        if(Vector3.Distance(transform.position,Hero.transform.position)<AI_ATTACT_DISTANCE)  
  32.        {  
  33.           //敌人开始奔跑  
  34.           this.GetComponent<Animation>().Play("run");  
  35.           //敌人进入奔跑状态  
  36.           NowState=STATE_RUN;  
  37.           //使敌人面向角色  
  38.           transform.LookAt(Hero.transform);  
  39.           //向玩家靠近  
  40.           transform.Translate(Vector3.forward*Time.deltaTime * 5);  
  41.        }else  
  42.        {  
  43.           //当当前时间与上一次思考时间的差值大于怪物的思考时间时怪物开始思考  
  44.           if(Time.time-LastThinkTime>AI_THINK_TIME)  
  45.           {  
  46.              //开始思考  
  47.              LastThinkTime=Time.time;  
  48.              //获取0-3之间的随机数字  
  49.              int Rnd=Random.Range(0,2);        
  50.              //根据随机数值为怪物赋予不同的状态行为  
  51.              switch(Rnd)  
  52.              {  
  53.                 case 0:  
  54.                 //站立状态  
  55.                 this.GetComponent<Animation>().Play("idle");  
  56.                 NowState=STATE_STAND;  
  57.                 break;  
  58.                   
  59.                 case 1:  
  60.                 //行走状态  
  61.                 //使怪物旋转以完成行走动作  
  62.                 Quaternion mRotation=Quaternion.Euler(0,Random.Range(1,5)*90,0);  
  63.                 transform.rotation=Quaternion.Slerp(transform.rotation,mRotation,Time.deltaTime*1000);  
  64.                 //播放动画  
  65.                 this.GetComponent<Animation>().Play("walk");  
  66.                 //改变位置  
  67.                 transform.Translate(Vector3.forward*Time.deltaTime * 3);  
  68.                 NowState=STATE_WALK;  
  69.                 break;  
  70.                  
  71.                 case 2:  
  72.                 //奔跑状态  
  73.                 this.GetComponent<Animation>().Play("run");  
  74.                 transform.Translate(Vector3.forward*Time.deltaTime * 5);  
  75.                 NowState=STATE_RUN;  
  76.                 break;  
  77.              }   
  78.           }  
  79.        }  
  80.     }  
  81. }  

          在上面的代码中,能够触发怪物状态发生变化的有两个条件,第一,是玩家进入了怪物的警范围,此时怪物将面向玩家奔跑靠近;第二,当前时间与怪物上一次思考的时间之差大于怪物的思考时间,此时,怪物将随机作出反应。

          好,下面我们回到游戏界面当中来。


        如图,博主事先从官方资源商店里下载了一个人物模型。在这个模型中,设计者已经为我们设计好了人物动画,我们将这个模型拖放到场景中,调整到合适的位置,并将人物默认动画设置为idle,下面我们将刚才写好的脚本拖放到此模型上,并设置Hero为我们的玩家对象,在这里我们使用了官方提供的第三人称角色控制器组件,最终实现的效果如下 :



       可以看到,在不同的时刻,怪物可以自己执行不同的状态动作,当玩家靠近怪物的时候,会被敌人追击,这就是今天的内容啦,谢谢大家!



转载:原文出处

2015-01-14 23:11:58 C1805217287 阅读数 1981
欢迎来到unity学习unity培训unity企业培训教育专区,这里有很多U3D资源U3D培训视频我们致力于打造业内unity3d培训学习第一品牌。


       所谓怪物AI就是指我们为怪物编写一定的算法,使其可以具备一定程度的智能化,以增强游戏的可玩性。在一般的RPG游戏中,怪物通常在一个游戏设定的范围内巡逻,当玩家进入怪物的警戒范围时,怪物就会由巡逻状态转变为攻击状态,向玩家进行攻击,那么,我们今天就来实现一个简单的怪物AI吧,下面我们一起来看代码:
public class AI : MonoBehaviour {

//定义怪物的四种状态:站立、行走、奔跑、无所事事
public const int STATE_STAND=0;
public const int STATE_WALK=1;
public const int STATE_RUN=2;

//怪物当前状态
private int NowState;
//游戏角色
public GameObject Hero;
//怪物思考时间
public const int AI_THINK_TIME=2;
//触发怪物攻击的临界距离
public const int AI_ATTACT_DISTANCE=10;

//上一次思考的时间
private float LastThinkTime;

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);
}else
{
//当当前时间与上一次思考时间的差值大于怪物的思考时间时怪物开始思考
if(Time.time-LastThinkTime>AI_THINK_TIME)
{
//开始思考
LastThinkTime=Time.time;
//获取0-3之间的随机数字
int Rnd=Random.Range(0,2);
//根据随机数值为怪物赋予不同的状态行为
switch(Rnd)
{
case 0:
//站立状态
this.GetComponent<Animation>().Play("idle");
NowState=STATE_STAND;
break;

case 1:
//行走状态
//使怪物旋转以完成行走动作
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;
break;

case 2:
//奔跑状态
this.GetComponent<Animation>().Play("run");
transform.Translate(Vector3.forward*Time.deltaTime * 5);
NowState=STATE_RUN;
break;

}
}
}
}
2016-10-19 13:32:00 weixin_30398227 阅读数 5

Window → Navigation
MeshRenders(障碍物)选择障碍物 Navigation Static打勾
Terrains(地形)选择地形 Navigation Static打勾
点Bake栏的Bake,烘培地形。
给寻路角色添加 Component → Navigation →Nav Mash Agent
添加代码
1.
//定义组件
private NavMeshAgent agent;
2.
void Start()
{
//获取组件
agent = GetComponent<NavMeshAgent>();
}
3.
//设置目标
agent.SetDestination(point);

------------------------------------------


Nav Mash Agent参数
velocity速度:实际速度。
Radius 半径: 代理的半径(仅用于寻路目的,可以跟实际对象的半径大小不一样,一般比实际对象的半径大)。
Speed 速度: 代理可以周游世界,走向它的目的地的最大移动速度。
Acceleration 加速度: 最大加速度。
Angular Speed 角速度: 最高转速(度/秒)。
Stopping distance 制动距离:制动距离。到目的地的距离小于这个值,代理减速。
Auto Traverse OffMesh Link 自动遍历OffMesh链接:自动移动并关闭OffMeshLinks
Auto Repath 自动重新寻路:如果现有的部分已失效,获得新的路径。
Height 高度:代理的高度(用于调试图形)。
Base offset 基本偏移:碰撞几何体相对于实际几何体垂直的偏移。
Obstacle Avoidance Type 障碍躲避类型 :躲避的质量水平。
NavMesh Walkable 导航网格行走:指定代理可以遍历的导航网格层类型。

navMeshAgent调用setDestination 后,会有一个计算路径的时间,计算过程中pathPending为true. 在这个过程中remainingDistance一直为0.

转载于:https://www.cnblogs.com/wowanyasuo/p/5976932.html

2014-01-24 15:26:47 u013265457 阅读数 1136

  1. Unity3D简单AI编写

  由于这次介绍的AI很简单,代码直接贴上,AI分成四个状态:思考,转身,移动,攻击,这里只是初步实现,所以想实现简单点的操作,就像自动范围内随机移动,锁敌攻击,超出距离复位,近距离察觉等。

  1 Enemy_AI.js

  2

  3 private var Regression : Vector3;

  4 public var Player_Prefab : Transform;

  5 public var Enemy_State : String;

  6 public var Doing : boolean = true;

  7 public var Range : float = 4.0;

  8 public var Bullet : Transform;

  9 public var Bullet_Prefab : Transform;

  10 //初始化敌人方向和位置

  11 function Start()

  12 {

  13 transform.localEulerAngles.y = Random.value * 360;

  14 Regression = transform.position;

  15 }

  16 //敌人行动模式

  17 public var Thinking : boolean = true;

  18 public var Thinking_Time : float = 1.0;

  19 private var relativePos : Vector3;

  20 private var rotation : Quaternion;

  21 public var Facing : boolean = false;

  22 public var Facing_Time : float = 2.0;

  23 public var Facing_Speed : float = 2.0;

  24 public var Moving : boolean = false;

  25 public var Moving_Speed : float = 0.5;

  26 public var Moving_Time : float = 4.0;

  27 public var Moving_Back : boolean = false;

  28 public var Attacking : boolean = false;

  29 private var Bullet_DO : boolean = true;

  30 public var Bullet_CD : float = 0.2;

  31 //随机移动方位

  32 private var R_Position : Vector3;

  33 function Update ()

  34 {

  35 if(Attacking)

  36 {

  37 Enemy_State = "Attacking";

  38 Facing = true;

  39 Moving = true;

  40 //Doing = true;

  41 Thinking = false;

  42 var dist2 = Vector3.Distance(Regression, transform.position);

  43 if(dist2 > 20)

  44 {

  45 relativePos = Regression - transform.position;

  46 rotation = Quaternion.LookRotation(relativePos);

  47 Attacking = false;

  48 Moving_Back = true;

  49 }

  50 }

  51 if(!Moving_Back)

  52 {

  53 var dist = Vector3.Distance(Player_Prefab.position, transform.position);

  54 if(dist > 100)

  55 {

  56 Attacking = false;

  57 return;

  58 }

  59 else if(dist < 5)

  60 {

  61 Attacking = true;

  62 }

  63 RayJudge();

  64 }

  65 transform.localEulerAngles.x = 0;

  66 transform.localEulerAngles.z = 0;

  67 if(Thinking && !Attacking && !Moving_Back)

  68 {

  69 Enemy_State = "Thinking";

  70 if(Doing)

  71 {

  72 StartCoroutine(Think(Thinking_Time));

  73 Doing = false;

  74 }

  75 }

  76 if(Facing)

  77 {

  78 Enemy_State = "Facing";

  79 if(Attacking)

  80 {

  81 relativePos = Player_Prefab.position - transform.position;

  82 rotation = Quaternion.LookRotation(relativePos);

  83 transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * Facing_Speed * 4);

  84 }

  85 else if(Moving_Back)

  86 {

  87 transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * Facing_Speed * 4);

  88 }

  89 else

  90 {

  91 transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * Facing_Speed);

  92 if(Doing)

  93 {

  94 StartCoroutine(Face(Facing_Time));

  95 Doing = false;

  96 }

  97 }

  98 }

  99 if(Moving)

  100 {

  101 Enemy_State = "Moving";

  102 if(Moving_Back)

  103 {

  104 transform.Translate(Vector3.forward * Time.deltaTime * Moving_Speed * 6);

  105 }

  106 else if(dist > 2)

  107 {

  108 if(Attacking)

  109 {

  110 transform.Translate(Vector3.forward * Time.deltaTime * Moving_Speed * 4);

  111 }

  112 else

  113 {

  114 transform.Translate(Vector3.forward * Time.deltaTime * Moving_Speed);

  115 }

  116 }

  117 if(Doing && !Attacking)

  118 {

  119 StartCoroutine(Move(Moving_Time));

  120 Doing = false;

  121 }

  122 }

  123 }

  124 //前方锁敌

  125 function RayJudge()

  126 {

  127 var layerMask = 1 << 2;

  128 layerMask = ~layerMask;

  129 var hit : RaycastHit;

  130 if(Physics.Raycast (transform.position, transform.TransformDirection(Vector3.forward), hit, 20,layerMask))

  131 {

  132 var distanceToForward = hit.distance;

  133 if(hit.transform.tag == "Player")

  134 {

  135 Attacking = true;

  136 if(Bullet_DO)

  137 {

  138 var Create = Instantiate (Bullet_Prefab, Bullet.position, Quaternion.identity);

  139 Create.rigidbody.AddForce (Bullet.forward * 1000);

  140 StartCoroutine(Wait(Bullet_CD));

  141 Bullet_DO = false;

  142 }

  143 }

  144 }

  145 }

  146 function Wait(waitTime : float)

  147 {

  148 yield WaitForSeconds (waitTime);

  149 Bullet_DO = true;

  150 }

  151 function Move(waitTime : float)

  152 {

  153 print("Move");

  154 if(Moving_Back)

  155 {

  156 yield WaitForSeconds (waitTime * 0.4);

  157 }

  158 else

  159 {

  160 yield WaitForSeconds (waitTime + Random.value * 2);

  161 }

  162 Thinking = true;

  163 Moving_Back = false;

  164 Moving = false;

  165 Facing = false;

  166 Doing = true;

  167 }

  168 function Face(waitTime : float)

  169 {

  170 print("Face");

  171 yield WaitForSeconds (waitTime + Random.value);

  172 Facing = false;

  173 Thinking = false;

  174 Moving = true;

  175 Doing = true;

  176 }

  177 function Think(waitTime : float)

  178 {

  179 print("Thinking");

  180 yield WaitForSeconds (waitTime + Random.value);

  181 R_Position = Regression + Random.insideUnitSphere * Range;

  182 R_Position.y = Regression.y;

  183 relativePos = R_Position - transform.position;

  184 rotation = Quaternion.LookRotation(relativePos);

  185 Thinking = false;

  186 Moving = false;

  187 Facing = true;

  188 Doing = true;

  189 }

  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写。

 

unity3d 怪物的简单ai

阅读数 1022

没有更多推荐了,返回首页