【UnityRPG游戏制作】NPC交互逻辑、动玩法

在这里插入图片描述


👨‍💻个人主页:@元宇宙-秩沅

👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!

👨‍💻 本文由 秩沅 原创
👨‍💻 收录于专栏:就业宝典

🅰️推荐专栏

⭐-软件设计师高频考点大全



文章目录

    • 前言
    • 🎶(==二==) NPC逻辑相关
    • (==1==) NPC范围检测
    • (==2==) NPC动画添加
    • (==3==) NPC和玩家的攻击受伤交互(事件中心)
    • (==4==) NPC的受伤特效添加
    • (==5==) NPC的死亡特效添加
    • 🅰️


前言


🎶( NPC逻辑相关



1 NPC范围检测


在这里插入图片描述

在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;//-------------------------------
//-------功能: NPC交互脚本
//-------创建者:         -------
//------------------------------public class NPCContorller : MonoBehaviour
{public PlayerContorller playerCtrl;//范围检测private void OnTriggerEnter(Collider other){playerCtrl.isNearby  = true;}private void OnTriggerExit(Collider other){playerCtrl.isNearby = false;}
}

2 NPC动画添加


在这里插入图片描述
请添加图片描述


3 NPC和玩家的攻击受伤交互(事件中心)


  • EnemyController 敌人
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;//-------------------------------
//-------功能:  敌人控制器
//-------创建者:         -------
//------------------------------public class EnemyController : MonoBehaviour
{public GameObject player;   //对标玩家public Animator animator;   //对标动画机public GameObject enemyNPC; //对标敌人public int hp;              //血量public Image hpSlider;      //血条private int attack = 10;    //敌人的攻击力public float CD_skill ;         //技能冷却时间private void Start(){enemyNPC = transform.GetChild(0).gameObject;animator = enemyNPC.GetComponent<Animator>();SendEvent();  //发送相关事件}private void Update(){CD_skill += Time.deltaTime; //CD一直在累加}/// <summary>/// 发送事件/// </summary>private void SendEvent(){//传递怪兽攻击事件(也是玩家受伤时)EventCenter.GetInstance().AddEventListener(PureNotification.PLAYER_INJURY, (int attack) =>{animator.SetBool("attack",true ); //攻击动画激活     });//传递怪兽受伤事件(玩家攻击时)EventCenter.GetInstance().AddEventListener(PureNotification.PLAYER_ATTRACK, ( ) =>{ animator.SetBool("hurt", true);  //受伤动画激活});//传递怪兽死亡事件EventCenter.GetInstance().AddEventListener(PureNotification.NPC_Died , () =>{      animator.SetBool("died", true);  //死亡动画激活gameObject.SetActive(false);     //给物体失活//暴金币});}//碰撞检测private void OnCollisionStay(Collision collision){if (collision.gameObject.tag == "Player") //检测到如果是玩家的标签{if(CD_skill > 2f)  //攻击动画的冷却时间{Debug.Log("怪物即将攻击");CD_skill = 0;//触发攻击事件EventCenter.GetInstance().EventTrigger(PureNotification.PLAYER_INJURY, Attack());}    }}/// <summary>/// 传递攻击力/// </summary>/// <returns></returns>public  int  Attack(){return attack;}//碰撞检测private void OnCollisionExit(Collision collision){if (collision.gameObject.tag == "Player") //检测到如果是玩家的标签{animator.SetBool("attack", false);       collision.gameObject.GetComponent<PlayerContorller>().animator .SetBool("hurt", false);}}//范围触发检测private void OnTriggerStay(Collider other){if(other.tag == "Player")  //检测到如果是玩家的标签{//让怪物看向玩家transform.LookAt(other.gameObject.transform.position);//并且向其移动transform.Translate(Vector3.forward * 1 * Time.deltaTime);}}}
  • PlayerContorller玩家
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;
using static UnityEditor.Experimental.GraphView.GraphView;//-------------------------------
//-------功能: 玩家控制器
//-------创建者:        
//------------------------------public class PlayerContorller : MonoBehaviour
{//-----------------------------------------//---------------成员变量区-----------------//-----------------------------------------public float  speed = 1;         //速度倍量public Rigidbody rigidbody;      //刚体组建的声明public Animator  animator;       //动画控制器声明public GameObject[] playersitem; //角色数组声明public bool isNearby = false;    //人物是否在附近public float CD_skill ;         //技能冷却时间public int curWeaponNum;        //拥有武器数public int attack ;             //攻击力public int defence ;            //防御力//-----------------------------------------//-----------------------------------------void Start(){rigidbody = GetComponent<Rigidbody>();SendEvent();//发送事件给事件中心}void Update(){CD_skill += Time.deltaTime;       //CD一直在累加InputMonitoring();}void FixedUpdate(){Move();}/// <summary>/// 更换角色[数组]/// </summary>/// <param name="value"></param>public void ChangePlayers(int value){for (int i = 0; i < playersitem.Length; i++){if (i == value){animator = playersitem[i].GetComponent<Animator>();playersitem[i].SetActive(true);}else{playersitem[i].SetActive(false);}}}/// <summary>///玩家移动相关/// </summary>private void Move(){//速度大小float horizontal = Input.GetAxis("Horizontal");float vertical = Input.GetAxis("Vertical");if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0){//方向Vector3 dirction = new Vector3(horizontal, 0, vertical);//让角色的看向与移动方向保持一致transform.rotation = Quaternion.LookRotation(dirction);rigidbody.MovePosition(transform.position + dirction * speed * Time.deltaTime);animator.SetBool("walk", true);//加速奔跑if (Input.GetKey(KeyCode.LeftShift) ){animator.SetBool("run", true);animator.SetBool("walk", true);                rigidbody.MovePosition(transform.position + dirction * speed*3 * Time.deltaTime);}else {animator.SetBool("run", false);;animator.SetBool("walk", true);}            }else {animator.SetBool("walk", false);}}/// <summary>/// 键盘监听相关/// </summary>public void InputMonitoring(){//人物角色切换if (Input.GetKeyDown(KeyCode.Alpha1)){ChangePlayers(0);}if (Input.GetKeyDown(KeyCode.Alpha2)){ChangePlayers(1);}if (Input.GetKeyDown(KeyCode.Alpha3)){ChangePlayers(2);}//范围检测弹出和NPC的对话框if (isNearby && Input.GetKeyDown(KeyCode.F)){          //发送通知打开面板GameFacade.Instance.SendNotification(PureNotification.SHOW_PANEL, "NPCTipPanel");}//打开背包面板if ( Input.GetKeyDown(KeyCode.Tab)){//发送通知打开面板GameFacade.Instance.SendNotification(PureNotification.SHOW_PANEL, "BackpackPanel");}//打开角色面板if ( Input.GetKeyDown(KeyCode.C)){//发送通知打开面板GameFacade.Instance.SendNotification(PureNotification.SHOW_PANEL, "RolePanel");}//攻击监听if (Input.GetKeyDown(KeyCode.Space) && CD_skill >= 1.0f) //按下空格键攻击,并且技能恢复冷却{if (curWeaponNum > 0)  //有武器时的技能相关{animator.speed = 2;animator.SetTrigger("Attack2");}else                  //没有武器时的技能相关{animator.speed = 1;animator.SetTrigger("Attack1");}CD_skill = 0;#region//技能开始冷却//    audioSource.clip = Resources.Load<AudioClip>("music/01");//    audioSource.Play();//    cd_Put = 0;//var enemys = GameObject.FindGameObjectsWithTag("enemy");//foreach (GameObject enemy in enemys)//{//    if (enemy != null)//    {//        if (Vector3.Distance(enemy.transform.position, this.transform.position) <= 5)//        {//            enemy.transform.GetComponent<_03EnemyCtrl>().SubSelf(50);//        }//    }//}//var bosses = GameObject.FindGameObjectsWithTag("boss");//foreach (GameObject boss in bosses)//{//    if (boss != null)//    {//        if (Vector3.Distance(boss.transform.position, this.transform.position) <= 5)//        {//            boss.transform.GetComponent<boss>().SubHP();//        }//    }//}#endregion}//if (Input.GetKeyDown(KeyCode.E))//{//    changeWeapon = !changeWeapon;//}//if (Input.GetKeyDown(KeyCode.Q))//{//    AddHP();//    diaPanel.USeHP();//}//if (enemys != null && enemys.transform.childCount <= 0 && key != null)//{//    key.gameObject.SetActive(true);//}}/// <summary>/// 发送事件/// </summary>private void SendEvent(){//传递玩家攻击事件EventCenter.GetInstance().AddEventListener(PureNotification.PLAYER_ATTRACK, () =>{});//传递玩家受伤事件(怪物攻击时)EventCenter.GetInstance().AddEventListener(PureNotification.PLAYER_INJURY , (int attack) =>{animator.SetBool("hurt", true);Debug.Log(attack + "掉血了");                                 });   }
}

4 NPC的受伤特效添加


请添加图片描述

    /// <summary>/// 碰撞检测/// </summary>/// <param name="collision"></param>private void OnCollisionStay(Collision collision){//若碰到敌人,并进行攻击if (collision.gameObject.tag == "enemy" && Input.GetKeyDown(KeyCode.Space)){Debug.Log("造成伤害");enemyController = collision.gameObject.GetComponent<EnemyController>();//触发攻击事件enemyController.animator.SetBool("hurt", true);  //怪物受伤动画激活enemyController.transform.GetChild(2).GetChild(0).GetComponent<ParticleSystem>().Play();enemyController.hp -= attack;//减少血量enemyController. hpSlider.fillAmount = (enemyController.hp / 100.0f);if (enemyController.hp <= 0) //死亡判断{collision.transform.GetChild(0).GetComponent<Animator>() .SetBool("died", true);  //死亡动画激活//播放动画collision.transform.GetChild(2).GetChild(0).GetComponent<ParticleSystem>().Play();collision. gameObject.SetActive(false); //将敌人失活//暴钻石(实例化)Instantiate(Resources.Load<GameObject>("Perfab/Prop/damon"), collision.transform.position , Quaternion.identity);Destroy(collision.gameObject, 3);}}}

5 NPC的死亡特效添加


请添加图片描述

   /// <summary>/// 碰撞检测/// </summary>/// <param name="collision"></param>private void OnCollisionStay(Collision collision){//若碰到敌人,并进行攻击if (collision.gameObject.tag == "enemy" && Input.GetKeyDown(KeyCode.Space)){Debug.Log("造成伤害");enemyController = collision.gameObject.GetComponent<EnemyController>();//触发攻击事件enemyController.animator.SetBool("hurt", true);  //怪物受伤动画激活enemyController.transform.GetChild(2).GetChild(0).GetComponent<ParticleSystem>().Play();enemyController.hp -= attack;//减少血量enemyController. hpSlider.fillAmount = (enemyController.hp / 100.0f);if (enemyController.hp <= 0) //死亡判断{collision.transform.GetChild(0).GetComponent<Animator>() .SetBool("died", true);  //死亡动画激活//播放动画collision.transform.GetChild(2).GetChild(0).GetComponent<ParticleSystem>().Play();collision. gameObject.SetActive(false); //将敌人失活//暴钻石(实例化)Instantiate(Resources.Load<GameObject>("Perfab/Prop/damon"), collision.transform.position , Quaternion.identity);Destroy(collision.gameObject, 3);}}}

🅰️


⭐【Unityc#专题篇】之c#进阶篇】

⭐【Unityc#专题篇】之c#核心篇】

⭐【Unityc#专题篇】之c#基础篇】

⭐【Unity-c#专题篇】之c#入门篇】

【Unityc#专题篇】—进阶章题单实践练习

⭐【Unityc#专题篇】—基础章题单实践练习

【Unityc#专题篇】—核心章题单实践练习


你们的点赞👍 收藏⭐ 留言📝 关注✅是我持续创作,输出优质内容的最大动力!


在这里插入图片描述


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

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

相关文章

多级留言/评论的功能实现——SpringBoot3后端篇

目录 功能描述数据库表设计后端接口设计实体类entity 完整实体类dto 封装请求数据dto 封装分页请求数据vo 请求返回数据 Controller控制层Service层接口实现类 Mapper层Mybatis 操作数据库 补充&#xff1a;返回的数据结构自动创建实体类 最近毕设做完了&#xff0c;开始来梳理…

✔ ★Java大项目——用Java模拟RabbitMQ实现一个消息队列(二)【创建核心类、封装数据库操作】

✔ ★Java大项目——用Java模拟RabbitMQ实现一个消息队列 四. 项⽬创建五. 创建核⼼类 ★创建 Exchange&#xff08;名字、类型、持久化、自动删除、参数&#xff09;创建 MSGQueue&#xff08;名字、持久化、独占标识&#xff09;创建 Binding&#xff08;交换机名字、队列名字…

UDP编程流程(UDP客户端、服务器互发消息流程)

一、UDP编程流程 1.1、 UDP概述 UDP&#xff0c;即用户数据报协议&#xff0c;是一种面向无连接的传输层协议。相比于TCP协议&#xff0c;UDP具有以下特点&#xff1a; 速度较快&#xff1a;由于UDP不需要建立连接和进行复杂的握手过程&#xff0c;因此在传输数据时速度稍快…

Arcpy批量克里金插值报错

Arcpy批量克里金插值报错 文章目录 Arcpy批量克里金插值报错问题解决参考 问题 在进行实验的时候&#xff0c;Arcpy中批量进行克里金插值报错&#xff0c;主要就是在运行这个工具的时候&#xff0c;一直报错&#xff0c;改了很多参数也不行 ERROR 010079: 无法估算半变异函数…

MySQL商城数据库88张表结构(46—50)

46、消息队列表 CREATE TABLE dingchengyu消息队列表 (id int(11) NOT NULL AUTO_INCREMENT COMMENT 序号,userId int(11) DEFAULT NULL COMMENT 用户id,msgTtype tinyint(4) DEFAULT 0 COMMENT 消息类型,createTime datetime DEFAULT NULL COMMENT 创建时间,sendTime datetim…

LabVIEW自动剪板机控制系统

LabVIEW自动剪板机控制系统 随着工业自动化的快速发展&#xff0c;钣金加工行业面临着生产效率和加工精度的双重挑战。传统的手动或脚踏式剪板机已无法满足现代生产的高效率和高精度要求&#xff0c;因此&#xff0c;自动剪板机控制系统的研究与开发成为了行业发展的必然趋势。…

【深度学习】序列模型

深度学习&#xff08;Deep Learning&#xff09;是机器学习的一个分支领域&#xff1a;它是从数据中学习表示的一种新方法&#xff0c;强调从连续的层中进行学习&#xff0c;这些层对应于越来越有意义的表示。 1. 为什么选择序列模型&#xff1f; 循环神经网络&#xff08;RNN…

[嵌入式系统-63]:RT-Thread-内核:内核在不同CPU架构上的移植和不同硬件板BSP上的移植

目录 内核移植 1. CPU 架构移植&#xff1a;由CPU厂家提供 1.1 实现全局中断开关&#xff1a;汇编语言实现 &#xff08;1&#xff09;关闭全局中断 &#xff08;2&#xff09;打开全局中断 1.2 实现线程栈初始化 1.3 实现上下文切换 &#xff08;1&#xff09;实现 rt…

零代码编程:用Kimichat从PDF文件中批量提取图片

一个PDF文件中&#xff0c;有很多图片&#xff0c;想批量提取出来&#xff0c;可以借助kimi智能助手。 在借助kimi智能助手中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个网页爬取Python脚本的任务&#xff0c;具体步骤如下&#xff1a; 打开文件夹…

基于深度学习检测恶意流量识别框架(80+特征/99%识别率)

基于深度学习检测恶意流量识别框架 目录 基于深度学习检测恶意流量识别框架简要示例a.检测攻击类别b.模型训练结果输出参数c.前端检测页面d.前端训练界面e.前端审计界面&#xff08;后续更新了&#xff09;f.前端自学习界面&#xff08;自学习模式转换&#xff09;f1.自学习模式…

数据结构与算法之经典排序算法

一、简单排序 在我们的程序中&#xff0c;排序是非常常见的一种需求&#xff0c;提供一些数据元素&#xff0c;把这些数据元素按照一定的规则进行排序。比如查询一些订单按照订单的日期进行排序&#xff0c;再比如查询一些商品&#xff0c;按照商品的价格进行排序等等。所以&a…

021、Python+fastapi,第一个Python项目走向第21步:ubuntu 24.04 docker 安装mysql8、redis(二)

系列文章目录 pythonvue3fastapiai 学习_浪淘沙jkp的博客-CSDN博客https://blog.csdn.net/jiangkp/category_12623996.html 前言 安装redis 我会以三种方式安装&#xff0c; 第一、直接最简单安装&#xff0c;适用于测试环境玩玩 第二、conf配置安装 第三、集群环境安装 一…

电脑崩溃了,之前备份的GHO文件怎么恢复到新硬盘?

前言 之前咱们说到用WinPE系统给电脑做一个GHO镜像备份&#xff0c;这个备份可以用于硬盘完全崩溃换盘的情况下使用。 那么这个GHO镜像文件怎么用呢&#xff1f; 咱们今天详细来讲讲&#xff01; 如果你的电脑系统硬盘崩溃了或者是坏掉了&#xff0c;那么就需要使用之前备份…

ElementUI从unpkg.com完整下载到本地的方法 - 解决unpkg.com不稳定的问题 - 自建镜像站 - 不想打包只想cdn一下

方法 方法1&#xff09;随便弄个文件夹&#xff0c;根据官网npm方法下载包&#xff0c;提取即可 npm i element-ui -S cd /node_modules/element-ui/ ls src 安装npm方法&#xff1a;https://nodejs.org/en 方法2&#xff09;不推荐 - 在github中搜索对应的库zip包&#xff0…

C++仿函数周边及包装器

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…

Vue Vant 移动端如何禁止手机调起自带的输入键盘

前言 前不久在公司用Vue2开发了一个手机充值项目&#xff0c;键盘组件用的vant2的NumberKeyboard 数字键盘组件&#xff1b;上线后在IOS端只有一个vant数字键盘组件&#xff0c;但到了Android端&#xff0c;输入框一获取焦点不仅vant数字键盘弹出&#xff0c;连手机自带的键盘…

39 死锁

目录 1.死锁 2.线程同步 3.条件变量 4.案例 死锁 概念 死锁是指在一组进程中的各个进程均占有不会释放的资源&#xff0c;但因互相申请被其他进程所占用不会释放的资源而处于的一种永久等待状态 四个必要条件 互斥条件&#xff1a;一个资源每次只能被一个执行流使用 请求…

如何使用提示测试为LLMs构建单元测试?

原文地址&#xff1a;how-to-build-unit-tests-for-llms-using-prompt-testing 确保您的人工智能交付&#xff1a;快速测试完美生成应用程序的基本指南 2024 年 4 月 26 日 如果你曾经编写过软件&#xff0c;你就会知道测试是开发过程中必不可少的一部分。特别是单元测试&#…

设计模式——保护性暂停

同步模式之保护性暂停 文章目录 同步模式之保护性暂停定义实现应用带超时版 GuardedObject扩展——原理之join扩展——多任务版 GuardedObject 定义 即 Guarded Suspension&#xff0c;用在一个线程等待另一个线程的执行结果 要点 有一个结果需要从一个线程传递到另一个线程&…

【Linux】进程的控制①之进程创建与进程退出

目录 ​编辑 一 、进程的创建 1、fork函数 2.函数的返回值 ①return 可以返回两次&#xff0c;使得父子进程读到的id有两个值 ②写实拷贝&#xff0c;使得父子进程读到的值都对自身有意义 a.为什么要写实拷贝&#xff0c;而不是在创建子进程的时候直接就将空间给子进程开辟好&a…