日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Unity 內(nèi)的敵人AI 或者 有限狀態(tài)機(jī)FSM實(shí)現(xiàn)AI

 W_R_F 2017-03-28

孫廣東  2015.8.15

一、Enemy Aim Ai 
          目的: 這篇文章的主要目的是為了讓您了解有關(guān)如何使用 Enemy Aim Ai 。你會(huì)得到結(jié)果:


          Enemy aim AI是非常有用的,當(dāng)你想要敵人一直監(jiān)視player。適當(dāng)爭取對(duì)象在真實(shí)世界的場景,需要時(shí)間,所以敵人會(huì)采取一些之前它鎖在目標(biāo)系統(tǒng)上的時(shí)間量。

這種效應(yīng)可以創(chuàng)建的 Lerping 旋轉(zhuǎn)角度對(duì)玩家的敵人。這種情況是在動(dòng)作游戲,敵人跟隨,目的是何地然后射球員的情況下非常有用。對(duì)敵人遵循概念是在早些時(shí)候發(fā)布的博客中已經(jīng)討論過。在推行針對(duì)在游戲的同時(shí),理解四元數(shù)的概念是非常必要的。

四元數(shù)存儲(chǔ)對(duì)象的旋轉(zhuǎn),還可以計(jì)算價(jià)值取向。一個(gè)可以直接玩歐拉角,但可能會(huì)出現(xiàn) 萬向鎖 的情況。

根據(jù)當(dāng)?shù)氐淖鴺?biāo)系統(tǒng),如果你旋轉(zhuǎn)模型X 軸,然后其 Y 和 Z 軸經(jīng)驗(yàn)萬向節(jié)鎖被'鎖定'在一起。

現(xiàn)在回到我們的主題,給出了下面是一個(gè)簡單的例子來解釋 Enemy aim AI


按照下面給出的步驟。

1、創(chuàng)建Cube將作用在player control

  • 應(yīng)用適當(dāng)?shù)牟牧?,根?jù)要求向其網(wǎng)格渲染器
  • 將 TargetMovementScript 應(yīng)用于游戲?qū)ο?/li>
  • 將Cube 作為對(duì)象來將移動(dòng)上 player'scommands。


TargetMovementScript.cs

public class TargetMovementScript : MonoBehaviour { public float targetSpeed=9.0f;//Speed At Which the Object Should Move void Update () transform.Translate (Input.GetAxis ('Horizontal')*Time.deltaTime*targetSpeed,Input.GetAxis ('Vertical')*Time.deltaTime*targetSpeed,0); } }

2、創(chuàng)建一個(gè)Enemy對(duì)象,由箭頭和Cube組成,

1、應(yīng)用適當(dāng)?shù)牟牧蠈?duì)Cube 。

2、使箭頭Sprite作為一個(gè)不同的對(duì)象

3、其方向由 Cube指出 . 所以在這里,箭頭將充當(dāng)了敵人的槍。

4、此箭頭將指向目標(biāo)對(duì)象和它看起來就好像它試圖鎖定目標(biāo)

5、我們也可以操縱速度,敵人將能夠鎖定目標(biāo)屬性 ;作為不同的敵人應(yīng)該是不同的困難,以及不同的功能。
6、一輛坦克應(yīng)采取更多的時(shí)間鎖定一名士兵用槍瞄準(zhǔn)。所以在其中之一可以鎖定目標(biāo)的速度應(yīng)該是不同的。


EnemyAimScript.cs

public class EnemyAimScript : MonoBehaviour { public Transform target; // Target Object public float enemyAimSpeed=5.0f; // Speed at Which Enenmy locks on the Target Quaternion newRotation; float orientTransform; float orientTarget; void Update () { orientTransform = transform.position.x; orientTarget = target.position.x; // To Check on which side is the target , i.e. Right or Left of this Object if (orientTransform > orientTarget) { // Will Give Rotation angle , so that Arrow Points towards that target newRotation = Quaternion.LookRotation (transform.position - target.position, -Vector3.up); } else { newRotation = Quaternion.LookRotation (transform.position - target.position,Vector3.up); } // Here we have to freeze rotation along X and Y Axis, for proper movement of the arrow newRotation.x = 0.0f; newRotation.y = 0.0f; // Finally rotate and aim towards the target direction using Code below transform.rotation = Quaternion.Lerp (transform.rotation,newRotation,Time.deltaTime * enemyAimSpeed); // Another Alternative // transform.rotation = Quaternion.RotateTowards(transform.rotation,newRotation, Time.deltaTime * enemyAimSpeed); } }

7、Hierarchy 和 Scene View 可能會(huì)像作為給定下面


備注:-

可以改變敵人目標(biāo)并設(shè)置鎖定目標(biāo)的速度。

可以腳本通過允許X 或 Y 軸旋轉(zhuǎn),為了解這一概念的 。

可以給敵人添加Follow 腳本,以便敵人Follow 和 瞄準(zhǔn) 玩家。


而不是使用 Quaternion.Lerp 你也可以使用 Quaternion.RotateTowards 達(dá)到相同的效果。


二、通過有限狀態(tài)機(jī)實(shí)現(xiàn)AI

Contents Objective Step -

1: Set up the scene Step -

2: Create and place Game Objects Step -

3: Implement the BoxMovement Script Step -

4: FSM Modelled Script Step -

5: AI Script for the Box -


目的: 這篇文章的主要目的是要給你一個(gè)關(guān)于如何使用有限狀態(tài)機(jī)模型在 實(shí)現(xiàn) AI 。

FSM 的基礎(chǔ)知識(shí):
           在游戲中實(shí)施 AI  Finite State Machine Framework是完美的, 產(chǎn)生偉大的結(jié)果,而無需復(fù)雜的代碼。   它是一個(gè)模型,由一個(gè)或多個(gè)狀態(tài)??梢栽谝欢螘r(shí)間只有一個(gè)單一的狀態(tài)處于活動(dòng)狀態(tài), 所以這臺(tái)機(jī)器必須從一個(gè)狀態(tài)到另一種的轉(zhuǎn)換 為執(zhí)行不同的操作。


