[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 ...
随机推荐
- PHP错误:Namespace declaration statement has to be the very first statement in the script
PHP错误:Namespace declaration statement has to be the very first statement in the script 原因:意思就是“names ...
- linux和CentOS下网卡启动、配置等ifcfg-eth0教程(转自)
转自:http://www.itokit.com/2012/0415/73593.html it 动力总结系统安装好后,通过以下二个步骤就可以让你的系统正常上网(大多正常情况下).步骤1.配置/etc ...
- Linux学习笔记12—磁盘管理
一.查看磁盘或目录的容量 1. df命令 作用:查看已挂载磁盘的总容量.使用容量.剩余容量等,可以不加任何参数,默认是按k为单位显示的 参数: -I : 查看inodes使用状况 -h: 使用合适的 ...
- Python:内置函数
Python所有的内置函数 Built-in Functions abs() divmod() input() open() staticmethod() all() enumerat ...
- WinPython
WinPython http://winpython.github.io/
- Apache CXF JAX-WS example
1. 环境说明 jdk 1.6.0_29 apache cxf 2.7.7 2. 新建JavaProject 3. 添加jar包,将apache cxf下面lib里面的jar包都添加到项目中(可能有 ...
- 图解 HTTP 协议
原文出处: BYSocket (@BYSocket) 一.技术基石及概述 问:什么是HTTP?答:HTTP是一个客户端和服务器端请求和响应的标准TCP.其实建立在TCP之上的. 当我们打开百度网页时, ...
- springboot集成swagger2,构建优雅的Restful API
swagger,中文“拽”的意思.它是一个功能强大的api框架,它的集成非常简单,不仅提供了在线文档的查阅,而且还提供了在线文档的测试.另外swagger很容易构建restful风格的api,简单优雅 ...
- 多线程本地图片载入演示样例【OpenCV】【Pthread】
Pthread barrier的简单使用演示样例: C++代码例如以下: // ThreadingLoadImages.cpp : 定义控制台应用程序的入口点. // #include "s ...
- jQuery的deferred对象详解(转)
jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...