首页 > 其他分享 >Unity中的委托

Unity中的委托

时间:2023-01-10 21:56:36浏览次数:29  
标签:projectWindowItemOnGUI return 委托 EditorApplication Unity 源码 public

目录

目录

基础介绍

在c#中委托是一个类型安全的,面向对象的函数指针。
委托的优点是它允许程序员在运行时动态地选择所需要调用的方法。
本文将从Unity的源码出发,分析委托的作用。

为什么用委托?

委托常用的场景有:

  • 回调函数:可以将一个委托作为参数传递给另一个函数,这样你就可以在运行时动态决定哪个方法应该被调用。
  • 事件处理:委托可以用于实现事件,在 C# 中,事件是一种特殊类型的委托,可以让多个对象监听并响应特定事件。特别适合用来作UI相应后的操作。
  • 多线程编程:可以使用委托来在多线程中调用函数。
  • 异步编程:可以使用委托来在异步方式中调用函数。

源码中的委托

针对委托的常用场景,找了下Unity源码中的例子。

用于回调函数

排序方法就是个很好的例子。
传一个匿名方法(a,b)={return a>b}就是一个委托。
下面是Unity源码中使用委托用于回调函数的例子:

// 这段代码来自UnityEditorInternal.DopeLine
m_Keys.Sort((a, b) => a.time.CompareTo(b.time));
//  这段代码出自UnityEditor.MaterialEditor
matched[i].Sort((s2, s1) =>
{
    var order = (int)((s2 as ShaderDropdownItem)?.fullName.Count(c => c == '/') - (s1 as ShaderDropdownItem)?.fullName.Count(c => c == '/'));
    if (order == 0)
        order = s2.name.CompareTo(s1.name);
    return order;
});

用于事件处理

EditorApplictaion.projectWindowItemCallback演示了委托用于事件处理

public static EditorApplication.ProjectWindowItemCallback 是Project 窗口中每个可见列表项的 OnGUI 事件的委托。

委托在UnityEditor.EditorApplication.cs里被定义:

public sealed partial class EditorApplication{
    // Delegate to be called for every visible list item in the ProjectWindow on every OnGUI event.
    public delegate void ProjectWindowItemCallback(string guid, Rect selectionRect);
    // Delegate for OnGUI events for every visible list item in the ProjectWindow.
    public static ProjectWindowItemCallback projectWindowItemOnGUI;
}

委托对象在UnityEditor.ProjectBrowser里被调用:

void OnGUIAssetCallback(int instanceID, Rect rect)
{
    // User hook for rendering stuff on top of assets
    if (EditorApplication.projectWindowItemOnGUI != null)
    {
        string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(instanceID));
        EditorApplication.projectWindowItemOnGUI(guid, rect);
    }

    if (EditorApplication.projectWindowItemInstanceOnGUI != null)
    {
        EditorApplication.projectWindowItemInstanceOnGUI(instanceID, rect);
    }
}

可以通过给委托添加方法来实现代码的触发,如:

//这是一段伪代码,展示了如何添加委托
{
    static ShowFileExtensions()
    {
        EditorApplication.projectWindowItemOnGUI += ProjectWindowItemOnGUI;
    }
    
    private static void ProjectWindowItemOnGUI(string guid, Rect rect)
    {
        //当Project 窗口中每个可见列表项的 OnGUI 事件发生时,这里的代码会执行
    }
}

组合委托是个好功能,可以更简单地组织代码,并且提高程序的可重用性。
可以使用组合委托来组织多个事件处理程序,如一个按钮点击,触发多个其他函数。

UnityEditor.ProjectBrowser里使用了组合委托,可以方便地添加调试逻辑而不与其他代码耦合:

// Keep for debugging
//EditorApplication.projectWindowItemOnGUI += TestProjectItemOverlayCallback;

其他知识

  • 虽然委托类型声明看上去和方法的生命一样,但它不需要再类内部进行声明,因为它是类型声明。
