添加更多的敵人
編輯EnemyController,解決報錯導致敵人無法注冊觀察者模式,從而無法執行敵人慶祝動畫
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; public enum EnemyStatus { GUARD,PATROL,CHASE,DEAD } //分別表示守衛(站樁)、巡邏(來回走動)、追逐、死亡狀態 [RequireComponent(typeof(NavMeshAgent))] //拖拽時自動添加component public class EnemyController : MonoBehaviour,IEndGameObserver {private EnemyStatus enemyStatus;...void Start(){//在點擊Play時才會執行,在Awake后執行if (isGuard){//如果勾選了站樁,進入守衛模式enemyStatus = EnemyStatus.GUARD;}else {//否則進入巡邏模式enemyStatus = EnemyStatus.PATROL;GetNewWayPoint();//獲取一個巡邏路徑點}//TODO: 場景切換后修改GameManager.Instance.AddOberver(this);}//啟用時//void OnEnable() //在做場景加載時用到//{// GameManager.Instance.AddOberver(this);//在執行OnEnable時沒有找到GameManger//}//禁用時(與OnDestory區別:銷毀完成后執行)void OnDisable(){//人物消失或游戲停止時執行if (GameManager.isInitialized) return; //如果GameManager沒有生成時直接returnGameManager.Instance.RemoveObserver(this);}... }
編輯PlayerController,避免Player死亡時仍然可以移動,添加對是否死亡的判斷
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI;public class PlayerController : MonoBehaviour {private NavMeshAgent agent;...public void MoveToTarget(Vector3 target) {StopAllCoroutines(); //這個代碼是用于:當人物向怪物移動攻擊時,如果鼠標點擊了其他地方可以打斷向怪物移動的協程if (isDead) return; //如果已經死亡則returnagent.isStopped = false;//還原非禁止狀態,保證攻擊后人物能繼續移動agent.destination = target; //指定人物移動到的位置}private void EventAttack(GameObject target){if (isDead) return; //如果已經死亡則returnif (target != null) {attackTarget = target;characterStatus.isCritical = UnityEngine.Random.value < characterStatus.attackData.criticalChance;//計算是否暴擊StartCoroutine(MoveToAttackTarget());//執行攜程函數 StartCoroutine:用于創建和啟動協程(Coroutine)的核心函數,可以暫停執行并在之后的某個時間點繼續執行}}... }
如果再復制一個Slime,當消滅掉一只時,另一只也死亡了,這是因為多個Slime用的同一個Slime Data,因此我們編輯CharacterStatus,創建模板并使用模板創建數據對象
using System; using System.Collections; using System.Collections.Generic; using UnityEngine;public class CharacterStatus : MonoBehaviour {public CharacterData_SO templateData;//模板數據public CharacterData_SO characterData;public AttackData_SO attackData;[HideInInspector] //不希望在界面中顯示public bool isCritical;//是否暴擊void Awake(){if (templateData != null) {characterData = Instantiate(templateData);//Instantiate:借助已有的預制體(Prefab),能夠創建新的游戲對象實例}}... }
然后修改兩個Slime的配置如圖
這樣就不會互相影響了
添加新的怪物:將其拖拽到Hierarchy
刪除其原有的Controller
編輯EnemyController,添加新的RequireComponent
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; public enum EnemyStatus { GUARD,PATROL,CHASE,DEAD } //分別表示守衛(站樁)、巡邏(來回走動)、追逐、死亡狀態 [RequireComponent(typeof(NavMeshAgent))] //拖拽時自動添加component [RequireComponent(typeof(CharacterStatus))] //拖拽時自動添加component public class EnemyController : MonoBehaviour,IEndGameObserver {private EnemyStatus enemyStatus;private NavMeshAgent agent;... }
如圖進行添加
然后將其Tag設為Enemy,并添加Box Collider組件
設置Agent屬性
創建基礎數值對象(Create->Character Status->Data)取名為TurtleShell Data,設置如圖
創建攻擊數據對象(Create->Attack->Attack Data)取名為TurtleShell BaseAttackData,設置如圖
綁定攻擊數據對象和基礎數據對象
配置EnemyController屬性
在Animator下創建Animator Override Controller,取名為Enemy_TurtleShell
在Enemy_TurtleShell屬性界面中選擇Enemy_Slime作為需要覆蓋的原始類,下面的是原始類已有的動畫,將需要的替換即可
ctrl+D復制Attack01和Attack02,然后拖拽到Enemy/TurtleShell(需新建此文件夾)下
綁定Enemy_TurtleShell
然后逐一去替換TurtleShell下動畫
如果發現多了一個CharactorStatus一定要記得刪掉
引入新的素材
Mini Legion Grunt PBR HP Polyart | Characters | Unity Asset Store
Mini Legion Rock Golem PBR HP Polyart | Characters | Unity Asset Store
將其添加到我的資源,然后進行Download、Import,然后將其放在Assets Packs下,如圖
同樣不要忘了選擇Edit->Render Pipline,如圖選擇將所有素材都適配渲染組件,然后選擇Proceed
然后我們將Prefab下的素材拖拽到Hierarchy創建兩個敵人,將其擺放到想要的位置
將Hierarchy的TurtleShell拖拽到Prefebs/Characters下,選擇Original Prefab
為GruntPolyart新建Box Collider組件,然后調整其范圍(使用矩形面上的小點);設置Tag為Enemy;刪掉原有的Controller;
另一個怪物同理,另外需要改一下它的名字
修改野人、石頭人身體材質(修改后身體顏色會更亮、反光效果)