Unity3D关于AI的编写代码

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

t; margin-top:0pt; " > 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值