【unity实战】事件(Event)的基本实战使用

文章目录

  • 最终效果
  • 前言
  • 一、素材
  • 二、角色金币交互
    • 1. 拾取金币
    • 2. 显示金币数UI
  • 完结

最终效果

在这里插入图片描述

前言

之前我们介绍过委托的用法,具体可以跳转:【unity小技巧】委托(Delegate)的基础使用和介绍

这期来讲讲事件,使用你会发现它和委托真的很像,那么他们具体有什么区别呢?

在Unity中,事件(Event)和委托(Delegate)是两种不同的概念,它们之间有一些区别:

  1. 委托(Delegate)

    • 委托是一种类型,用于引用一个或多个方法。委托可以看作是函数指针或函数的代理。
    • 委托用于实现回调函数、事件处理和方法的动态绑定。
    • 委托是一种类型安全的方式来封装方法调用。
  2. 事件(Event)

    • 事件是建立在委托之上的高级概念,它提供了一种更加简洁、安全的方式来实现观察者模式。
    • 事件使用委托来通知其他对象或类,当特定情况发生时,让它们执行相应的操作。
    • 事件可以通过“+=”(添加订阅者)和“-=”(移除订阅者)来管理委托的订阅和取消订阅。

何时使用事件和委托

  • 当需要实现一对多的消息传递时,可以使用事件。比如,当某个对象的状态发生变化时,需要通知多个其他对象做出相应的反应。
  • 当需要回调函数或方法引用时,可以使用委托。比如,当某个操作完成后需要执行特定的方法,可以使用委托来实现回调。

综合来说,事件和委托在Unity开发中都有各自的用途,根据具体情况选择合适的方式来实现功能会更加方便和有效。

一、素材

https://assetstore.unity.com/packages/2d/environments/pixel-art-top-down-basic-187605
在这里插入图片描述

二、角色金币交互

1. 拾取金币

金币事件,定义当金币增加时触发的事件

public class GoldEvents
{
    public event Action<int> onGoldGained; // 当金币增加时触发的事件
    public void GoldGained(int gold) 
    {
        onGoldGained?.Invoke(gold); // 触发金币增加事件
    }
}

游戏事件管理中心,初始化各种事件

public class GameEventsManager : MonoBehaviour
{
    public static GameEventsManager instance { get; private set; } // 单例实例
    
    public GoldEvents goldEvents; // 金币事件

    private void Awake()
    {
        if (instance != null)
        {
            Debug.LogError("在场景中找到多个游戏事件管理器"); // 如果场景中存在多个游戏事件管理器,则输出错误信息
        }
        instance = this; // 设置单例实例为当前实例
        
        // 初始化所有事件
        goldEvents = new GoldEvents(); // 初始化金币事件
    }
}

挂载脚本
在这里插入图片描述

管理玩家的金币,注册金币增加事件执行方法

// GoldManager类,负责管理玩家的金币
public class GoldManager : MonoBehaviour
{
    [Header("Configuration")]
    // 游戏开始时玩家拥有的金币数量
    [SerializeField] private int startingGold = 5;

    // 当前玩家持有的金币数量,外部只能获取不能设置
    public int currentGold { get; private set; }

    // 在对象被激活时调用,初始化玩家的金币数量
    private void Awake()
    {
        currentGold = startingGold;
    }

    // 注册事件监听器
    private void OnEnable() 
    {
        // 当玩家获得金币时,注册GoldGained方法来处理事件
        GameEventsManager.instance.goldEvents.onGoldGained += GoldGained;
    }

    // 注销事件监听器
    private void OnDisable() 
    {
        // 当对象被禁用时,取消注册GoldGained方法
        GameEventsManager.instance.goldEvents.onGoldGained -= GoldGained;
    }

    // 处理获得金币的事件
    private void GoldGained(int gold) 
    {
        // 增加玩家的金币数量
        currentGold += gold;
    }
}

配置脚本
在这里插入图片描述

