Unity使用C++作为游戏逻辑脚本分析
发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,这篇文章主要介绍"Unity使用C++作为游戏逻辑脚本分析",在日常操作中,相信很多人在Unity使用C++作为游戏逻辑脚本分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家
千家信息网最后更新 2025年02月02日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安全错误
数据库的锁怎样保障安全
深圳地产软件开发定制
江苏互联网智能科技是什么
机网络技术
公务员考试计算机网络技术题库
网络安全研究中心
网络安全与信息化的基础是什么
电脑有网找不到dns的服务器
曙光服务器默认管理ip
宁夏曙光服务器虚拟化费用
税务网络安全认识
中国网络安全政策法规
泰拉瑞亚tmod服务器卡顿
虹口区银联网络技术服务保障
c 编程软件开发
控制台打开数据库的命令是
网络安全简短演讲稿
mdb数据库下拉框
服务器卫士
卖服务器的梗
华为网络安全与隐私保护岗位
沧州的软件开发公司电话
江山实惠软件开发特点
怎么重启虚拟机的服务器
svn服务器管理平台
嵌入式软件开发专业代码
软件开发适合学什么专业
互联网科技素材海报
学校网络安全教育宣传信息
美网络安全股市销率
奉贤区智能软件开发供应商家