Unity学习笔记(五)——3DRPG游戏(2)

添加更多的敌人

编辑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;

另一个怪物同理,另外需要改一下它的名字

修改野人、石头人身体材质(修改后身体颜色会更亮、反光效果)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/89780.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/89780.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025测绘程序设计国赛实战:一轮终章 | 单向后方交会C#实现

前言本文是小编对六道国赛试题中的最后一个试题&#xff0c;单向后方交会的一篇学习日志。本文的整体架构&#xff0c;依旧首先拿训练数据跟大家介绍本题涉及到的数据的属性含义&#xff0c;涉及到算法的原理、执行流程和终极目的。然后附上小编用C#来实现的程序&#xff0c;从…

基于Echarts的气象数据可视化网站系统的设计与实现(Python版)

本系统旨在构建一个基于Echarts的气象数据可视化系统&#xff0c;本系统能够从中国天气网爬取实时天气数据&#xff0c;并进行存储、分析和可视化展示。用户可以通过网页界面查看不同地区的天气情况&#xff0c;以及历史天气数据的变化趋势。 技术栈&#xff1a;Python语言、My…

HarmonyOS 启动提速秘籍:懒加载全链路实战解析

摘要 随着移动应用功能越来越复杂、界面越来越丰富&#xff0c;应用启动慢、内存占用高等问题也越来越普遍。特别是在 HarmonyOS NEXT 应用开发中&#xff0c;如果不加优化&#xff0c;用户打开页面时可能要等好几秒&#xff0c;体验就很差了。 懒加载&#xff08;Lazy Loading…

全新安装Proxmox VE启动时卡在Loading initial ramdisk

原因&#xff1a; 使用了Ventoy启动盘装载 Proxmox ISO 文件安装。 要用Ventoy优盘启动&#xff0c;选择Advance Option里的Rescue Boot&#xff0c; 修改文件/etc/default/grub.d/installer.cfg&#xff0c;删除rdinit/vtoy/vtoy运行 update-grub 更新grub配置&#xff0c;重启…

【Java项目安全基石】登录认证实战:Session/Token/JWT用户校验机制深度解析

目录 1.前言 2.正文 2.1Cookie—Session机制 2.1.1核心原理图解&#xff1a; 2.1.2四步核心流程&#xff1a; 2.1.3存储架构对比 2.1.4集群部署方案&#xff08;Spring Session Redis&#xff09; 2.2Token令牌 2.2.1核心原理图解&#xff1a; 2.2.2四步核心流程&am…

融合优势:SIP 广播对讲联动华为会议 全场景沟通响应提速​

SIP 广播对讲与华为视频会议融合解决方案&#xff0c;是基于 SIP 协议将广播对讲系统与华为视频会议系统进行整合&#xff0c;实现通信资源共享与业务流程联动&#xff0c;可提升应急响应效率与沟通协作能力。融合原理&#xff1a;SIP 是一种基于文本的应用层协议&#xff0c;具…

Milvus Dify 学习笔记

目录 docker方式&#xff1a; 模式一&#xff1a;Milvus Lite linux docker方式&#xff1a; 下载yml文件&#xff0c; https://github.com/milvus-io/milvus/releases docker启动&#xff1a; docker compose up -d from pymilvus import connections connections.conne…

汽车ECU控制器通信架构

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

【Linux】基本指令(入门篇)(上)

目录 前言 1.目录操作指令 1.1指令 1.2理论 1.2.1文件 1.2.2目录与路径 2.文件操作指令 2.1指令 2.2理论 2.2.1输出与输入 2.2.2一切皆文件 前言 这是Linux学习下的第一篇文章&#xff0c;后续Linux的学习也会持续更新分享。 Linux的基本指令是使用Linux操作系统的基础…

正向代理与反向代理理解

问&#xff1a; 应用a请求ng&#xff0c;然后ng根据不同请求路径将请求转发到不同的服务器&#xff0c;对于应用a来说这个ng是正向代理角色还是反向代理呢&#xff1f; 答&#xff1a; 在这个场景中&#xff0c;Nginx 扮演的是反向代理的角色&#xff0c;而不是正向代理。以下是…