设置脚本执行顺序,在Unity的"Project Settings"中,你可以通过"Script Execution Order"设置脚本的执行顺序,确保GameEventsManager的Awake方法总是在其他依赖它的组件之前执行,不然可能会报错。
在这里插入图片描述

定义金币脚本,控制金币拾取和金币重新生成

[RequireComponent(typeof(CircleCollider2D))]
public class Coin : MonoBehaviour
{
    [Header("Config")]
    [SerializeField] private float respawnTimeSeconds = 8; // 重生时间
    [SerializeField] private int goldGained = 1; // 获得的金币数量

    private CircleCollider2D circleCollider; // 圆形碰撞体
    private SpriteRenderer visual; // 视觉元素

    private void Awake() 
    {
        // 初始化圆形碰撞体和视觉元素
        circleCollider = GetComponent<CircleCollider2D>();
        visual = GetComponentInChildren<SpriteRenderer>();
    }

    // 收集金币的方法
    private void CollectCoin() 
    {
        circleCollider.enabled = false;
        visual.enabled = false;
        // 触发获得金币事件
        GameEventsManager.instance.goldEvents.GoldGained(goldGained);
        StopAllCoroutines();
        StartCoroutine(RespawnAfterTime());
    }

    // 在一定时间后重生金币
    private IEnumerator RespawnAfterTime()
    {
        yield return new WaitForSeconds(respawnTimeSeconds);
        circleCollider.enabled = true;
        visual.enabled = true;
    }

    // 触发进入触发器事件
    private void OnTriggerEnter2D(Collider2D otherCollider) 
    {
        if (otherCollider.CompareTag("Player"))
        {
            CollectCoin();
        }
    }
}

金币挂载脚本
在这里插入图片描述
运行效果
在这里插入图片描述
拾取金币后,currentGold加1,说明没问题
在这里插入图片描述

2. 显示金币数UI

一直查看金币变量数据变化,不是很方便,我们可以让金币数显示出来

修改GoldEvents,新增金币变化事件

public class GoldEvents
{
	//。。。
	
    public event Action<int> onGoldChange; // 当金币数量变化时触发的事件
    public void GoldChange(int gold) 
    {
        onGoldChange?.Invoke(gold); // 触发金币变化事件
    }
}

新增GoldUI,注册金币数量发生变化时调用的方法

public class GoldUI : MonoBehaviour
{
    [Header("Components")]
    // 用于显示金币数量的TextMeshProUGUI组件
    [SerializeField] private TextMeshProUGUI goldText;

    // 在对象激活时注册事件监听器
    private void OnEnable() 
    {
        // 当金币数量发生变化时,注册GoldChange方法来处理事件
        GameEventsManager.instance.goldEvents.onGoldChange += GoldChange;
    }

    // 在对象禁用时注销事件监听器
    private void OnDisable() 
    {
        // 当对象被禁用时,取消注册GoldChange方法
        GameEventsManager.instance.goldEvents.onGoldChange -= GoldChange;
    }

    // 处理金币数量变化的事件
    private void GoldChange(int gold) 
    {
        // 将金币数量转换为字符串,并更新UI显示
        goldText.text = gold.ToString();
    }
}

同样配置GoldUI 脚本执行顺序
在这里插入图片描述

挂载脚本
在这里插入图片描述
修改GoldManager,广播当前金币数量的改变事件

// 在第一帧更新之前调用,广播当前金币数量的改变
private void Start()
{
    GameEventsManager.instance.goldEvents.GoldChange(currentGold);
}

// 处理获得金币的事件
private void GoldGained(int gold) 
{
    // 增加玩家的金币数量
    currentGold += gold;
    // 广播金币数量的变化
    GameEventsManager.instance.goldEvents.GoldChange(currentGold);
}

效果
在这里插入图片描述

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第五十一回 李逵打死殷天赐 柴进失陷高唐州-AI发展历程和常用框架

