Unity3D基礎(chǔ)教程:簡(jiǎn)單AI編寫(xiě)
1. Unity簡(jiǎn)單AI編寫(xiě)
由于這次介紹的AI很簡(jiǎn)單,代碼直接貼上,AI分成四個(gè)狀態(tài):思考,轉(zhuǎn)身,移動(dòng),攻擊,這里只是初步實(shí)現(xiàn),所以想實(shí)現(xiàn)簡(jiǎn)單點(diǎn)的操作,就像自動(dòng)范圍內(nèi)隨機(jī)移動(dòng),鎖敵攻擊,超出距離復(fù)位,近距離察覺(jué)等。
- Enemy_AI.js
- private var Regression : Vector3;
- public var Player_Prefab : Transform;
- public var Enemy_State : String;
- public var Doing : boolean = true;
- public var Range : float = 4.0;
- public var Bullet : Transform;
- public var Bullet_Prefab : Transform;
- //初始化敵人方向和位置
- function Start()
- {
- transform.localEulerAngles.y = Random.value * 360;
- Regression = transform.position;
- }
- //敵人行動(dòng)模式
- public var Thinking : boolean = true;
- public var Thinking_Time : float = 1.0;
- private var relativePos : Vector3;
- private var rotation : Quaternion;
- 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;
- //隨機(jī)移動(dòng)方位
- private var R_Position : Vector3;
- function Update ()
- {
- if(Attacking)
- {
- Enemy_State = "Attacking";
- Facing = true;
- Moving = true;
- //Doing = true;
- Thinking = false;
- var dist2 = Vector3.Distance(Regression, transform.position);
- if(dist2 > 20)
- {
- relativePos = Regression - transform.position;
- 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.position;
- 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 = ~layerMask;
- var hit : RaycastHit;
- if(Physics.Raycast (transform.position, transform.TransformDirection(Vector3.forward), hit, 20,layerMask))
- {
- var distanceToForward = hit.distance;
- 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 * Range;
- R_Position.y = Regression.y;
- relativePos = R_Position - transform.position;
- rotation = Quaternion.LookRotation(relativePos);
- Thinking = false;
- Moving = false;
- Facing = true;
- Doing = true;
- }
工程截圖(這里是9個(gè)拿槍的敵人- - 藍(lán)色為控制角色,WASD控制行動(dòng))
2.Unity學(xué)習(xí)過(guò)程中的一些細(xì)節(jié)分析
1.獲取位置坐標(biāo):當(dāng)你translate.position獲取的不是物體在世界的坐標(biāo)時(shí)可以試試translate. localRotation
2.改變旋轉(zhuǎn)角度:這里多半是用translate.localRotation= Quaternion.Euler(x,y,z);
3.如何更改鼠標(biāo)指針圖片,這也是羽化以后可能遇到的問(wèn)題,這里只能簡(jiǎn)單分析下,首先把鼠標(biāo)默認(rèn)指針隱藏掉Screen.showCursor=flase;再用個(gè)粒子或者圖片代替,具體位置可以用Camera.main.ScreenToWorldPoint()和Input.mousePosition獲得。但有個(gè)問(wèn)題就產(chǎn)生了,UI會(huì)遮擋鼠標(biāo),鼠標(biāo)圖片用UI代替總感覺(jué)不妥。。。所以羽化還沒(méi)想出解決方法- -
4.有關(guān)過(guò)場(chǎng)Loading的制作,一張圖片還好說(shuō),換個(gè)Scene或者寫(xiě)個(gè)UI都能解決,動(dòng)態(tài)Loading的是用Application.LoadLevelAsync可以達(dá)到效果,或者是預(yù)加載,具體可以看看羽化無(wú)縫地圖研究博文里面的一個(gè)別墅例子。
5.也許有一天你也會(huì)遇到腳本用C#編寫(xiě)時(shí)遇到一些莫名其妙的錯(cuò)誤,所以這里羽化建議動(dòng)態(tài)腳本命令最好用js寫(xiě)。