            有限狀態(tài)機(jī)框架通常用于管理、 組織和 代表不同的狀態(tài)、執(zhí)行流,在游戲中實(shí)現(xiàn)人工智能是非常有用的。'brain'是敵人,例如,可以使用有限狀態(tài)機(jī)來實(shí)現(xiàn):   每個(gè)狀態(tài)表示一個(gè)動(dòng)作,例如 巡邏、 Chase、 逃避或拍攝或任何其他種類的行動(dòng)。


          AI FSMs 的工作與Unity的的Animation FSMs,在那里一個(gè)動(dòng)畫狀態(tài)將更改為另一個(gè)符合的要求。可以通過使用第三方插件像行為實(shí)施 AI FSM 或它可以直接由腳本以及執(zhí)行。


若要獲取有限狀態(tài)機(jī)框架的基本理念,我們將執(zhí)行一個(gè)教程最簡單的方法,使用 switch 語句。然后我們將學(xué)習(xí)如何使用一個(gè)框架,使 AI 實(shí)現(xiàn)易于管理和擴(kuò)展。


請(qǐng)按照下面的步驟來執(zhí)行簡單的有限狀態(tài)機(jī)。


在這里我們將會(huì)有兩個(gè)Box,在那里將由玩家控制一個(gè)Box和 對(duì)方將由 AI 控制Box。此 AI 控制的Box會(huì)在chasing追逐狀態(tài)或patrolling巡邏狀態(tài),即Box中將開始追逐Player Box,一旦Player Box進(jìn)來的接近 AI 控制Box。它將切換回 巡邏狀態(tài),如果玩家足夠遠(yuǎn)逃避  未未的定義的愿景。


Step - 1: Set up the scene

以一個(gè)平面和兩個(gè)Box在場景中,如下圖所示的設(shè)置。


Step - 2: Create and place Game Objects

          創(chuàng)建空的游戲?qū)ο蟛⑵渥鳛橛巫狱c(diǎn)Wanderer Points。放置這些空的游戲?qū)ο笙?,為您選擇平面周圍。在這里藍(lán)色的Cube是 AI Cube和紅一個(gè)是玩家控制的Cube。將它們放在距離不夠遠(yuǎn)。

Step - 3: Implement the BoxMovement Script

        實(shí)現(xiàn) BoxMovement 腳本來控制玩家的Cube的移動(dòng):如下:

public class BoxMovementScript : MonoBehaviour { public float speed = 0.1f; private Vector3 positionVector3; void Update () { InitializePosition (); if (Input.GetKey (KeyCode.LeftArrow)) { GoLeft (); } if (Input.GetKey (KeyCode.RightArrow)) { GoRight (); } if (Input.GetKey (KeyCode.UpArrow)) { GoTop (); } if (Input.GetKey (KeyCode.DownArrow)) { GoDown (); } RotateNow (); } private void InitializePosition () { positionVector3 = transform.position; } private void RotateNow () { Quaternion targetRotation = Quaternion.LookRotation (transform.position - positionVector3); transform.rotation = targetRotation; } private void GoLeft () { transform.position = transform.position new Vector3 (-speed, 0, 0); } private void GoRight () { transform.position = transform.position new Vector3 (speed, 0, 0); } private void GoTop () { transform.position = transform.position new Vector3 (0, 0, speed); } private void GoDown () { transform.position = transform.position new Vector3 (0, 0, -speed); } }

Step - 4: FSM Modelled Script

構(gòu)建FSM模型腳本:

public class FSM : MonoBehaviour { //Player Transform protected Transform playerTransform; //Next destination position of the Box protected Vector3 destPos; //List of points for patrolling protected GameObject[] pointList; protected virtual void Initialize (){ } protected virtual void FSMUpdate (){ } protected virtual void FSMFixedUpdate (){ } void Start () { Initialize (); } void Update () { FSMUpdate (); } void FixedUpdate () { FSMFixedUpdate (); } }


Step - 5: AI Script for the Box

