宇宙第一小正太\ (o)/~萌量爆表求带飞=≡Σ((( つo)つ~ dalao们点个关注呗~
如果您尚且对“委托”的概念感到陌生,小熊在本文的末尾“福利时间”,稍微讲到了这个概念,(虽然可能不太对 )微软的官方文档本熊建议你可以去看看,那个写的应该会比我专业很多QAQ。不过,我在本文的末尾,同样还更新了C++的一个“模仿”C#委托的程序,希望对您有帮助。
问题描述:
最近笔者在研究Unity3D引擎的时候,发现,跨脚本委托的时候,无法委托,而且无法绑定(注册的委托函数,引擎的控制台会提示:找不到实例),然儿在VS2019下面是提示NO Problem,没有错误。
源代码:
GLEventSyste.cs 设计初衷:定义一个委托,然后向别的脚本发送消息,如果使用SendMessage也不是不可以,但是我不喜欢,比较学习算法的,一切都是向着效率看齐对吧hhh。 别的脚本的函数绑定在了MDChain 上面,这样当我调用一次MDChain ,那么其他的被绑定的函数都会被执行。
public class GLEventSystem : MonoBehaviour {
public delegate void MessageDelegate(int a);
public MessageDelegate MDChain = null;
public static int a;
void printM(int a) {
print("现在发出消息的是全局脚本系统哦");
}
private void Awake() {
MDChain += printM;
}
void Start() {
MDChain(9);
}
}
S.cs 设计初衷:用来绑定上面脚本中的委托函数。 最关键的地方就在于,在本脚本中,我将本脚本的PPPP 函数绑定在了MDChain 这个委托上面。
public class S : MonoBehaviour {
private void Awake() {
if (_GLEventSystem == null) {
_GLEventSystem = GameObject.Find("GLEventSystem");
if (_GLEventSystem == null)
Debug.LogError("找不到全局控制器,未能注册全局消息系统QAQ");
}
}
void Start() {
if (_GLEventSystem != null) {
Debug.Log("已经跨脚本绑定啦");
_GLEventSystem.GetComponent<GLEventSystem>().MDChain += this.PPPP;
}
}
void PPPP(int a) {
Debug.Log("嘤嘤嘤,你这个是跨脚本调用了哦!");
}
}
Unity层级视图
问题复现:
当运行的时候: 我们期望的结果:
解决办法:
我百思不得其解,后来我想明白了。 其实就是脚本的调用顺序的问题。 因为不同脚本的调用时许是不同的,所以这就会引发一些调用方面的问题了。 所以,只需要 让S脚本先去执行,先去绑定,然后这样就可以被调用了。靠,卡住了本熊6个小时啊,本熊做梦都在想着这个问题hhh。
小福利Time:
对于不知道指针概念的同学: 本熊的独家理解“委托”:委托就是一个变量。 我们知道变量有int,float这些,但是有没有想过,我们现在有一个变量,它的变量就是一个函数的声明。 比如现在:internal delegate void FBES(); 那么internal 是范围修饰符,delegate 意味着它是一个委托,FBES 意味着这个是新的一种类型的变量。这个新类型指的是,它是一个函数,也就是这个函数它的返回值是void 然后他的参数是int 然后FBES fbes = null; 或者FBES fbes = FBES(你想要绑定函数的函数名); 定义了一个类型为FBES 的fbes 的变量。 现在这个变量它就可以用来传递函数了。而且是你绑定的函数。 比如:现在我想传入一个函数,作为另外一个函数的参数。 例子如下:
void QAQ我的参数是函数(int a,int b,FBES Function){
}
现在QAQ我的是参数是函数 的这个函数的第三个参数就是一个是“函数”变量的参数了。 然后我们就可以在这个函数里面,使用这个Function 变量,来调用另一个函数啦。
一下是代码全部样貌:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class S2 : MonoBehaviour {
internal delegate void FBES();
void QAQ我的参数是函数(int a, int b, FBES Function) {
Function();
}
void 我的专业是にほ語() {
Debug.Log("但是日语学不会就转计算机了呜呜呜");
}
private void Start() {
QAQ我的参数是函数(1, 2, 我的专业是にほ語);
}
}
对于知道指针概念的同学: 我觉得,C井的委托挺像C++里面的指针的QAQ。(虽然肯定不是一个东西啦(比如C++对指针没有重载+=运算符),但是我真心觉得他们好像呐,也不知道我理解的对不对。) C井: internal delegate void FBES(); C++: typedef int(FallBcak)(int); 下面是C++的代码全貌:
#include <iostream>
using namespace std;
typedef int(FallBcak)(int);
int SayHello(int a);
void MyCanShuShiHanShu(FallBcak);
int main() {
FallBcak* p = SayHello;
p(3);
MyCanShuShiHanShu(SayHello);
return 0;
}
int SayHello(int a) {
cout << "你好呀小千同学,传入的参数是:" << a << endl;
}
void MyCanShuShiHanShu(FallBcak Fun) {
Fun(20020109);
}
我水平也不是太高,就是做个自我记录,我摸索Unity是从7月中旬开始的,到今天还没有满一个月,C井学的更是一塌糊涂,还要继续加油www
|