Unity使用C++作为游戏逻辑脚本分析
发表于:2024-11-19 作者:千家信息网编辑
千家信息网最后更新 2024年11月19日,这篇文章主要介绍"Unity使用C++作为游戏逻辑脚本分析",在日常操作中,相信很多人在Unity使用C++作为游戏逻辑脚本分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家
千家信息网最后更新 2024年11月19日Unity使用C++作为游戏逻辑脚本分析
这篇文章主要介绍"Unity使用C++作为游戏逻辑脚本分析",在日常操作中,相信很多人在Unity使用C++作为游戏逻辑脚本分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Unity使用C++作为游戏逻辑脚本分析"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
一、C#和C++的通信
c#和c++的交互,也是非常类似的,c#可以直接的通过P/Invoke的方式来调用c++的函数,而C++调用C#的函数,C++的函数是被封装成DLL来放在Unity的工程文件中的Plugins中,则需要基于.NET来操作,利用Marshal.GetFunctionPointerForDelegate来获取函数的指针,然后传递到c++中进行操作。
二、编辑器下实现实时的编译和脚本更新
在Unity中,我们可以在打开的Unity中,直接编译c#的文件,这样不需要每次都关闭工程再打开来执行编译,而C++由于通过DLL来调用,每次更新的C++都需要关闭工程,然后更新DLL,然后打开工程,这样的操作,对于编辑器下的开发是极其耗费的。
对于上面提到的反复开关工程执行DLL的更新,可以利用[DllImport]的属性来实现在编辑器下的更新。
该属性是基于OS的,所以不会存在跨平台的问题。
三、示例代码展示
show the code
c# code part:
using System;using System.IO;using System.Runtime.InteropServices;using UnityEngine;class TestScript:MonoBehaviour{#if UNITY_EDITOR // pointer handle to the C++ DLL public IntPtr libarayHandle; public delegate void InitDelegate(IntPtr gameObjectNew, IntPtr gameObjectGetTransform, IntPtr transformSetPosition);#endif}#if UNITY_EDITOR_OSX || UNITY_EDITOR_LINUX //OSX 和Linux下的导入 [DLLImport("__Internal")] public static extern IntPtr dlopen(string path, int flag); [DllImport("__Internal")] public static extern IntPtr dlsym(IntPtr handle, string symbolName); [DllImport("__Internal")] public static extern int dlclose(IntPtr handle); public static IntPtr OpenLibrary(string path) { IntPtr handle = dlopen(path, 0); if(handle == IntPtr.Zero) { throw new Exception("Couldn't open native library: "+ path); } return handle; } public static void CloseLibrary(IntPtr libraryHandle) { dlclose(libraryHandle); } public static T GetDelegate(IntPtr libraryHandle, string functionName) where T: class { IntPtr symbol = dlsym(libraryHandle, functionName); if(symbol == IntPtr.Zero) { throw new Exception("Couldn't get function:" + functionName); } return Marshal.GetDelegateForFunctionPointer(symbol, typeof(T)) as T; }#elif UNITY_EDITOR_WIN // win 编辑器下 [DllImport("kernel32")] public static extern IntPtr LoadLibrary(string path); [DllImport("kernel32")] public static extern IntPtr GetProcAddress(IntPtr libraryHandle, string symbolName); [DllImport("kernel32)] public static extern bool FreeLibrary(IntPtr libraryHandle); public static IntPtr OpenLibrary(string path) { IntPtr handle = LoadLibrary(path); if(handle == IntPtr.Zero) { throw new Exception("Couldn't open native library: "+ path); } return handle; } public static void CloseLibrary(IntPtr libraryHandle) { FreeLibrary(libraryHandle); } public static T GetDelegate (IntPtr libraryHandle, string functionName) where T: class { IntPtr symbol = GetProcAddress(libraryHandle, functionName); if(symbol == IntPtr.Zero) { throw new Exception("Couldn't get function:" + functionName); } return Marshal.GetDelegateForFunctionPointer(symbol, typeof(T)) as T; }#else //本地加载 [DllImport("NativeScript")] static extern void Init(IntPtr gameObjectNew, IntPtr gameObjectGetTransform, IntPtr transformSetPosition); [DllImport("NativeScript")] static extern void MonoBehaviourUpdate();#endif delegate int GameObjectNewDelegate(); delegate int GameObjectGetTransformDelegate(int thisHandle); delegate void TransformSetPositionDelegate(int thisHandle, Vector3 position);#if UNITY_EDITOR_OSX const string LIB_PATH = "/NativeScript.bundle/Contents/MacOS/NativeScript";#elif UNITY_EDITOR_LINUX const string LIB_PATH = "/NativeScript.so";#elif UNITY_EDITOR_WIN const string LIB_PATH = "/NativeScript.dll";#endif void Awake() {#if UNITY_EDITOR //open the native library libraryHandle = OpenLibrary(Application.dataPath + LIB_PATH); InitDelegate Init = GetDelegate (libraryHandle, "Init"); MonoBehaviourUpdate = GetDelegate ( libraryHandle,"MonoBehaviourUpdate");#endif //init the C++ Library ObjectStore.Init(1024); Init( Marshal.GetFunctionPointerForDelegate(new GameObjectNewDelegate(GameObjectNew)), Marshal.GetFunctionPointerForDelegate(new GameObjectGetTransformDelegate(GameObjectGetTransform)), Marshal.GetFunctionPointerForDelegate(new TransformSetPositionDelegate(TransformSetPosition)) ); } void Update() { MonoBehaviourUpdate(); } void OnApplicationQuit() {#if UNITY_EDITOR CloseLibrary(libraryHandle); libraryHandle = IntPtr.Zero;#endif } //c# function for c++ call static int GameObjectNew() { GameObject go = new GameObject(); return ObjectStore.Store(go); } static int GameObjectGetTransform(int thisHandle) { GameObject go = (GameObject)ObjectStore.Get(thisHandle); Transform transform = go.transform; return ObjectStore.Store(transform); } static void TransformSetPosition(int handle, Vector3 position) { Transform t =(Transform)ObjectStore.Get(handle); t.position = position; }}
c++ code part:
#ifdef _WIN32 #define DLLEXPORT __declspec(dllexport)#else #define DLLEXPORT#endifextern "C"{ //C# VECTOR STRUCT struct Vector3 { float x; float y; float z; } //c# function for c++ to call int(*GameObjectNew)(); int(*GameObjectGetTransform)(int thisHandle); void(*TransformSetPosition)(int thisHandle, Vector3 position); //c++ functions for c# to call int numCreated; DLLExport void Init( int(*gameObjectNew)(), int(*gameObjectGetTrasform)(int), void(*transformSetPosition)(int, Vector3)){ GameObjectNew = gameObjectNew; GameObjectGetTransform = gameObjectGetTransform; TransformSetPosition = trasformSetPosition; numCreated = 0;} // DLLEXPORT void MonoBehaviourUpdate(int thisHandle) { if( numCreated < 10) { //获取函数handle,然后操作 int goHandle = GameObjectNew(); int transformHandle = GameObejctGetTransform(goHandle); float comp = 10.0f * (float)numCreated; Vector3 position = {comp, comp, comp}; TransformSetPosition(transformHandle, position); numCreated++; } }}
到此,关于"Unity使用C++作为游戏逻辑脚本分析"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
C++
c++
脚本
函数
工程
更新
逻辑
分析
编辑器
c#
学习
编译
属性
文件
更多
问题
C#
帮助
实用
接下来
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
北京erp软件开发询问报价
数据库常用查看语句
国家网络安全局文职
用友nc系统怎么采集数据库
注册表修复软件开发
电击文库零境交错数据库
服务器剩余时间
五年级关于网络安全的画
什么是nas服务器
易语言软件开发者赚钱吗
华为服务器错误标识
哪一个不是数据库授权口令
升级数据库后没有网络连接
sql 数据库被删除
新建数据库默认值是多少
it软件开发要多少学历
sql数据库工作怎么样
雪玲妃软件开发
怎么配置宝塔面板新服务器
江苏米康网络技术有限公司
宜昌市网络安全支撑单位
wificam服务器
服务器多重网络环境不可达
军队网络安全 检查
中国知网介绍全文型数据库
红旗服务器操作系统
大学生网络安全演讲稿200
国家网络安全宣传周专题片
常熟品牌网络技术优势
车载边缘计算服务器选择