Untiy-委托[delegate]和事件[event]详解和区别(一)

                  Untiy-委托[delegate]和事件[event]详解和区别(一)


目录

1.博文介绍

2.委托(delegate)

3.委托的用法

4.资源包的下载

5.结语


1.博文介绍

       简单介绍一下本篇文章,博主之前对委托和事件一直没有一个很透彻的理解,看了大量的文章和视频,总是不求甚解,博主的学习方式一般是先知道其怎么用,再去了解为什么,学习的目的就是知其然,且知其所以然。后来在油管看了些视频对委托和事件有了一个略微透彻的理解,写下这篇文章的目的,一是为了记录,二便是希望利用直白的语言来分享给有所需要的人。

       本篇文章可能更多的是博主的个人累述,文字可能比较冗余,但是博主希望你能够静下心看完,博主认为,本篇文章对于希望理解委托和事件用法以及差别的人来说将会很有帮助。

2.委托(delegate)

       什么是委托呢?网上对于委托的定义和介绍文章多不胜数,博主就不做介绍了,博主只解说一下对委托的个人理解。

顾名思义啊,委托委托,就是将你需要做的事情去委托给一个代理执行的东西,这个代理会帮你执行你想要执行的操作。

具体一点举个例子!

A,B,C三个脚本当中均有一个相同返回值,相同参数的方法。

A     :void FucOne(string str){ }

B     :void FucTwo(string str){ }

C     :void FucThree(string str){ }

我在D脚本中,建立了一个委托MyDelegate,并实例该委托

D: public delegate void MyDelegate(string str) --声明委托的写法 关键字 delegate 带有返回值和参数

     public static MyDelegate myDelegate;   --这里设为静态方便调用

注意:你如果想要代理方法,声明的委托必须和想要代理的方法有相同的返回值和参数,这里是无返回值,一个字符串参数

我在ABC脚本当中分别将当中的方法委托介绍给了D脚本的myDelegate。

A     :void Start() { D.myDelegate +=FucOne; }

B     :void Start() { D.myDelegate +=FucTwo; }

C     :void Start() { D.myDelegate +=FucThree; }

       如此以来,要展现委托的强大之处了,我只用调用myDelegate,那么ABC当中FucOne,FucTwo,FucThree都会执行。好了各位读者现在应该对委托的用法有了一个略微宏观的了解,现在我们深入一点。

       这个时候你可能会有疑问,为什么要找一个中间人一样的玩意去帮你执行,我直接去调ABC的方法不就可以了吗,这个也是博主学习阶段的一个疑问,博主认为啊,你仔细想一下,如果是我在D脚本里面要执行ABC的方法,我需要在D当中实例ABC三个脚本,然后再调用方法,少了还可以啊,如果你需要在E,F,G,H,J,K,L脚本里都调用呢?你就需要在这么多的脚本里面全部去实例化一遍,这***多麻烦啊,现在你只需要在E,F,G,H,J,K,L里面调用一下D的myDelegate就可以执行ABC的方法了,是不是代码瞬间就变得很简洁了。

3.委托的用法

下面我们就在Unity内写一个小情景来展示委托的具体用法。

情景: 小明有两个状态 出生 死亡,出生的时候小红,小花,小蓝会来祝贺掏份子钱,但是中间的时候小明和小蓝打架了,所以小明死的时候小蓝不会来哭丧,只有小红和小花来。

Ming: 在小明脚本当中我们声明了一个带有一个string参数的委托MyDelegate,并且实例化为myDelegate,一个出生方法,Birth( ),这个方法宣告小明出生,并且调用,myDelegate("Birth"),这里需要注意,判断myDelegate是否空,如果没有注册的方法的话,直接调用会报空的。死亡方法Death( ),这个方法宣告了小明死亡,并调用myDelegate("Death")。这里参数不同是为了给注册的方法来判断小明到底是出生还是死亡。点击A小明出生,点击D小明死亡。

using UnityEngine;

