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

  1. BroadcastMessage(<接收函数名>)         广播消息
  2. SendMessage(<接收函数名>)                 发送消息
  3. 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

  1. UnityAction本质上是delegate,且有数个泛型版本(参数最多是4个),一个UnityAction可以添加多个函数 (多播委托)。

  2. 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:

  1. 在脚本中通过AddListener()添加的是一个0个参数的delegate(UnityAction)回调。是不可序列化的,在Inspector中是无法看到的。这种Listener是常规Listener。
  2. 在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的更多相关文章

  1. ubuntu14.04, Cloudera Manager 5.11.1, cdh5.11.1 postgresql离线部署

    最近一段时间团队接到的项目需要处理的数据量非常大,之前的处理方式难以满足现有需求.最近两周前前后后折腾了不少,在搭建了hadoop+hbase+hive+spark的一个集群后,由于感觉管理和监控太麻 ...

  2. zepto源码学习-04 event

    之前说完$(XXX),然后还有很多零零碎碎的东西需要去分析,结果一看代码,发现zepto的实现都相对简单,没有太多可分析的.直接略过了一些实现,直接研究Event模块,相比JQuery的事件系统,ze ...

  3. [Node.js] 04 - Event and Callback

    回调函数 回调函数在完成任务后就会被调用,Node 使用了大量的回调函数,Node 所有 API 都支持回调函数. 异步读取文件的回调函数: var fs = require("fs&quo ...

  4. 本人AI知识体系导航 - AI menu

    Relevant Readable Links Name Interesting topic Comment Edwin Chen 非参贝叶斯   徐亦达老板 Dirichlet Process 学习 ...

  5. 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 ...

  6. 理解Mac和iOS中的 Event 处理

    根据现在的理解,我把event处理分为5部分,第一是,Event处理的Architecture:第二是,Event的Dispatch到first responder之前: 第三是,Event从firs ...

  7. Weak Event Patterns

    https://msdn.microsoft.com/en-US/library/aa970850(v=vs.100).aspx In applications, it is possible tha ...

  8. Event Managers

    Some PLF-based controls expose a convenient facility for temporarily disabling their events and for ...

  9. 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 ...

随机推荐

  1. 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 ...

  2. linux和CentOS下网卡启动、配置等ifcfg-eth0教程(转自)

    转自:http://www.itokit.com/2012/0415/73593.html it 动力总结系统安装好后,通过以下二个步骤就可以让你的系统正常上网(大多正常情况下).步骤1.配置/etc ...

  3. Linux学习笔记12—磁盘管理

    一.查看磁盘或目录的容量 1.  df命令 作用:查看已挂载磁盘的总容量.使用容量.剩余容量等,可以不加任何参数,默认是按k为单位显示的 参数: -I : 查看inodes使用状况 -h: 使用合适的 ...

  4. Python:内置函数

    Python所有的内置函数     Built-in Functions     abs() divmod() input() open() staticmethod() all() enumerat ...

  5. WinPython

    WinPython   http://winpython.github.io/

  6. Apache CXF JAX-WS example

    1. 环境说明 jdk 1.6.0_29 apache cxf  2.7.7 2. 新建JavaProject 3. 添加jar包,将apache cxf下面lib里面的jar包都添加到项目中(可能有 ...

  7. 图解 HTTP 协议

    原文出处: BYSocket (@BYSocket) 一.技术基石及概述 问:什么是HTTP?答:HTTP是一个客户端和服务器端请求和响应的标准TCP.其实建立在TCP之上的. 当我们打开百度网页时, ...

  8. springboot集成swagger2,构建优雅的Restful API

    swagger,中文“拽”的意思.它是一个功能强大的api框架,它的集成非常简单,不仅提供了在线文档的查阅,而且还提供了在线文档的测试.另外swagger很容易构建restful风格的api,简单优雅 ...

  9. 多线程本地图片载入演示样例【OpenCV】【Pthread】

    Pthread barrier的简单使用演示样例: C++代码例如以下: // ThreadingLoadImages.cpp : 定义控制台应用程序的入口点. // #include "s ...

  10. jQuery的deferred对象详解(转)

    jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...