朱仝说只要杀了李逵就上梁山&#xff0c;柴进就劝李逵先在庄上住一段时间&#xff0c;先让朱仝、雷横和吴用回了梁山。 李逵在柴进庄上住了一个月&#xff0c;碰到柴进的叔叔柴皇城病重来信叫他去一趟&#xff0c;于是李逵就随着柴进去了高唐州。 柴皇城被殷天锡气死&#xf…

Linux——进程信号(一)

目录 1、信号入门 1.1、技术应用角度的信号 1.2、注意 1.3、信号概念 1.4、用kill -l命令可以查看系统定义的信号列表 1.5、信号处理常见方式概览 2、产生信号 2.1通过终端按键产生信号 Core Dump 2.2、调用系统函数向进程发信号 2.3、由软条件产生信号 3、总结思考…

H12-821_135

135.如图所示&#xff0c;R1和R2组成一个VRID为12的VRRP备份组。现用户在R2启动一分钟后再启动R1&#xff0c;那么以下关于R1缺省情况下状态的描述&#xff0c;正确的是哪些项?&#xff08;多选&#xff09; A.若将R1优先级改为100再启动&#xff0c;最终Master设备为R2 B.R1启…

一次一对一服务引起的沉思和笑话

前情提要 客户需求&#xff1a; 分析页面代码和接口请求协议和参数需求&#xff0c;将人工下载视频怎么获得最终的视频链接&#xff0c;这一逻辑清晰的展示并讲解清除。我询问了是否需要成品爬虫&#xff0c;他说代码他自己能搞定。 我给的价格选择&#xff1a; 第一种、首…

可视化拖拽式小程序源码系统 带完整的安装代码包以及搭建教程

信息技术的快速发展&#xff0c;小程序已成为企业、个人开发者以及各类机构推广品牌、提供服务的重要载体。然而&#xff0c;对于许多非专业开发者来说&#xff0c;编写小程序源码往往是一个复杂且耗时的过程。小编给大家分享一款可视化拖拽式小程序源码系统&#xff0c;旨在帮…

对 JVM 的类加载机制以及寻找字节码文件的“双亲委派模型”的理解

目录 1、JVM 的类加载机制 1.1、加载 1.2、验证 1.3、准备 1.4、解析 1.5、初始化 2、双亲委派模型 2.1、工作过程 1、JVM 的类加载机制 类加载指的是 Java 进程运行的时候&#xff0c;需要把 .class 文件从硬盘读取到内存&#xff0c;并进行一系列的校验解析的过程。…

电脑蓝牙在哪里打开?不同系统详解

在现代计算机的多功能性中&#xff0c;蓝牙技术的广泛应用使得我们能够轻松连接各种外部设备&#xff0c;实现无线传输和分享。无论是连接无线耳机、键盘&#xff0c;还是与其他设备快速交换文件&#xff0c;蓝牙在电脑中的角色很重要。然而&#xff0c;对于一些用户而言&#…

【小白学机器学习5】评价预测值和观测值差异的指标:MSE, RMSE,MAE, MAPE, WMAPE

目录 1 评价误差的各种度量指标 2 从误差的评价开始捋这个问题 2.1 误差问题的由来&#xff1a;回归模型预测值和真实值的差距 2.2 如何评价某函数的预测值是否足够好&#xff1f; 如何比较不同的预测函数的预测值的好坏呢&#xff1f; 2.3 最小二乘法&#xff1a;应该叫最…

Linux-网络-011

1网络协议模型 1.1【OSI】协议模型 1.1.1应用层 实际发送的数据应用层:HTTP 超文本传输协议HTTPS FTP 文件传输协议TFTP 简单文本传输协议SMTP 邮件传输协议MQTT TELNET ..1.1.2表示层 发送的数据是否加密1.1.3会话层 是否建立会话连接1.1.4传输层 数据…

STM32各外设初始化步骤

1、GPIO初始化步骤 1、使能GPIO时钟 2、初始化GPIO的输入/输出模式 3、设置GPIO的输出值或获取GPIO的输入值 GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitStruct.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin…