/// <summary>
/// 小明脚本
/// Date:2018/11/4
/// Author:Mr.Sun
/// </summary>
public class Ming : MonoBehaviour
{

	public delegate void MyDelegate(string str); //声明委托

	public static MyDelegate myDelegate; //实例委托,静态方便调用
	
	// Update is called once per frame
	void Update () {

		if (Input.GetKeyDown(KeyCode.A))
		{
			Birth(); //点A出生
		}
		else if (Input.GetKeyDown(KeyCode.D))
		{
			Death(); //点D死亡
		}
		
	}

	/// <summary>
	/// 小明出生
	/// </summary>
	void Birth()
	{
		print("我出生啦,我叫小明");

		if (myDelegate!=null)
		{
			myDelegate("Birth");
		}
	}


	/// <summary>
	/// 小明死亡
	/// </summary>
	void Death()
	{
		print("我死啦,我是小明");
		
		if (myDelegate!=null)
		{
			myDelegate("Death");
		}
	}
}

Hua:小花的脚本就很简单了,只有一个祝福的方法Speak,这个方法和小明声明的委托形式是一样的无返回值,有一个字符串参数。然后在Start当中将Speak方法委托给了小明的myDelegate就可以了。

using UnityEngine;

/// <summary>
/// 小花脚本
/// Date:2018/11/4
/// Author:Mr.Sun
/// </summary>
public class Hua : MonoBehaviour {

	// Use this for initialization
	void Start ()
	{
		Ming.myDelegate += Speak; //注册

	}
	

	/// <summary>
	/// 这个方法委托给了Ming.myDelegate去执行
	/// </summary>
	/// <param name="str"></param>
	void Speak(string str)
	{
		if (str=="Birth")
		{
			print("小花:祝贺祝贺,我的份子钱1000块");
		}
		else if (str=="Death")
		{
			print("小花:死样,让你浪!!");
		}
	}
}

Hong:和小花基本相同,只有祝词不同

using UnityEngine;

/// <summary>
/// 小红脚本
/// Date:2018/11/4
/// Author:Mr.Sun
/// </summary>
public class Hong : MonoBehaviour {
	

	// Use this for initialization
	void Start ()
	{
		Ming.myDelegate += Speak; //注册

	}

	/// <summary>
	/// 这个方法委托给了Ming.myDelegate去执行
	/// </summary>
	/// <param name="str"></param>
	void Speak(string str)
	{
		if (str=="Birth")
		{
			print("小红:祝贺祝贺,我的份子钱200块");
		}
		else if (str=="Death")
		{
			print("小红:啊!!小明你死的好惨啊!");
		}
	}
}

Lan:这个脚本也是基本形式相同,但是注意啊,没有死亡判断,如果小明是死了,这里小蓝是不会输出哭丧的

using UnityEngine;

/// <summary>
/// 小蓝脚本
/// Date:2018/11/4
/// Author:Mr.Sun
/// </summary>
public class Lan : MonoBehaviour {

	// Use this for initialization
	void Start ()
	{
		Ming.myDelegate += Speak; //注册

	}
	
	/// <summary>
	/// 这个方法委托给了Ming.myDelegate去执行
	/// </summary>
	/// <param name="str"></param>
	void Speak(string str)
	{
		if (str=="Birth")
		{
			print("小蓝:祝贺祝贺,我的份子钱500块");
		}
	}
}

 

好了情景脚本都结束了,我们看一下输出结果把!

点击键盘A:

点击键盘D:

如此一来,你想要让更多的人知道小明出生或者挂了,你只需要在其他脚本里面把需要在小明出生或者死亡时执行的方法通过+=的方式注册给Ming的myDelegate就可以了,怎么样这样一个小例子是不是让你更加理解委托了。

这里有一点注意,如果你不想要某个脚本去继续监听小明的状态,你只需要接触注册就可以了,使用-=方式就可以了:

例子:Ming.myDelegate -= Speak; //解除注册