namespace UnityEngine.Events
{
    // 可以在类外面声明委托
    public delegate void UnityAction<T0>(T0 arg0);

    [Serializable]
    public class UnityEvent<T0> : UnityEventBase
    {
        
    }
}
  • 在使用+=和-=运算符,其实是创建了一个新的委托,这个委托持有委托组合的引用。
  • 调用带返回值的委托,最后一个方法的返回值就是委托的返回值,中间其他方法的返回值都会被忽略。
  • 调用带有引用参数的委托,参数的新值(不是初始值)会传给下一个方法。
  • 委托的几种创建方式:
//基础语法
MyDelegate del = new MyDelegate(obj.TestMethod));
del();

//快捷语法
MyDelegate del2 = (obj.TestMethod);
del2();

//匿名方法(C#2.0引入)
MyDelegate del3 = delegate ()
{
    return;
};
del3();

//lambda表达式(C#3.0引入)
MyDelegate del4 = () =>
{
    return;
};
del4();

//lambda,不加括号也行
int x = 1;
MyDelegate2 del5 = x => { return; };

标签:projectWindowItemOnGUI,return,委托,EditorApplication,Unity,源码,public
From: https://www.cnblogs.com/wenqu/p/17041466.html

相关文章

  • unityShader入门精要 渲染流水线
    应用阶段把数据加载到显存中设置渲染状态调用DrawCall几何阶段顶点着色器顶点着色器需要完成的工作主要有:坐标变换和逐顶点光照坐标变换:就是对顶点的......
  • 关于Unity的Android工程,写文件的问题
    UnityAndroid工程中的写文件在安卓工程下,写入文件可以直接用:File.WriteAllText(UnityEngine.Application.persistentDataPath+"/XXX.txt","文件内容");路径前面没有加“......
  • Unity+Pico 手柄按键控制
    一、定义手柄按键API1、InputDevices.GetDeviceAtXRNode,通过XRNode获取对应的设备;2、XRNode是一个枚举类型,包含LeftEye、RightEye、CenterEye、Head、LeftHand、RightHa......
  • Unity+Pico 响应射线事件
    1、添加组件为了让场景内的物体能够响应射线的操作,需要在该物体上添加“XRSimpleInteractable”组件,并对射线的交互事件编写脚本看,最常用的是“Hover”和“Select”事件......
  • UnityShader入门精要学习 第二章解惑
    困惑什么是OpenGL、DirectX如果开发者直接访问GPU是一件非常麻烦的事情,我们可能需要和各种寄存器、显存打交道。而图像编程接口再这些硬件的基础上实现了一层抽象。Ope......
  • Unity UI显示3D模型,控件与屏幕分辨率不同,导致在屏幕上鼠标点选模型,无法选中模型的问题
    ​UI界面显示3d模型,需要添加模型相机,通过中间RenderTexture来连接相机与界面的承载容器【RawImage】,根据项目在显示时,会对界面做适当调整,但是RawImage的宽和高会产生运行时......
  • Unity优化 - 总览
    基于Unity移动端游戏性能优化简谱-UWA整理而得,不定期更新。细节部分可移步UWA相关博文查阅优化总览Q&A图片放大看不清?A.图片右键->新标签页打开图片->放大B.右键......
  • 【Unity TIL】7. 手动刷新资源
    背景最近的项目,Unity版本是2020.3,电脑是mac,不清楚是哪个的原因,unity经常崩溃。代码敲着敲着就崩溃,关闭了运行时编译代码还是崩,后来就直接关了AutoRefrash,崩溃的问题......
  • [UnityAI]行为树的中断机制
    参考链接:https://www.cnblogs.com/01zxs/p/9863715.htmlhttps://blog.csdn.net/AcmHonor/article/details/123234763https://blog.csdn.net/u012632851/article/details......
  • Unity 2D入门基础教程
    http://www.raywenderlich.com/61532/unity-2d-tutorial-getting-started,作者:ChristopherLaPollo,由Xiaoke翻译,如果用以前版本的Unity做2D游戏,虽然能做,但是......