上篇文章我们初步的接触了怎么创建游戏物体的功能组件代码,这篇文章我们将会详细的讲解这个代码是怎么被Unity使用的,以及我们如何编写在Inspector上可以展示参数的功能组件。
Unity反射调用声明周期函数
在上一章中,我们先硬灌输了一个Start函数会被Unity在适当的时机调用的知识,但是这并不符合我们的常识,一个函数被调用,肯定有类似这样一个代码:
classA.Start();
但是Unity中我们的组件类里面却并不需要这样的代码就能被Unity调用,甚至这个Start函数还是private访问控制的,正常手段根本无法从外部调用。
所以Unity使用的是C#语言的特性:反射(Reflection)。
听起来好像很厉害,其实就是编译器记录了你编写的代码的内容,然后代码可以通过反射这样一个功能知道你写了哪些函数,哪些变量,甚至调用函数,改变变量的值等操作。
是不是还没懂?没事,我们手动来实现一下,因为涉及到指针,C#不太直观,我们换回C++来做示例:
class Test
{
private:
void Func() {}
};
Test t;
t.Func(); // <-- 错误,你无法调用到private下的成员函数
这里我们新定义一个Test类,给了一个Func成员函数,但是是private访问控制的,所以正常情况,我们无法通过Test的实例调用到这个Func函数。
另一方面,如果了解了函数指针,我们是能知道类的成员函数也是有指针的,所以我们只需要将类的成员函数作为指针保存在一个我们够得到的地方,这样我们就可以调用了,让我们来一些魔法:
#include <iostream>
class Test
{
public:
// 为了方便,我们将Func函数指针的类型换个名字叫MemberFunctionPointerType
typedef void (Test::*MemberFunctionPointerType)();
// 定义一个public函数来获取私有的成员函数指针
MemberFunctionPointerType GetFuncPointer() { return &Test::Func; }
private:
void Func() { std::cout << "Hello world!"; }
};
int main() {
Test t;
auto memberFunc = t.GetFuncPointer();
// 调用获取到的私有函数指针
(t.*memberFunc)();
return 0;
}
运行这个代码,你可以看到输出
1万+



被折叠的 条评论
为什么被折叠?