chrome插件chrome.storage数据写入失败QUOTA_BYTES_PER_ITEM quota exceeded

Unchecked runtime.lastError while running storage.set: QUOTA_BYTES_PER_ITEM quota exceeded at Object.callback 在开发浏览器插件的时候&#xff0c;报错提示&#xff1a;超出存储限制&#xff0c;浏览器插件存储官方文档&#xff1a;https://developer.chrome.com/docs…

【数据结构】21 Trie字符串统计

Trie 树 Trie树又称字典树、单词查找树。是一种能够高效存储和查找字符串集合的数据结构。 插入字符串 对上面已知的tire树&#xff0c;假如插入一个字符串"abdf"&#xff0c;需要进行以下操作&#xff1a; 从字符a开始寻找&#xff1a; 从第一层开始p 0 ,s[p][a…

Datadog平台各服务简介

AIOps的核心是AI&#xff0c;所以训练一个AI是实现AIOps的首要任务。 Datadog平台服务简介 Datadog 是一个云监控平台&#xff0c;提供了多种服务来帮助用户监控、分析、优化和保护他们的应用程序、基础设施、网络和安全。以下是每个服务的简要介绍&#xff1a; INFRASTRUCTU…

[C#]winform基于C2PNet算法实现室内和室外图像去雾

【CP2Net框架】 https://github.com/YuZheng9/C2PNet 【CP2Net介绍】 Abstract 考虑到不适定的性质&#xff0c;发展了单图像去模糊的对比正则化&#xff0c;引入了来自负图像的信息作为下界。然而&#xff0c;对比样本是非一致的&#xff0c;因为阴性通常距离清晰&#xff…

中国制造赢得世界 外贸独立站wordpress建站案例

孵化器wordpress外贸主题 孵化器、孵化设备wordpress企业主题&#xff0c;适合做孵化器 、孵化设备的企业使用。 https://www.jianzhanpress.com/?p3478 橡胶制品wordpress外贸主题 橡胶制品wordpress外贸主题&#xff0c;橡塑产品对外贸易公司官方网站wordpress模板。 ht…

ServletContext

ServletContext 1.共享数据 ServletContext servletContext this.getServletContext(); String username "徐凤年"; servletContext.setAttribute("username",username);ServletContext servletContext this.getServletContext(); String username (…

Subversion svn 开源的版本控制系统入门介绍 VCS

拓展阅读 Subversion 开源的版本控制系统入门介绍 VCS Git 开源的版本控制系统-01-入门使用介绍 Git 开源的版本控制系统-02-base usage 基本用法 Git 开源的版本控制系统-03-时间数据回溯 Git 开源的版本控制系统-04-branch manage 分支管理 Git 开源的版本控制系统-05-…

软考-中级-系统集成2023年综合知识(六)

🌹作者主页:青花锁 🌹简介:Java领域优质创作者🏆、Java微服务架构公号作者😄 🌹简历模板、学习资料、面试题库、技术互助 🌹文末获取联系方式 📝 软考中级专栏回顾 专栏导航描述软考-中级系统集成2023年综合知识(一)软考-中级系统集成2023年综合知识(二)软…

泛微OA本地部署项目

泛微OA本地部署 本文演示脱离公司服务器&#xff0c;在本地搭建泛微 OA。 本次演示的版本如下&#xff1a; ecology&#xff1a;e-9sql server 版本&#xff1a;2012jdk 版本&#xff1a;1.8 一、安装 VmWare、Centos 7 对于 VmWare、Centos 7的安装&#xff0c;此处不再一一…

[LeetBook]【学习日记】有效数字——状态机

题目 有效数字 有效数字&#xff08;按顺序&#xff09;可以分成以下几个部分&#xff1a; 若干空格一个小数或者整数&#xff08;可选&#xff09;一个’e’或’E’&#xff0c;后面跟着一个整数若干空格 小数&#xff08;按顺序&#xff09;可以分成以下几个部分&#xff1a…