Unity使用C++作为游戏逻辑脚本分析
发表于:2025-02-19 作者:千家信息网编辑
千家信息网最后更新 2025年02月19日,这篇文章主要介绍"Unity使用C++作为游戏逻辑脚本分析",在日常操作中,相信很多人在Unity使用C++作为游戏逻辑脚本分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家
千家信息网最后更新 2025年02月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安全错误
数据库的锁怎样保障安全
自动化网络安全防护中级操作题
加强感知网络安全态势
网络安全培训考试总结
中国互联网企业科技创新
系统数据库打开错误
大话2黄金数据库
云服务器搭建专用网盘
服务器管理站
青少年网络安全日活动总结
网络安全问题分析与设计文献检索
个人服务器哪家好
网络安全校园日征文
网络安全与执法四川警察学院
碧蓝航线服务器全绿
对网络安全法律法规的看法
广西电商软件开发技术
软件开发公司岗位职责
红包软件开发商
山东互联网科技公司
网络安全 网络立法
无锡品牌软件开发活动简介
bim数据库的更新的意义
云端知识数据库
对日软件开发详细设计
服务器连接命令
巴勒斯坦服务器好吗
软件开发公司网站
福建智能化网络技术收费标准
互联网科技创新的方法路径
win7网络安全模式很卡