Building Robust and Flexible Event System in Unity3D

1. Prerequisites

1.1 Observer Pattern

According to Wikipedia, the observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. (I omitted the definition in the Gang of Four book since it's not easy to understand)

Observer Pattern is often used in game when you need to build a event system. A event system is capable of notifying other classes about some specific events (player died, boss slaughtered, key item found, ...).

1.2 Observer Pattern in C# Language

Observer pattern is so commonly used that C# supports observer pattern at language level, which saves us a lot of labor and potential trouble in implementing it.

1.2.1 The delegate keyword

delegate is a special data type in C# representing functions. It's similar to function pointer in C, but has the advantage of multicasting, which allows combining different functions into a single variable.

delegate void MyDelegate(int num);
public void UseDelegate() {
MyDelegate myDelegate = f;
myDelegate += g;
myDelegate();
}
public void f(int a) {...}
public void g(int b) {...}

1.2.2 The event keyword

The event data type is just similar to the delegate data type, but it doesn't allow any modification other than adding and removing observers to/from the event variable.

public delegate void ClickAction();
public static event ClickAction OnClicked;
OnClicked += button1.ProcessClicked;
OnClicked += scene.ProcessClicked;
OnClicked -= button1.ProcessClicked;
OnClicked -= scene.ProcessClicked;

An important thing to notice is that a function MUST be removed from the event variable if the object it belongs to has been disabled or garbage collected, otherwise erroneous behaviors may occur.

2. Example Usage

Suppose we have a boss in game that we can slaughter it to win the level. When the boss died three class need to response to it. The player should cheer, the UI should display message and the game should end a few seconds later. Then we can arrange our code as follows:

public class GameManager : MonoBehaviour {
// Manage Events
public delegate void BossSlaughteredAction();
public static event BossSlaughteredAction bossSlaugheredAction;
public static void OnBossSlaughtered() {
if (bossSlaugheredAction != null) bossSlaugheredAction();
}
void OnEnable() {
bossSlaugheredAction += HandleBossSlaughtered;
}
void OnDisable() {
bossSlaugheredAction -= HandleBossSlaughtered;
}
public void HandleBossSlaughtered() {
//Debug.Log("Boss Slaughtered!");
DisplayTextAtScreen("猎得传奇猎物,游戏结束!", 5.0f);
Invoke("ProcessGameEnding", 5.0f);
}
void ProcessGameEnding() {
UnityEngine.SceneManagement.SceneManager.LoadScene("StartMenu");
}
}
public class BeerAttributes : MonoBehaviour {
[SerializeField] float health = 100.0f;
void TakeDamage(float amount) {
health -= amount;
if (health <= 0) {
this.enabled = false;
//Debug.Log("Die");
GameManager.OnBossSlaughtered();
}
}
}
public class WolfEventHandler : MonoBehaviour {
void OnEnable() {
GameManager.bossSlaugheredAction += HandleBossSlaughtered;
}
void OnDisable() {
GameManager.bossSlaugheredAction -= HandleBossSlaughtered;
}
void HandleBossSlaughtered() {
Animator animator = GetComponent<Animator>();
animator.SetTrigger("Cheer");
}
}

Building Robust and Flexible Event System in Unity3D的更多相关文章

  1. The Event System

    The Event System 在Qt中,事件是继承了虚拟类QEvent的对象,它代表了程序所发生的事情或者程序需要知道的一个外部活动的结果.事件可以被任意 QObject子类的实例接收和处理,是与 ...

  2. 【SaltStack官方版】—— Events&Reactor系统—EVENT SYSTEM

    Events&Reactor系统 EVENT SYSTEM The Salt Event System is used to fire off events enabling third pa ...

  3. event system

    事件的概念 简单来说, 就是应用程序感兴趣的应用内部或者外部的活动结果. 在Qt中, 使用QEvent 抽象这些活动. 事件驱动模型 事件驱动模型现在在计算机很多领域都有使用. 例如 BSD sock ...

  4. UICamera(NGUI Event system)原理

    看了UICamera的源码就显而易见了: UICamera « on: November 21, 2013, 12:21:48 AM »   Overview UICamera is a somewh ...

  5. [React] Normalize Events with Reacts Synthetic Event System

    Event handlers are passed an instance of SyntheticEvent in React. In this video we'll take a look at ...

  6. Three Sources of a Solid Object-Oriented Design

    pingback :http://java.sys-con.com/node/84633?page=0,1 Object-oriented design is like an alloy consis ...

  7. Android入门:一、Android Studio 2.1安装及初始化配置

    以前研究过eclipse +ADT开发android app,没深入再加上工作也用不上就扔在那,现在需要做APP开发,发现eclipse +ADT也不再更新了,google推出了功能强大的Androi ...

  8. Linux System Log Collection、Log Integration、Log Analysis System Building Learning

    目录 . 为什么要构建日志系统 . 通用日志系统的总体架构 . 日志系统的元数据来源:data source . 日志系统的子安全域日志收集系统:client Agent . 日志系统的中心日志整合系 ...

  9. Single-stack real-time operating system for embedded systems

    A real time operating system (RTOS) for embedded controllers having limited memory includes a contin ...

随机推荐

  1. KeyDown,KeyPress和KeyUp详解(转)

    1.按键的类型 Windows窗体将键盘输入标识为由按位Keys枚举表示的虚拟键代码.使用Keys枚举,可以综合一系列按键以生成单个值,这些值与WM_KEYDOWN和WM_SYSKEYDOWNWind ...

  2. GlusterFS + lagstash + elasticsearch + kibana 3 + redis日志收集存储系统部署 01

    因公司数据安全和分析的需要,故调研了一下 GlusterFS + lagstash + elasticsearch + kibana 3 + redis 整合在一起的日志管理应用: 安装,配置过程,使 ...

  3. ⑦ 设计模式的艺术-13.代理(Proxy)模式

    为什么需要代理模式 中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口. 开闭原则,增加 ...

  4. 【POJ】3070 Fibonacci

    [算法]矩阵快速幂 [题解] 根据f[n]=f[n-1]+f[n-2],可以构造递推矩阵: $$\begin{vmatrix}1 & 1\\ 1 & 0\end{vmatrix} \t ...

  5. 【BZOJ】3091: 城市旅行 Link-Cut Tree

    [题意]参考PoPoQQQ. 给定一棵树,每个点有一个点权,提供四种操作: 1.删除两点之间的连边 不存在边则无视 2.在两点之前连接一条边 两点已经联通则无视 3.在两点之间的路径上所有点的点权加上 ...

  6. HDU 3790 最短生成树 (最短路)

    题目链接 Problem Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的. ...

  7. eclipse运行Android项目出现“The connection to adb is down, and a severe error has occured. You must restart adb and Eclipse. ”

    重启eclipse之后仍然出现同样错误,此时可以尝试一下方法: cmd打开命令窗口: 之后重启eclipse,基本可以解决问题!

  8. layui的模块化和非模块化使用

    非模块化和模块化的区别是 非模块化不用每次都调用layui.use([],fun...)引入对应模块,引入的JS是/layui/layui.all.js 模块化必须每次都调用layui.use([], ...

  9. ruby post json

    require 'net/http' require 'json' uri = URI('http://localhost/test1.php') req = Net::HTTP::Post.new ...

  10. Supply

    Supplier创建一个Supply Supply有tap或emit方法. 可以这样理解: Supplier创建一个工厂 Supply 用tap创建流水线 emit向流水线上传送加工品进行加厂 my ...