注意:如果你声明了一个委托delegate,你可以使用 = 符号来注册方法,但是这样你只能注册一个方法,你如果想要注册很多方法,就必须使用 += 符号来注册方法,还有一点就是,无论你在任何地方调用delegate,他的所有注册方法都会执行,就比如上边的例子,你在小红的脚本里面调用myDelegate("Birth"),那么小红和小明还有小蓝都会以为小明出生了,并执行方法。

 

4.资源包的下载

例子代码在这里,和上述相同,有需要的可以下一下看看

https://download.csdn.net/download/mr_sun88/10762267

 

5.结语

       博主本身是想要将delegate和event结合在一起来告诉大家的,但是我觉得文章有点长,在加上字比较多,怕各位看的比较疲惫,所以我就分开来写了,当然单独看一篇文章也是没有问题的,不过博主希望你能够把这个系列看完。

第二章推送:https://blog.csdn.net/Mr_Sun88/article/details/83688255

       另博主能力有限,文中若有错误的地方期望各位看家可以指点交流。

       QQ交流群:806091680(Chinar)

       该群为CSDN博主Chinar所创,推荐一下!我也在群里!

       本文属于原创文章,转载请著名作者出处!!!!!

以下是一个基本的Unity登录和完成UI的代码示例: ```csharp using UnityEngine; using UnityEngine.UI; public class LoginUI : MonoBehaviour { public InputField usernameInput; public InputField passwordInput; public Button loginButton; private void Start() { // 给登录按钮添加点击事件 loginButton.onClick.AddListener(OnLoginButtonClicked); } private void OnLoginButtonClicked() { // 获取输入的用户名和密码 string username = usernameInput.text; string password = passwordInput.text; // 检查用户名和密码是否有效,如果有效则登录成功,否则提示错误信息 if (IsValidLogin(username, password)) { // 登录成功,切换到完成UI SceneManager.LoadScene("CompleteUI"); } else { // 登录失败,提示错误信息 ShowErrorMessage("Invalid username or password!"); } } private bool IsValidLogin(string username, string password) { // 在这里检查用户名和密码是否有效 // 如果有效则返回 true,否则返回 false return true; // 这里暂时返回 true,表示用户名和密码都有效 } private void ShowErrorMessage(string message) { // 在这里实现显示错误信息的逻辑 } } public class CompleteUI : MonoBehaviour { public Text welcomeText; public Button completeButton; private void Start() { // 在这里设置欢迎文本,例如:“欢迎,XXX!” // 可以从登录UI中获取用户名,然后显示在欢迎文本中 // 给完成按钮添加点击事件 completeButton.onClick.AddListener(OnCompleteButtonClicked); } private void OnCompleteButtonClicked() { // 在这里实现完成UI中的逻辑,例如保存数据、提交成绩等等 // 如果完成成功,则可以返回到登录UI或者切换到其他场景 } } ``` 在上面的代码中,我们创建了两个脚本:`LoginUI`和`CompleteUI`。`LoginUI`处理登录UI的逻辑,包括获取用户名和密码、检查用户名和密码是否有效、显示错误信息等等。`CompleteUI`处理完成UI的逻辑,包括设置欢迎文本、保存数据、提交成绩等等。 在`LoginUI`中,我们使用`InputField`组件获取用户名和密码的输入,使用`Button`组件添加登录按钮的点击事件。当用户点击登录按钮时,我们调用`OnLoginButtonClicked`方法,获取用户名和密码,并调用`IsValidLogin`方法检查用户名和密码是否有效。如果用户名和密码都有效,则切换到完成UI,否则提示错误信息。 在`CompleteUI`中,我们使用`Text`组件设置欢迎文本,使用`Button`组件添加完成按钮的点击事件。当用户点击完成按钮时,我们调用`OnCompleteButtonClicked`方法,完成完成UI中的逻辑,例如保存数据、提交成绩等等。 当然,这只是一个基本的示例,你可以根据自己的需求对代码进行修改和扩展。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值