RPG怪物AI

最近在做一個小的ARPG游戲。剛寫了一點關(guān)于怪物的AI控制的代碼,前后還出現(xiàn)了很多問題的?,F(xiàn)在拿出來分享一下。

首先我們先導(dǎo)入一個骷髏模型作例子學(xué)習(xí)。


1、先增加一個animator狀態(tài)機。

2、然后我們把Skeleton_Pack文件夾里面的其中一個prefab拖到場景。我們在prefab給他添加好Controller,組件和腳本。(差點忘了說,我們把prefab拖出來后,在skeleton_archer_blue設(shè)置一個空的gameobject,命名為head,這個head的坐標(biāo)是skeleton_archer_blue的頭頂,用來顯示血條的。)


3.using UnityEngine;

using System.Collections;

////// 功能:人物血條的隱藏與顯示,怪物的轉(zhuǎn)向(當(dāng)player與怪物小于一定距離,則設(shè)置兩者面對面),怪物的自動攻擊。

///public class MonsterAI : MonoBehaviour {?

?? public GameObject uiPrefab; ? //血條的prefab? ?

?//角色頭頂?shù)狞c,最好讓美術(shù)把這個點直接做在fbx模型里面? ?

? public Transform head;??

? public enum State? ? {? ? ?

?? IDLE,? ? ? ? WALK,? ? ? ? ATTACK,? ? ? ? DANGER? ?

?}?

?? public State state;??

? private Animator animator;//獲取Animator組件? ??

? private CharacterController control;??

? ?private GameObject ui;? ??

?//默認(rèn)血條與攝像機的距離? ?

? ? private float fomat;? ??

? //人物位置坐標(biāo)? ?

? ? private Vector3 playerPosition;? ? ? ? ? ?

? ? void Awake()? ? {? ? ? ?

? ? ?ui = (GameObject)Instantiate(uiPrefab);? ? ? ??


? ? ? animator = GetComponent();? ? ? ??

? ? ? control = GetComponent();? ?

? ? ? }? ? ?

? ? ? ? void Start () {? ? ??

? ? ? ? state = State.IDLE;? ? ??

? ? ? ? fomat = Vector3.Distance(head.position, Camera.main.transform.position);? ?

? ? ?} ? ? ? ? ?

? ? ? ?void Update () {? ? ? ??

? ? ? //人物Position? ? ? ?

? ? ? ? playerPosition=PlayerControl.instance.transform.position;? ? ?

? ? ? ? Debug.DrawLine(playerPosition, transform.position, Color.red);? ? ? ?

? ? ? ? ?setBloodBar();? ? ??

? ? ? ?//人物與怪物的距離? ? ?

? ? ? ?float dis = Vector3.Distance(transform.position, playerPosition);? ? ??


? ? ? ?/**? ? ? ? * 下面是這樣的,當(dāng)兩者距離小于3時,則怪物攻擊,設(shè)置怪物狀態(tài)為ATTACK? ? ??

? ? ? ? ? ? ? ? ?* 當(dāng)兩者距離大于3小于15時候 ,怪物走向player?

? ? ? ? ? ? ? ? ? * 當(dāng)大于15時, 怪物處于IDLE狀態(tài))??

? ? **/ ? ? ??



if(dis < 3){

? ?state ?= State.Attack;

}if( dis <15){

print("進(jìn)入攻擊狀態(tài)");


? Quatertion rotation? =Quatertion.Slerp( tranform.rotation , Quatertion.LookRotation( playerPosition - transform.position),5 * Time.deltatime);? (LookRotation 創(chuàng)建由怪物正方向轉(zhuǎn)向玩家正方向的旋轉(zhuǎn))


? if(dis > 3){

? state = State.WALK;

? ?transform.position += transform.forwrd * 5 * Time.deltatime;?

? ? ? ? ? ? ? ? ? ? }

}

? ? ? ?else? ? ? ? {? ? ? ? ?

? ? ? ? ? ?print("退出小怪攻擊范圍");? ? ? ? ? ??

? ? ? ? ? ?state = State.IDLE;? ? ? ?

? ? ? ? }? ? ? ??

? ? ? ?MonsterStateControl();? ? }? ?

