添加更多的敌人
编辑EnemyController,解决报错导致敌人无法注册观察者模式,从而无法执行敌人庆祝动画
csusing 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没有生成时直接return GameManager.Instance.RemoveObserver(this); } ... }编辑PlayerController,避免Player死亡时仍然可以移动,添加对是否死亡的判断
csusing 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; //如果已经死亡则return agent.isStopped = false;//还原非禁止状态,保证攻击后人物能继续移动 agent.destination = target; //指定人物移动到的位置 } private void EventAttack(GameObject target) { if (isDead) return; //如果已经死亡则return if (target != null) { attackTarget = target; characterStatus.isCritical = UnityEngine.Random.value < characterStatus.attackData.criticalChance;//计算是否暴击 StartCoroutine(MoveToAttackTarget());//执行携程函数 StartCoroutine:用于创建和启动协程(Coroutine)的核心函数,可以暂停执行并在之后的某个时间点继续执行 } } ... }如果再复制一个Slime,当消灭掉一只时,另一只也死亡了,这是因为多个Slime用的同一个Slime Data,因此我们编辑CharacterStatus,创建模板并使用模板创建数据对象
csusing 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
csusing 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;
另一个怪物同理,另外需要改一下它的名字
修改野人、石头人身体材质(修改后身体颜色会更亮、反光效果)
Unity学习笔记(五)——3DRPG游戏(2)
呼叫冰河谷2025-07-21 8:08
相关推荐
~kiss~3 小时前
A Survey of On-Policy Distillation for LLMs 学习(一)一只大鸽子4 小时前
游戏开发笔记4-像素画基础 轮廓-直线和曲线小杨小杨、努力变强!5 小时前
python学习笔记杨逢昌工厂6S管理7 小时前
150-杨逢昌一线现场诊断笔记:越管一线越抵触背后的熵增机理与基准化治理Star(up up up)10 小时前
Redis Windows 安装教程:使用Windows 的 Redis 压缩包希和202711 小时前
江科大 51 单片机课程笔记:DS1302 实时时钟 + LCD1602 可调电子钟(小白逐行讲解)岑梓铭12 小时前
《考研408数据结构》第七章(B树 和 B+树)复习笔记乌暮13 小时前
Spring AOP 与 Spring 事务:用大白话彻底理解原理与实践暴走约伯14 小时前
【VFX工具链源码拆解 09】终极工业化闭环:基于 ID 规则驱动的全自动场景建档、骨骼挂载与男转女场景迁移Go Work16 小时前
docker 占满根分区时先分清谁在吃盘





























