unity3d 委托委托和事件的区别

委托与事件(散分)
[问题点数:100分,结帖人sx_lxh]
委托与事件(散分)
[问题点数:100分,结帖人sx_lxh]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2005年12月 总版技术专家分月排行榜第二
2005年12月 .NET技术大版内专家分月排行榜第一2005年11月 .NET技术大版内专家分月排行榜第一
匿名用户不能发表回复!|Unity中的委托和事件
Unity中的委托与事件
&&东方喵(译)&
目的:本教程的目的是了解如何在Unity中使用和实现委托和事件。
如果你喜欢我以前的关于单例的教程,这是系列教程中的第二篇,学习如何使用unity发挥出其充分的潜力,并在unity中编写有效率的代码。
委托和事件是#C#语言非常强大的功能,它有助于在unity里编写高效的、干净的代。
委托是一个方法的引用指针。它允许我们将方法作为一个变量并传递方法作为回调函数的一个变量。
当它被调用,它通知所有的引用方法,他们背后的基本思想和订阅杂志是完全相同的。
任何人都可以订阅服务,他们将在正确的时间自动接收更新。
我知道在这个时候一切似乎很混乱,只是等待一切都会很清楚,当开始做编码。
委托的类型:
Single Delegate :
单例委托:
It can reference to only single method at a time.
在同一时间只能引用单例方法一次。
Multicast Delegate :
多播委托:
It can store the reference of multiple methods at a
它可以同时存储多个引用方法。
我们看到这种动作中,创建新的脚本命名delegatehandler并挂载到空的游戏体上,并粘贴下面的代码:
现在创建游戏对象&
3D对象&球体并创建新的脚本命名objectcontroller并挂载在球体上并添加下面的objectcontroller类代码:
现在在检视面板中,把按钮事件拖“OnButtonClick”委托方法中达到点击播放。
如果我们点击按钮,会看到它会调用被分配的方法。在这种方式中,任何类都可以监听onbuttonclick委托并得到一个回调,当被调用。现在我希望弄明白他的原理。
但这种实现容易出错,正如我们前面所诉说的,有两种类型的引用,所以如果我们使用单播多播委托引用选项后,它会重置现有调用方法的列表。
现在创建一个新的“changerotation”方法改变“objectcontrollerclass”的启动方法,如下。
然后运行unity,你会发现现在ChangePosition&和&ChangeColor不会被调用,只有changerotation代码将运行,这是因为赋值运算符将重置现有的调用列表,如果多个类监听相同的引用,这种情况是很难去跟踪的,为了避免这种情况,我们使用事件。
事件添加了一个抽象的抽象层和对委托的保护,这种保护防止委托的委托造成重置委托以及调用列表。事件只允许在调用列表中添加和删除方法。
把DelegateHandler 类修改如下
现在如果你回到unity编辑器,它将显示错误消息“在类型`
DelegateHandler”之外使用时,事件`DelegateHandler.buttonClickDelegate”只能出现在+
=或-=的左边。
在Start方法如下改变来消除错误,别忘了在OnDisable销毁方法,否则,它将内存泄露。
我希望现在你对委托和事件有更好的理解。
Conclusion :总结:
Delegates and Events help us to write modular and reusable
委托和事件帮助我们编写模块化和可重用的代码。
Always use Events together with Delegates for safety.
为了安全,总是将委托与时间一起使用。
Do not forget to unsubscribe otherwise, it will lead to memory
不要忘记解除监听,否则,它会导致内存泄漏。
原文作者:UG
原文链接:&
&http://www.unitygeek.com/delegates-events-unity/
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。猫捉老鼠是一个典型的观察者模式的实现案例,在其中加入委托与事件的程序实现,将会提高代码的一个可读性,其下是代码实现:
创建一个Cat类:
using System.Collections.G
using System.Diagnostics.C
using System.L
using System.T
using System.Threading.T
namespace 猫捉老鼠
/// &summary&
/// 定义一个猫类
/// &/summary&
public string
public string
Cat(string name, string color)
this.name =
this.color =
/// &summary&
/// 定义猫来了状态
/// &/summary&
public void CatComing()
Console.WriteLine(color+"这个"+name+"来了,喵喵猫~~~");
if (CatCome != null)
CatCome();
/// &summary&
/// 定义一个事件
/// &/summary&
public event Action CatC
创建一个mouse类:
using System.Collections.G
using System.L
using System.T
using System.Threading.T
namespace 猫捉老鼠
/// &summary&
/// 定义一个老鼠类
/// &/summary&
class mouse
public string
public string
public mouse(string name, string color,Cat cat)
this.name =
this.color =
cat.CatCome += this.RunA//将猫自身的方法注册进老鼠中
public void RunAway()
Console.WriteLine(color+"这个"+name+"的跑了~~~");
在program类中实现:
using System.Collections.G
using System.L
using System.T
using System.Threading.T
namespace 猫捉老鼠
class Program
static void Main(string[] args)
Cat cat = new Cat("老虎猫", "蓝色");
mouse mouse1=new mouse("米老鼠","灰色",cat);
cat.CatCome += mouse1.RunA
mouse mouse2 = new mouse("唐老鸭", "黑色",cat);
cat.CatCome += mouse2.RunA
mouse mouse3 = new mouse("任意猫", "任意色",cat);
cat.CatCome += mouse3.RunA
cat.CatComing();//猫的状态发生改变
Console.ReadKey();
完成整个案例的开发。
阅读(...) 评论()事件/委托机制(event/delegate)(Unity3D开发之十七)
Delegate作用我就不多说了,Unity中可以直接使用EventHandler实现事件委托,咱们直接事例吧。
一、场景物体移动结束后事件监听
假如PlayerControl,移动结束后触发MoveComplete事件。
using UnityE
using System.C
public class PlayerControl : MonoBehaviour {
public event EventHandler MoveC
// Use this for initialization
void Start () {
// Update is called once per frame
void Update () {
if (Input.GetMouseButtonUp(0)) {
// Test logic for PlayerMoveComplete
PlayerMoveComplete();
void PlayerMoveComplete()
if (MoveComplete != null) {
MoveComplete(this, EventArgs.Empty);
事件接收处理
using UnityE
using System.C
public class GameManager : MonoBehaviour {
public static GameManager I
public PlayerControl playerC
void Awake ()
// check there isn't more than one instance of the GameManager in the scene
if(Instance != null){
Debug.LogError(More than one GameManager found in the scene);
// set the global instance
Instance =
// Use this for initialization
void Start () {
playerControl.MoveComplete += HandleMoveC
void HandleMoveComplete (object sender, EventArgs e)
Debug.Log(MoveComplete:);
// Update is called once per frame
void Update () {
这里由于使用的EventHandler实现,所以在事件中无法传递自定义参数。
二、自定义Event,事件中传递自定义参数
1、自定义EventArgs
using UnityE
using System.C
public class PlayerMoveEventArgs : EventArgs {
public PlayerMoveEventArgs(string message)
this.message =
public string Message
public delegate void MoveCompleteHandle(object sender, PlayerMoveEventArgs e);
那么我们修改下PlayerControl
using UnityE
using System.C
public class PlayerControl : MonoBehaviour {
public event EventHandler MoveC
public event MoveCompleteHandle CustomMoveC
// Use this for initialization
void Start () {
// Update is called once per frame
void Update () {
if (Input.GetMouseButtonUp(0)) {
// Test logic for PlayerMoveComplete
PlayerMoveComplete();
void PlayerMoveComplete()
if (MoveComplete != null) {
MoveComplete(this, EventArgs.Empty);
if (CustomMoveComplete != null) {
CustomMoveComplete(this, new PlayerMoveEventArgs(Move: + this.name));
处理事件的我们也修改下
using UnityE
using System.C
public class GameManager : MonoBehaviour {
public static GameManager I
public PlayerControl playerC
void Awake ()
// check there isn't more than one instance of the GameManager in the scene
if(Instance != null){
Debug.LogError(More than one GameManager found in the scene);
// set the global instance
Instance =
// Use this for initialization
void Start () {
playerControl.MoveComplete += HandleMoveC
playerControl.CustomMoveComplete += HandleCustomMoveC
void HandleCustomMoveComplete (object sender, PlayerMoveEventArgs e)
Debug.Log(HandleCustomMoveComplete: + e.Message);
void HandleMoveComplete (object sender, EventArgs e)
Debug.Log(MoveComplete:);
// Update is called once per frame
void Update () {
ok,现在你可以自由的玩耍了。

我要回帖

更多关于 unity3d 委托 的文章

 

随机推荐