? ?////// 怪物的各種狀態(tài)處理,設(shè)置了animator的狀態(tài)機的變量


///void MonsterStateControl()? ? {? ? ?

? ? ? ? switch (state)? ? ? ? {? ? ??

? ? ? ? ? ?case State.IDLE:? ? ? ? ? ? ? ??

? ? ? ? ? ? ?animator.SetBool("isAttack00", false);? ? ? ? ??

? ? ? ? ? ? ?animator.SetBool("isRun", false);? ? ? ? ? ? ? ??

? ? ? ? ? ? ?break;? ? ? ? ? ?

? ? ? ? ? case State.WALK:? ? ? ? ? ? ??

? ? ? ? ? ? animator.SetBool("isRun", true);? ? ? ? ? ??

? ? ? ? ? ?animator.SetBool("isAttack00", false);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? ? ? break;? ? ? ? ? ?

? ? ? ? ? case State.ATTACK:? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? ? animator.SetBool("isAttack00", true);? ? ? ? ??

? ? ? ? ? ?animator.SetBool("isRun", false);? ? ? ? ??

? ? ? ? ? ?break;? ? ? ? ? ?

? ? ? ? ? ? case State.DANGER:? ? ? ? ? ? ?

? ? ? ? ? ? state = State.ATTACK;? ? ? ? ? ?

? ? ? ? ? ? ? break;? ? ? ?

? ? ? ? }? ?

? ?}? ??


? ? ////// 設(shè)置怪物血條,當(dāng)怪物在人物前方時顯示血條,否則隱藏

///void setBloodBar()? ? {? ? ??

? ? /**? ? ? ? * 此處判斷怪物是否在player的前方。 * 獲得player的forward,和兩者的距離,再通過Vector3.Angle取得player正前方方向與distance方向的角度? ? ? ? * 計算,magnitude表示兩者距離,angle當(dāng)角度小于45,證明怪物在player的正前方視野。? ? ? ? * */? ??


? ? ? Vector3 Playerforward = PlayerControl.instance.transform.TransformDirection(Vector3.forward); ? ? ?(從自身坐標(biāo)到世界坐標(biāo)的變換)


? ?//人物與怪物的距離? ? ? ?

? Vector3 distance = transform.position - playerPosition;? ? ?

? ? float angle = Vector3.Angle(Playerforward, distance);? ? ? ? ? ??

? ? ? ? if(angle<45 && distance.magnitude<15)? ? ? ? {? ? ? ?

? ? ? ? ? ?ui.SetActive(true);? ? ? ??

? ? ? }? ? ? ? else? ? ? ? {? ? ? ??

? ? ? ? ? ? ui.SetActive(false);? ? ??

? ? ? ?}? ? ? ? ? ? ? ??

? ? ? //這里可以判定一下,如果位置沒有變化就不要再賦值了? ? ??

? ? ? ?float newFomat = fomat / Vector3.Distance(head.position, Camera.main.transform.position);? ??

? ? ? ?ui.transform.position = WorldToUI(head.position);? ? ?

? ? ? ?ui.transform.localScale = Vector3.one * newFomat;? ?

? }? ? ? ?

? //核心代碼在這里把3D點換算成NGUI屏幕上的2D點。? ?

? public static Vector3 WorldToUI(Vector3 point)? ? {? ? ?

? ? Vector3 pt = Camera.main.WorldToScreenPoint(point);? ? ?

? ? Vector3 ff = UICamera.currentCamera.ScreenToWorldPoint(pt);? ? ? ??

? ? //UI的話z軸等于0? ? ? ??

? ? ? ff.z = 0;? ? ?

? ? ? return ff;? ?

? ? ?}

?}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容