[Unity3D] 04 - Event Manager
message消息管理
脚本与GameObject的关系
被显式添加到 Hierarchy 中的 GameObject 会被最先实例化,GameObject 被实例化的顺序是从下往上。
GameObject 被实例化的同时,加载其组件 component 并实例化,
如果挂载了脚本组件,则实例化脚本组件时,将调用脚本的 Awake 方法,组件的实例化顺序是也是从下往上。
在所有显式的 GameObject 及其组件被实例化完成之前,游戏不会开始播放帧。
当 GameObject 实例化工作完成之后,将开始播放游戏帧。每个脚本的第一帧都是调用 Start 方法,其后每一帧调用 Update,而且每个脚本在每一帧中的调用顺序是从下往上。
总结:被挂载到 GameObject 下面的脚本会被实例化成 GameObject 的一个成员。
Unity 3种message消息管理使用
Ref: http://blog.csdn.net/u011484013/article/details/51487936
- BroadcastMessage(<接收函数名>) 广播消息
- SendMessage(<接收函数名>) 发送消息
- SendMessageUpwards(<接收函数名>) 向上发送消息
举个例子:
MonoBehaviour 是 Unity 中所有脚本的基类,
- 如果你使用JS的话,脚本会自动继承MonoBehaviour。
- 如果使用C#的话,你需要显式继承MonoBehaviour。
- 示范:

