学习笔记:在unity中理解C#委托(一)

it2025-06-26  6

一,什么是委托 1.概念

一个委托(delegate)是一种类(Class),可以指向一个或多个方法。是一种引用类型的数据类型。 当你实例化委托后,这个实例,可以存储其他类型兼容的方法的引用。 你可以通过委托类型的实例,间接调用这些方法。

2.通俗的说

委托是一种数据类型,这个类型的实例可以保存多个方法,可以调用这个实例去调用保存在内部的方法。

二,在unity中示范一下

1.不用委托 首先,我在unity中放了个小狐狸素材。 然后为小狐狸创建了一个C#脚本,包含三个方法。

using UnityEngine; using System; public class player : MonoBehaviour { private SpriteRenderer sp; private void Start() { sp = GetComponent<SpriteRenderer>(); } private void Update() { if (Input.GetKeyDown(KeyCode.Space)) { Blink(); ChangeColor(); Log(); } } public void Blink() //更换位置 { Vector2 Pos = transform.position; Pos.x = UnityEngine.Random.Range(-5f, 5f); transform.position = Pos; } private void ChangeColor() //变色 { sp.color = new Color(UnityEngine.Random.value, UnityEngine.Random.value, UnityEngine.Random.value); } private void Log() //控制台打印 { Debug.Log("Current Time is :" + DateTime.Now); } }

那么现在的情况是,按下空格键时Input.GetKeyDown(KeyCode.Space) 会执行三个方法Blink(),ChangeColor(),Log() 即,1.小狐狸横坐标随机移动,2.小狐狸随机变色,3.控制台输出时间,如图: 通过概念知道了,委托类型实例,是可以封装方法的,条件是这些方法的返回值和参数类型,和此自定义委托的返回值和参数类型一致。我们现在看到了Blink(),ChangeColor(),Log()这三个方法都是无参,返回值都是void,那么试着做一下,看看怎么用委托实例来封装这三个方法达成同样的效果。

2.用委托试试 首先我们要先定义一个委托类型,这个委托类型为了封装上文的三个方法,返回值和参数列表必须是一致的。所以我们创建返回值是void,无参的委托类型。

创建委托类型MyDelegate,创建此类型的实例mydelegate01:

public delegate void MyDelegate(); MyDelegate mydelegate01;

往mydelegate01中存入三个方法

private void OnEnable() { mydelegate01 = Blink; mydelegate01 += ChangeColor; mydelegate01 += Log; }

这里我将此步骤放入OnEnable()方法中,在unity生命周期中,OnEnable()方法在update()前执行,并且执行一次。(这里并不严谨,但是先不做讨论)

将以前的update()方法中三个方法注释掉,调用委托

private void Update() { if (Input.GetKeyDown(KeyCode.Space)) { mydelegate01(); //Blink(); //ChangeColor(); //Log(); } }

回到unity,执行测试 这边我们看到最终的效果是一样的,三个方法顺利执行

三,有关内存泄漏 在委托引用一个实例方法(非static,隶属于对象)的时候,那么实例方法的对象就必须存在在内存当中,即便没有其他引用变量引用这个对象,这个对象的内存也无法释放,因为一旦释放,委托就不再能够间接调用对象的方法了。 所以,委托可能导致内存泄漏(memory leak)

先整理到这,下一章讨论委托的实际使用方法。 文章参考,整理于:B站【委托•语法篇】. 在这边感谢BeaverJoe老师,感兴趣的各位请点击原视频并一键三连,谢谢各位!

最新回复(0)