Unity3D如何编写AI

  • Post author:
  • Post category:其他



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


写。