- 发送消息
using UnityEngine;
using System.Collections; public class xx1 : MonoBehaviour
{
void OnGUI()
{
if (GUI.Button(new Rect(, , , ), "发送1"))
{
SendMessage("myTest"); # <-- button 向当前对象挂载的所有脚本上面发送消息
}
if (GUI.Button(new Rect(, , , ), "发送2"))
{
BroadcastMessage("myTest"); # <-- button 朝物体和所有子物体发送消息
} if (GUI.Button(new Rect(, , , ), "发送3"))
{
SendMessageUpwards("myTest"); # <-- button 朝物体和上级父物体发送信息
}
}
}
- 接收消息
using UnityEngine;
using System.Collections; public class XXX : MonoBehaviour { // Use this for initialization
void Start () { } // Update is called once per frame
void Update () { } void OnDrag(Vector2 delta)
{
Debug.Log("-------OnDrag--------");
} public void myTest() {
Debug.Log("this is a methord:" + gameObject.name);
}
}
EventManager的两种简单实现方式
From: http://blog.csdn.net/u010989951/article/details/79051299
第一种、调用Unity的事件系统来进行封装,
另一种、使用C#的事件与委托机制实现。
这里讲解第一种,即采用Unity事件系统API来实现;第二种详见原链接。
- EventManager 定义
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events; public class EventManager
{
private Dictionary<string, UnityEvent> eventDictionary=new Dictionary<string, UnityEvent>();
private static EventManager eventManager = new EventManager();
private EventManager()
{ }
public static EventManager GetInstance
{
get
{
return eventManager;
}
}
public void StartListening(string eventName, UnityAction listener)
{
UnityEvent thisEvent = null;
if (eventManager.eventDictionary.TryGetValue(eventName, out thisEvent))
{
thisEvent.AddListener(listener); // 给event [UnityEvent]附上listener
}
else
{
thisEvent = new UnityEvent();
thisEvent.AddListener(listener);
eventManager.eventDictionary.Add(eventName, thisEvent);
}
} public void StopListening(string eventName, UnityAction listener)
{
if (eventManager == null) return;
UnityEvent thisEvent = null;
if (eventManager.eventDictionary.TryGetValue(eventName, out thisEvent))
{
thisEvent.RemoveListener(listener);
}
} public void TriggerEvent(string eventName)
{
UnityEvent thisEvent = null;
if (eventManager.eventDictionary.TryGetValue(eventName, out thisEvent))
{
thisEvent.Invoke();
}
}
}
- Event 注册
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
using System; public class EventTest : MonoBehaviour
{
private Event_CallBack someListener;
void Awake()
{
someListener = new Event_CallBack(SomeFunction);
} void OnEnable()
{
EventManager.GetInstance.StartListening("test", someListener);
EventManager.GetInstance.StartListening("Spawn", SomeOtherFunction);
EventManager.GetInstance.StartListening("Destroy", SomeThirdFunction);
}
void OnDisable()
{
EventManager.GetInstance.StopListening("test", someListener);
EventManager.GetInstance.StopListening("Spawn", SomeOtherFunction);
EventManager.GetInstance.StopListening("Destroy", SomeThirdFunction);
} void SomeFunction(object sender)
{
Debug.Log("Some Function was called!");
} void SomeOtherFunction(object sender)
{
Debug.Log("Some Other Function was called!");
} void SomeThirdFunction(object sender)
{
Debug.Log("Some Third Function was called!");
}
}
- Event 触发
using UnityEngine;
using System.Collections; public class EventTriggerTest : MonoBehaviour
{
void Update()
{
if (Input.GetKeyDown("q"))
{
EventManager.GetInstance.TriggerEvent("test");
} if (Input.GetKeyDown("o"))
{
EventManager.GetInstance.TriggerEvent("Spawn");
} if (Input.GetKeyDown("p"))
{
EventManager.GetInstance.TriggerEvent("Destroy");
} if (Input.GetKeyDown("x"))
{
EventManager.GetInstance.TriggerEvent("Junk");
}
}
}
- UnityAction和UnityEvent的用法详解
Ref: http://blog.csdn.net/inlet511/article/details/46822907
UnityAction本质上是delegate,且有数个泛型版本(参数最多是4个),一个UnityAction可以添加多个函数 (多播委托)。
UnityEvent本质上是继承自UnityEventBase的类,它的AddListener()方法能够注册UnityAction,RemoveListener能够取消注册UnityAction,还有Invoke()方法能够一次性调用所有注册了的UnityAction。UnityEvent也有数个泛型版本(参数最多也是4个),但要注意的一点是,UnityAction的所有带参数的泛型版本都是抽象类(abstract),所以如果要使用的话,需要自己声明一个类继承之,然后再实例化该类才可以使用。
不使用带参数的UnityEvent:
using UnityEngine;
using System.Collections;
using UnityEngine.Events; public class UnityActionAndEvent : MonoBehaviour { public UnityAction action;
public UnityEvent myEvent = new UnityEvent(); void Start()
{
action = new UnityAction(MyFunction);
action += MyFunction2;
myEvent.AddListener(action);
} void Update()
{
if(Input.GetKeyDown(KeyCode.P))
{
myEvent.Invoke();
}
} public void MyFunction()
{
print ("Hello: ");
} public void MyFunction2()
{
print ("Hello2: ");
}
}
使用带参数的UnityEvent:
using UnityEngine;
using System.Collections;
using UnityEngine.Events; //因为UnityEvent<T0>是抽象类,所以需要声明一个类来继承它
public class MyEvent:UnityEvent<int>{} public class UnityActionWithParameter : MonoBehaviour { public MyEvent myEvent = new MyEvent();
public UnityAction<int> action; void Start () {
action = new UnityAction<int>(MyFunction);
action += MyFunction2;
myEvent.AddListener(action);
} void Update () {
if(Input.GetKeyDown(KeyCode.A))
{
myEvent.Invoke();
}
} public void MyFunction(int i)
{
print (i);
}
public void MyFunction2(int i)
{
print(i*);
}
}
Unity中通过面板中添加的Listener和通过脚本添加的Listener实际上是两种不同类型的Listener:
- 在脚本中通过AddListener()添加的是一个0个参数的delegate(UnityAction)回调。是不可序列化的,在Inspector中是无法看到的。这种Listener是常规Listener。
- 在Inspector中添加的则是永久性的Listener(persistent listener)。他们需要指定GameObject、方法以及方法需要的参数。他们是序列化的,用脚本是无法访问到的。
添加任意多个参数的函数
另外在脚本中使用lamda表达式来添加listener是非常方便的。
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using UnityEngine.UI; public class EventAndLamda : MonoBehaviour { void Start () {
//lamda方式可以添加包含任意参数的函数,非常方便
GetComponent<Button>().onClick.AddListener( ()=>{
//此处其实可以直接写Myfuction(.....),因为是同一个脚本里的函数
//这样写是为了说明调用其他组件中的函数也是可以的。如果有其他组件的引用,可以直接写:
//someReference.theMethod(arguments);
this.GetComponent<EventAndLamda>().MyFunction(,20.0f,new Vector3(,,));
} );
} public void MyFunction(int i, float f, Vector3 v)
{
print (i.ToString()+"\n" + f.ToString() + "\n" + v.ToString());
}
}
Package: UnityEditor.Events
Class: UnityEventTools
Description: Editor tools for working with persistent UnityEvents.
| AddBoolPersistentListener | Adds a persistent, preset call to the listener. |
| AddFloatPersistentListener | Adds a persistent, preset call to the listener. |
| AddIntPersistentListener | Adds a persistent, preset call to the listener. |
| AddObjectPersistentListener | Adds a persistent, preset call to the listener. |
| AddPersistentListener | Adds a persistent, call to the listener. Will be invoked with the arguments as defined by the Event and sent from the call location. |
| AddStringPersistentListener | Adds a persistent, preset call to the listener. |
| AddVoidPersistentListener | Adds a persistent, preset call to the listener. |
| RegisterBoolPersistentListener | Modifies the event at the given index. |
| RegisterFloatPersistentListener | Modifies the event at the given index. |
| RegisterIntPersistentListener | Modifies the event at the given index. |
| RegisterObjectPersistentListener | Modifies the event at the given index. |
| RegisterPersistentListener | Modifies the event at the given index. |
| RegisterStringPersistentListener | Modifies the event at the given index. |
| RegisterVoidPersistentListener | Modifies the event at the given index. |
| RemovePersistentListener | Removes the given function from the event. |
| UnregisterPersistentListener | Unregisters the given listener at the specified index. |
[Unity3D] 04 - Event Manager的更多相关文章
- ubuntu14.04, Cloudera Manager 5.11.1, cdh5.11.1 postgresql离线部署
最近一段时间团队接到的项目需要处理的数据量非常大,之前的处理方式难以满足现有需求.最近两周前前后后折腾了不少,在搭建了hadoop+hbase+hive+spark的一个集群后,由于感觉管理和监控太麻 ...
- zepto源码学习-04 event
之前说完$(XXX),然后还有很多零零碎碎的东西需要去分析,结果一看代码,发现zepto的实现都相对简单,没有太多可分析的.直接略过了一些实现,直接研究Event模块,相比JQuery的事件系统,ze ...
- [Node.js] 04 - Event and Callback
回调函数 回调函数在完成任务后就会被调用,Node 使用了大量的回调函数,Node 所有 API 都支持回调函数. 异步读取文件的回调函数: var fs = require("fs&quo ...
- 本人AI知识体系导航 - AI menu
Relevant Readable Links Name Interesting topic Comment Edwin Chen 非参贝叶斯 徐亦达老板 Dirichlet Process 学习 ...
- Magic Quadrant for Security Information and Event Management
https://www.gartner.com/doc/reprints?id=1-4LC8PAW&ct=171130&st=sb Summary Security and risk ...
- 理解Mac和iOS中的 Event 处理
根据现在的理解,我把event处理分为5部分,第一是,Event处理的Architecture:第二是,Event的Dispatch到first responder之前: 第三是,Event从firs ...
- Weak Event Patterns
https://msdn.microsoft.com/en-US/library/aa970850(v=vs.100).aspx In applications, it is possible tha ...
- Event Managers
Some PLF-based controls expose a convenient facility for temporarily disabling their events and for ...
- The .NET weak event pattern in C#
Introduction As you may know event handlers are a common source of memory leaks caused by the persis ...
随机推荐
- oracle级联删除
oracle级联删除可以使用触发器来实现,但是比较麻烦,最简单的就是直接建立表的主外键关系,给列设置级联删除. ------创建了CLASS表,并设置ID字段为主键. -- Create table ...
- PID控制器(比例-积分-微分控制器)- IV
调节/测量放大电路电路图:PID控制电路图 如图是PlD控制电路,即比例(P).积分(I).微分(D)控制电路. A1构成的比例电路与环路增益有关,调节RP1,可使反相器的增益在0·5一∞范围内变化; ...
- Delphi识别读取验证码
unit OCR; interface uses Windows, SysUtils, Graphics, Classes, PNGImage, GIFImage, JPEG, Math, Asphy ...
- Linux之路,起步虽晚,迈步才会成功(2013.08.09)
工作太忙,很久没写文章了.以前基本没有接触过,但是基于现在工作的状态,对于linux这种博大精深的东西,速成是没有可能的,只能积累,起步虽晚,迈步才会成功,以此勉励自己.
- Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘.dot.mul运算详解 2016年09月02日 00:00:36 -牧野- 阅读数:59593 标签: Opencv矩阵相乘点乘dotmul 更多 个人分类: O ...
- Duplicate复制数据库并创建物理StandBy(pfile版本)
1设定环境如下: Primary数据库 IP 172.17.22.16 SID orcl Standby数据库 IP 172.17.22.17 SID orcl 设置提示,以区分操作的位置 prima ...
- Linux下计算进程的CPU占用和内存占用的编程方法[转]
from:https://www.cnblogs.com/cxjchen/archive/2013/03/30/2990548.html Linux下没有直接可以调用系统函数知道CPU占用和内存占用. ...
- Eclipse Unhandled event loop exception GC overhead limit exceeded
修改Eclipse的配置文件:
- Swift 同构与异构
1.数据源中的同构与异构 对于 Swift 的集合数据来说,有同构和异构之分. 如果你需要讨论一群鸟类或者一批飞机,那么这样的数据是同构的,比如包含鸟类的数组 [Bird] 和包含飞机的数组 [Air ...
- Android Studio updating indices 一直刷新和闪烁
Android Studio 更新到了 3.1.3 版本,在导入了工程以后,一直出现了 updating indices 刷新的情况,造成闪烁,在切换到其他视图以后,Android Studio 会一 ...