插件格式
有2种方式
- 以源码方式引用,就是直接放入 cpp 文件,以及相关的头文件,cpp 文件才要放在unity中,头文件可以放在别的地方,只要能引用到就行 编译时本身就会把C#通过IL2CPP反编译成cpp,然后再同插件中的cpp一起使用emscripten编译成最后的.wasm
- 编译成静态库 2021.2版本之前,是编译成 .wasm 和 .js 格式 2021.2版本开始,是编译成 .a 和 .jslib 格式 .jslib 就是把 .js 扩展名改一下,都是为了把c++函数导出给js用的,如果你都是在c#中通过 [DllImport(“__Internal”)] 方式导入,那么可以不要这个文件 .wasm 和 .a 就是库文件,只不过需要用 emscripten 工具来编译而不是 gcc
官方示例NativeRenderingPlugin编译
git: https://github.com/Unity-Technologies/NativeRenderingPlugin.git
目录结构
- PluginSource c++插件工程
- UnityProject unity工程
入口
UseRenderingPlugin.cs 调用c++插件进行额外的渲染
编译web库
该示例本身是通过 cpp 源码方式直接做为web插件的,跟 PluginSource 中的头文件是有引用关系的,发布时最好编译成 .a库
由于这里不需要把接口导出给js用,因此不需要编译 .jslib ,只需要编译出 .a
- 通过bat编译 把下面代码放在 PluginSource/build_web_lib.bat 中运行即可
:: 把webgl的cpp打包成.a库 :: 把emscriptenDir改成对应unity版本的路径,或直接使用 gaussiansplattingweb 内置的 Tools/BuildWebRenderPlugin 工具进行编译 set emscriptenDir=C:\Program Files\Unity\Hub\Editor\2021.3.25f1c1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\ set srcDir=..\UnityProject\Packages\mg.gaussiansplattingweb\Runtime\Plugins\WebGL\ set emcc=%emscriptenDir%emscripten\emcc.bat set emar=%emscriptenDir%emscripten\emar.bat set EMSDK_PYTHON=%emscriptenDir%python\python.exe set EM_CONFIG=%emscriptenDir%.emscripten set cppPath=%srcDir%RenderingPlugin.cpp set objPath=RenderingPlugin.o set libPath=%srcDir%RenderingPlugin.a call "%emcc%" -c "%cppPath%" -o "%objPath%" call "%emar%" rcs "%libPath%" "%objPath%" del "%objPath%" pause
- 通过unity编辑器脚本编译 加入编辑器脚本 BuildWebRenderPlugin.cs 在插件的 Editor 目录下
// 把webgl的cpp打包成.a库// 对应 source 分支下 PluginSource/build_web_lib.bat 实现的功能// 使用内置脚本有个好处,直接使用匹配的emscripten进行编译,不需要手动干预publicclassBuildWebRenderPlugin:ScriptableObject{[MenuItem("Tools/BuildWebRenderPlugin")]publicstaticvoidRunEmscriptenBuild(){// 获取 Unity 安装路径string unityPath = EditorApplication.applicationPath;string unityRoot = Path.GetDirectoryName(unityPath);// 获取当前脚本的 MonoScript 实例MonoScript script = MonoScript.FromScriptableObject(ScriptableObject.CreateInstance<BuildWebRenderPlugin>());// 获取当前脚本的路径string scriptPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(script));// 构建文件路径string cppFilePath = Path.Combine(scriptPath,"..","Runtime","Plugins","WebGL","RenderingPlugin.cpp");string outputObjectFilePath ="RenderingPlugin.o";string outputLibraryFilePath = Path.Combine(scriptPath,"..","Runtime","Plugins","WebGL","RenderingPlugin.a"); UnityEngine.Debug.Log($"RenderingPlugin.cpp Path={cppFilePath}");// 拼接 emcc 和 emar 路径string emccPath = Path.Combine(unityRoot,"Data","PlaybackEngines","WebGLSupport","BuildTools","Emscripten","emscripten","emcc.bat");string emarPath = Path.Combine(unityRoot,"Data","PlaybackEngines","WebGLSupport","BuildTools","Emscripten","emscripten","emar.bat");string pythonPath = Path.Combine(unityRoot,"Data","PlaybackEngines","WebGLSupport","BuildTools","Emscripten","python","python.exe");string emConfigPath = Path.Combine(unityRoot,"Data","PlaybackEngines","WebGLSupport","BuildTools","Emscripten",".emscripten"); UnityEngine.Debug.Log($"emcc.bat Path={emccPath}");// 确保路径存在if(!File.Exists(emccPath)||!File.Exists(emarPath)||!File.Exists(pythonPath)||!File.Exists(emConfigPath)){ UnityEngine.Debug.LogError("Emscripten tools not found. Please check your Unity installation.");return;}if(!File.Exists(cppFilePath)){ UnityEngine.Debug.LogError($"C++ source file not found: {cppFilePath}");return;}// 设置环境变量var envVariables =newSystem.Collections.Generic.Dictionary<string,string>{{"EMSDK_PYTHON", pythonPath },{"EM_CONFIG", emConfigPath }};// 执行 emcc 命令ExecuteCommand(emccPath,$"-c \"{cppFilePath}\" -o \"{outputObjectFilePath}\"", envVariables);// 执行 emar 命令ExecuteCommand(emarPath,$"rcs \"{outputLibraryFilePath}\" \"{outputObjectFilePath}\"", envVariables);// 删除 .o 文件 File.Delete(outputObjectFilePath); AssetDatabase.Refresh(); UnityEngine.Debug.Log($"RenderingPlugin.a 生成成功");}privatestaticvoidExecuteCommand(string command,string arguments,System.Collections.Generic.Dictionary<string,string> envVariables){ UnityEngine.Debug.Log($"ExecuteCommand cmd={command} args={arguments}");ProcessStartInfo startInfo =newProcessStartInfo{ FileName = command, Arguments = arguments, RedirectStandardOutput =true, RedirectStandardError =true, UseShellExecute =false, CreateNoWindow =true};// 设置环境变量foreach(var envVar in envVariables){ startInfo.EnvironmentVariables[envVar.Key]= envVar.Value;}using(Process process =newProcess{ StartInfo = startInfo }){ process.Start();string output = process.StandardOutput.ReadToEnd();string error = process.StandardError.ReadToEnd(); process.WaitForExit();// 输出日志 UnityEngine.Debug.Log($"output:{output}");if(!string.IsNullOrEmpty(error)){ UnityEngine.Debug.LogError($"error:{error}");}}}}
版权归原作者 qmladm 所有, 如有侵权,请联系我们删除。