Unity使用C++作为游戏逻辑脚本分析
发表于:2025-12-01 作者:千家信息网编辑
千家信息网最后更新 2025年12月01日,这篇文章主要介绍"Unity使用C++作为游戏逻辑脚本分析",在日常操作中,相信很多人在Unity使用C++作为游戏逻辑脚本分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家
千家信息网最后更新 2025年12月01日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安全错误
数据库的锁怎样保障安全
青州天盛网络技术
PCB和软件开发哪个好上手
国内网络安全行业发展趋势
临时数据库连接失败
电信网络技术定义
计算机网络技术基础课
洛阳软件开发哪家便宜
数据库必须是一种什么表
检索数据库名称
mc部落服务器手机能玩吗
三维数据库命名规则
中国知网外文数据库
img src数据库图片
戴尔3020mt服务器
网络安全的创业板
迷你世界云服服务器怎么清屏
湖南企业软件开发多少钱
小学一年级网络安全教育视频
数据库自动化技术
风电场网络安全应急预案
腾讯基于全时态数据库技术
小说阅读器软件开发
外企网络安全工作
手机怎么注册服务器
宜采软件开发有限公司
数据库设计 时间序列
信息网络安全宣传实施方案
心跳包会不会增加服务器压力
厦门软件开发园二期租房
众商网络技术有限公司