Unity游戏状态脚本控制思考(二)
来源:互联网 发布:游乐网软件下载 编辑:程序博客网 时间:2024/05/29 11:18
最近忙着项目上线,一摊子事,好久没更了,于是乎补上一更。
上一篇聊到Unity的脚本控制,这一篇就细说下Unity的实现原理.
核心点
C#脚本+Mono+C++
UnityEngine里的核心类似这么写的:
public class Component { private IntPtr native_handle=IntPtr.Zero; [MethodImpl(MethodImplOptions.InternalCall)] public extern static Component[] GetComponents(); [MethodImpl(MethodImplOptions.InternalCall)] public extern static int get_id_Internal(IntPtr native_handle); [MethodImpl(MethodImplOptions.InternalCall)] public extern static int get_tag_Internal(IntPtr native_handle); public int ID { get { return get_id_Internal(native_handle); } } public int Tag { get { return get_tag_Internal(native_handle); } } }
关键的部分我们都是反编译看不到的,看不到的部分都是通过底层C++去实现的,然后通过Mono进行交互(托管代码与非托管代码之间的交互).
对应C++代码是这样的:
struct Component
{
int id;
int tag;
};
Component* Components;uint32_t num_Components;MonoClassField* native_handle_field;MonoDomain* domain;MonoClass* Component_class;//获取属性int ManagedLibrary_Component_get_id_Internal(const Component* component){ return component->id;} //获取tagint ManagedLibrary_Component_get_tag_Internal(const Component* component){ return component->tag;}//获取组件MonoArray* ManagedLibrary_Component_GetComponents(){ MonoArray* array = mono_array_new(domain, Component_class, num_Components); for(uint32_t i = 0; i < num_Components; ++i) { MonoObject* obj = mono_object_new(domain, Component_class); mono_runtime_object_init(obj); void* native_handle_value = &Components[i]; mono_field_set_value(obj, native_handle_field, &native_handle_value); mono_array_set(array, MonoObject*, i, obj); } return array;}int main(int argc, char* argv[]){//------------------------------------------------------------------------------------------------ //例子3:模仿Unity的实现方式 //mono运行时的配置 mono_set_dirs("C:\\Program Files\\Mono\\lib", "C:\\Program Files\\Mono\\etc"); mono_config_parse(NULL); const char* managed_binary_path = "E:\\test\\ManagedLibrary.dll"; //获取应用域 domain = mono_jit_init(managed_binary_path); //加载程序集 MonoAssembly* assembly = mono_domain_assembly_open(domain, managed_binary_path); MonoImage* image = mono_assembly_get_image(assembly); //通过Mono的mono_add_internal_call方法将C#中的接口和C/C++中的具体实现关联起来 mono_add_internal_call("ManagedLibrary.Component::get_id_Internal",reinterpret_cast<void*>(ManagedLibrary_Component_get_id_Internal)); mono_add_internal_call("ManagedLibrary.Component::get_tag_Internal",reinterpret_cast<void*>(ManagedLibrary_Component_get_tag_Internal)); mono_add_internal_call("ManagedLibrary.Component::GetComponents",reinterpret_cast<void*>(ManagedLibrary_Component_GetComponents)); //Component.cs Component_class =mono_class_from_name(image,"ManagedLibrary","Component"); native_handle_field =mono_class_get_field_from_name(Component_class,"native_handle"); num_Components =5; Components = new Component[5]; for(uint32_t i = 0; i < num_Components; ++i) { Components[i].id = i; Components[i].tag = i * 5; } // Main.cs MonoClass* main_class = mono_class_from_name(image, "ManagedLibrary", "Main"); const bool include_namespace = true; MonoMethodDesc* managed_method_desc = mono_method_desc_new("ManagedLibrary.Main:TestComponent()", include_namespace); MonoMethod* managed_method = mono_method_desc_search_in_class(managed_method_desc, main_class); mono_method_desc_free(managed_method_desc); //执行 mono_runtime_invoke(managed_method, NULL, NULL, NULL); //释放应用域 mono_jit_cleanup(domain); //释放组件 delete[] Components; return 0;//--------------------------------------------------------------------------}
着重理解下核心点“C#脚本+Mono+C++”,明白了这个就简单了。
附件
工程源代码
阅读全文
0 0
- Unity游戏状态脚本控制思考(二)
- Unity游戏状态脚本控制思考
- 【Unity 3D】学习笔记二十二:unity游戏脚本(二)
- Unity学习(七):Unity中游戏对象间的访问方法、脚本时间控制
- 【Unity 3D】学习笔记二十一:unity游戏脚本(一)
- 【Unity 3D】学习笔记二十三:unity游戏脚本(三)
- 【Unity 3D】学习笔记二十四:unity游戏脚本(四)
- 【Unity 3D】学习笔记二十五:unity游戏脚本(五)
- 【Unity 3D】学习笔记二十六:unity游戏脚本(六)
- 【Unity 3D】学习笔记二十七:unity游戏脚本(七)
- android 2D游戏开发,引擎设计(二)脚本思考
- Unity 游戏脚本解密
- Unity 游戏脚本
- unity镜头控制脚本
- unity脚本的一些笔记(二)
- Unity脚本的生命周期(二)- 转载
- 【Unity常识】游戏对象及脚本的状态与Start等函数的调用关系
- Unity第一人称控制脚本解析
- 购物车之订单列表
- 如何搭建gerrit服务器进行code review
- 160个练手CrackMe-044
- 3.反向代理-负载均衡
- 在eclipse导入paramiko模块
- Unity游戏状态脚本控制思考(二)
- 大数的阶乘
- 记一次python中使用jinja2模板渲染文本
- 数据结构实验之排序六:希尔排序
- <转>URL编码
- 使用随机森林计算特征重要度
- 快速排序简单实现
- HDOJ 2013 蟠桃记
- java读取excel文件的数字,读取时间