   構(gòu)建 AI 腳本作為Box擴(kuò)展.

public class BoxFSM : FSM { public enum FSMState { None, Patrol, Chase, } //Current state that the Box is in public FSMState curState; //Speed of the Box private float curSpeed; //Box Rotation Speed private float curRotSpeed; //Initialize the Finite state machine for the AI Driven Box protected override void Initialize () { curState = FSMState.Patrol; curSpeed = 5.0f; curRotSpeed = 1.5f; //Get the list of points pointList = GameObject.FindGameObjectsWithTag ('WandarPoint'); //Set Random destination point for the patrol state first FindNextPoint (); //Get the target enemy(Player) GameObject objPlayer = GameObject.FindGameObjectWithTag ('Player'); playerTransform = objPlayer.transform; if (!playerTransform) print ('Player doesn't exist.. Please add one ' 'with Tag named 'Player''); } //Update each frame protected override void FSMUpdate () { switch (curState) { case FSMState.Patrol: UpdatePatrolState (); break; case FSMState.Chase: UpdateChaseState (); break; } } protected void UpdatePatrolState () { //Find another random patrol point on reaching the current Point //point is reached if (Vector3.Distance (transform.position, destPos) <= 2.5f) { print ('Reached to the destination point\n' 'calculating the next point'); FindNextPoint (); } //Check the distance with player Box //When the distance is near, transition to chase state else if (Vector3.Distance (transform.position, playerTransform.position) <= 15.0f) { print ('Switch to Chase State'); curState = FSMState.Chase; } //Rotate to the target point Quaternion targetRotation = Quaternion.LookRotation (destPos - transform.position); transform.rotation = Quaternion.Slerp (transform.rotation, targetRotation, Time.deltaTime * curRotSpeed); //Go Forward transform.Translate (Vector3.forward * Time.deltaTime * curSpeed); } protected void FindNextPoint () { print ('Finding next point'); int rndIndex = Random.Range (0, pointList.Length); float rndRadius = 5.0f; Vector3 rndPosition = Vector3.zero; destPos = pointList [rndIndex].transform.position rndPosition; //Check Range to Move and decide the random point //as the same as before if (IsInCurrentRange (destPos)) { rndPosition = new Vector3 (Random.Range (-rndRadius, rndRadius), 0.0f, Random.Range (-rndRadius, rndRadius)); destPos = pointList [rndIndex].transform.position rndPosition; } } protected bool IsInCurrentRange (Vector3 pos) { float xPos = Mathf.Abs (pos.x - transform.position.x); float zPos = Mathf.Abs (pos.z - transform.position.z); if (xPos <= 8 && zPos <= 8) return true; return false; } protected void UpdateChaseState () { //Set the target position as the player position destPos = playerTransform.position; //Check the distance with player Box When float dist = Vector3.Distance (transform.position, playerTransform.position); //Go back to patrol as player is now too far if (dist >= 15.0f) { curState = FSMState.Patrol; FindNextPoint (); } //Rotate to the target point Quaternion targetRotation = Quaternion.LookRotation (destPos - transform.position); transform.rotation = Quaternion.Slerp (transform.rotation, targetRotation, Time.deltaTime * curRotSpeed); //Go Forward transform.Translate (Vector3.forward * Time.deltaTime * curSpeed); } }

       此腳本適用于Cube是要跟隨玩家,不要忘記把player標(biāo)記Tag為 Player 和 Tag 為 WandarPoint,現(xiàn)在如 FSMUpdate() 所示的腳本將調(diào)用方法,這在子類中重寫和它將在每個(gè) update () 上執(zhí)行。

         在這里switch case被實(shí)施 將用于執(zhí)行的當(dāng)前狀態(tài)的操作。 因此擴(kuò)展 AI 是很簡單的僅僅通過添加新的state。Initialize() 方法也重寫,并將在 start () 方法中調(diào)用執(zhí)行。UpdatePatrolState() 將在每次更新上執(zhí)行,當(dāng)當(dāng)前狀態(tài)是patrol 周圍巡邏,也將會(huì)發(fā)生在 UpdateChaseState(),當(dāng)玩家在接近度 AI Box。如果當(dāng)處于巡邏,玩家進(jìn)來的 AI Box中,狀態(tài)將更改為 巡邏,相同 類型的檢查仍在  追逐模式檢查如果球員已遠(yuǎn)離其視野范圍, 然后切換回巡邏狀態(tài), 在每個(gè)更新,檢查狀態(tài)更改。

結(jié)論:
       FSM 的很容易理解和實(shí)現(xiàn),F(xiàn)sm 可以用于執(zhí)行復(fù)雜的 AI 。他們也可以表示使用圖,允許開發(fā)人員很容易理解,因此開發(fā)人員可以調(diào)整、 改變和優(yōu)化的最終結(jié)果。有限狀態(tài)機(jī)使用的函數(shù)或方法來代表狀態(tài)執(zhí)行是簡單、 功能強(qiáng)大、 易于擴(kuò)展。  可以使用基于堆棧的狀態(tài)機(jī),確保易于管理和穩(wěn)定的 執(zhí)行流,而不會(huì)產(chǎn)生消極影響的代碼應(yīng)用甚至更復(fù)雜的 AI。 所以讓你的敵人更聰明使用有限狀態(tài)機(jī),讓您的游戲的成功。













    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多