在用Unity的时候一直有一个比较困惑问题,继承自MonoBehaviour脚本的Awake(),Start(),Update()等这些函数是怎样被调用的。今天阅读了下Unity的代码了解了其中的调用原理,然后自己写了一个sample来模拟Unity中的调用方式。
Unity的引擎是用C++实现的,自己实现的MonoBehaviour的脚本却是CS脚本。所以这里就涉及到C++调用CS函数的过程。Unity中用的Mono的Framework来实现在C++调用CS脚本,不多说直接上sample就懂了。
测试环境: macOS 10.12.3 , mono 4.8.0
有一个注意的地方就是必须设置好PKG_CONFIG_PATH环境变量,不然gcc在链接exe文件时候会报错,我是这样配置的: export PKG_CONFIG_PATH=/Library/Frameworks/Mono.framework/Versions/Current/lib/pkgconfig/
1 |
|
编译MonoBehaviour.cs生成MonoBehaviour.exe 或者 MonoBehaviour.exe.dll (此处我直接生成exe文件)
mcs MonoBehaviour.cs
然后实现C++层调用代码(此处是根据mono的官方文档和官方的sample来写的)
1 |
|
编译InvokeMonoBehaviour.c生成了a.out文件
gcc InvokeMonoBehaviour.c `pkg-config –cflags –libs mono-2`
然后执行a.out文件
./a.out
可以看到terminal中输出:
1 |
|
当我们编译了InvokeMonoBehaviour.c之后我们再次编辑MonoBehaviour.cs就不需要再编译InvokeMonoBehaviour.c文件就可以加载最新编译出的exe文件,这样还是比较方便的。
整个调用过程就是这样的。在Unity中我们编写的CS脚本被编译成dll存放在项目根目录的Library/ScripAssemblies目录下面(Editor模式),Unity引擎内部封装了一个Manager来专门管理和加载这些dll。加载的方式和上面sample的方式是一样的。