【Kafka】深入理解 Kafka MirrorMaker2 - 实战篇

文章目录一、把“家伙事儿”都备齐二、部署其实很简单三、配置 MirrorMaker2四、修改启动脚本五、集群启动与验证六、这集群“结实”吗&#xff1f;聊聊它的高可用它没有“大脑”&#xff0c;但活得很好极限测试&#xff1a;干掉两个节点会怎样&#xff1f;写在最后最近在跟 Ka…

借助AI学习开源代码git0.7之四update-cache

借助AI学习开源代码git0.7之四update-cache update-cache.c 主要负责对索引&#xff08;index&#xff09;&#xff0c;也即缓存&#xff08;cache&#xff09;&#xff0c;进行增、删、改操作。现在的高层命令 git add 的部分核心功能就是由这个代码实现的。 核心功能 该程序的…

【48】MFC入门到精通——MFC 文件读写总结 CFile、CStdioFile、CFileDialog

文章目录1 打开文件1.2 打开文件模式总结2 常用函数2.1 写文件2.2 读文件2.3 获取文件长度3. 文件打开读写实力3.1 写文件 覆盖写3.2 文尾追加写3.3 换行写4 文件对话框 CFileDialog4.2 文件对话框实例5 CStdioFile 类 读写CStingMFC提供了一个文件操作的基类CFile&#xff0c;…

Leetcode 124. 二叉树中的最大路径和

递归/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode…

MTSC2025参会感悟:手工测试用例的智能化生成

目录 一、测试用例生成的时代困境与 AI 机遇 1.1 传统手工测试用例的固有痛点 1.2 AI 时代的测试新挑战 1.3 智能化转型的机遇窗口 二、智能用例生成的核心特性与产品功能 2.1 核心特性解析 2.2 四大核心产品功能 功能一&#xff1a;基于 PRD 理解的一键生成用例 功能二…

后台管理系统登录模块(双token的实现思路)

最近在写后台管理&#xff0c;这里分享一下我的登录模块的实现&#xff0c;我是使用reacttypescript实现的&#xff0c;主要是登录的逻辑和双token的处理方式&#xff0c;请求接口的二次封装aixos1.首先我们需要渲染登录界面的窗口&#xff0c;这个很简单就不详细讲解了&#x…

第十四讲 | AVL树实现

AVL树实现一、AVL的概念二、AVL树的实现1、AVL树的结构2、AVL树的插入&#xff08;1&#xff09;、AVL树插入一个值的大概过程&#xff08;2&#xff09;、平衡因子更新更新原则更新停止条件插入结点及更新平衡因子的代码实现3、旋转&#xff08;1&#xff09;、旋转的原则&…

《P3398 仓鼠找 sugar》

题目描述小仓鼠的和他的基&#xff08;mei&#xff09;友&#xff08;zi&#xff09;sugar 住在地下洞穴中&#xff0c;每个节点的编号为 1∼n。地下洞穴是一个树形结构。这一天小仓鼠打算从从他的卧室&#xff08;a&#xff09;到餐厅&#xff08;b&#xff09;&#xff0c;而…

锤子助手插件功能六:启用拦截消息撤回

锤子助手插件功能六&#xff1a;启用拦截消息撤回锤子助手插件功能六&#xff1a;启用拦截消息撤回&#x1f6e1;️ 插件简介 拦截撤回消息&#xff0c;信息不再消失&#x1f527; 功能说明⚠️ 使用风险与注意事项&#x1f3af; 适合人群❤️ 结语锤子助手插件功能六&#xf…

深度解析:基于EasyX的C++黑白棋AI实现 | 算法核心+图形化实战

摘要 本文详解C黑白棋AI实现&#xff0c;使用EasyX图形库打造完整人机对战系统。涵盖&#xff1a; 递归搜索算法&#xff08;动态规划优化&#xff09; 棋盘状态评估函数设计 图形界面与音效集成 胜负判定与用户交互 附完整可运行代码资源文件&#xff0c;提供AI难度调节方案…