本人是個(gè)超級(jí)菜鳥(niǎo),因?yàn)轫?xiàng)目需要用到unity、matlab并且實(shí)現(xiàn)兩者聯(lián)動(dòng),才剛開(kāi)始接觸Unity、Matlab,以前只有一點(diǎn)C/C++和Java基礎(chǔ)(好幾年前學(xué)的,只會(huì)加減乘除、連dll是什么都不懂),花了好幾天時(shí)間根據(jù)網(wǎng)上、文獻(xiàn)里的各種教程,踩了很多無(wú)法言說(shuō)的小白坑,特此把過(guò)程中遇到的問(wèn)題和原因記錄一下,給自己做個(gè)備忘(標(biāo)紅的都是我踩的重點(diǎn)坑?。。韵聝?nèi)容全是各大佬教程與官方文檔的拼接匯總以及自己踩的坑?。?!有任何描述有誤的地方歡迎指正??!
記錄在飛書(shū)文檔里,在這里蠻發(fā)一下,后續(xù)可能會(huì)繼續(xù)在飛書(shū)文檔里維護(hù):https://qgg997k2aa.feishu.cn/docx/Wew3dfr7Ko14HKxaDKrcyw1KnEb
我用的是matlab2020b,VS2019,電腦系統(tǒng).net4.8,Unity項(xiàng)目 unity2020.3.44f1c1版本、項(xiàng)目設(shè)置里player Api兼容級(jí)別是 .net4.x 、腳本后端用的是Mono。目前實(shí)現(xiàn)了在unity中調(diào)用帶參matlab函數(shù),輸出矩陣跟進(jìn)行簡(jiǎn)單計(jì)算,更復(fù)雜的后頭具體實(shí)踐的時(shí)候再學(xué)吧。。。
方案一:將matlab文件轉(zhuǎn)化成.dll引用
小伙伴總結(jié)的方法(如果下文中 “一、前期軟件準(zhǔn)備” 里相關(guān)軟件都安裝了的話全程看這個(gè)鏈接就行,unity中引用跟vs里C#項(xiàng)目有一點(diǎn)差別,具體見(jiàn)下文“三、Unity中添加引用”,其他都完全一樣):https://blog.csdn.net/weixin_40699340/article/details/79855169
matlab官方文檔(完整詳細(xì),就是看起來(lái)比較晦澀):https://ww2.mathworks.cn/help/compiler_sdk/gs/create-a-dotnet-application-with-matlab-code.html
一、前期軟件準(zhǔn)備:
1、需安裝matlab、matlab compiler、matlab compiler SDK 。用安裝程序安裝就行,或者在matlab命令行窗口 deploytool 點(diǎn)擊 matlab compiler SDK 安裝就可以(會(huì)自動(dòng)安裝matlab compiler)
matlab compiler SDK的兼容詳情:https://ww2.mathworks.cn/help/compiler_sdk/dotnet/matlab-builder-ne-prerequisites.html

2、安裝 Visual Studio ,不同版本對(duì)matlab功能的支持情況不同,具體可參考下方鏈接查看自己安裝的vs版本是否支持想要調(diào)用的matlab產(chǎn)品:https://ww2.mathworks.cn/support/requirements/supported-compilers.html
3、安裝MATLAB Runtime。(按理說(shuō)安裝matlab的時(shí)候就會(huì)自動(dòng)安裝,但是我自動(dòng)安裝的用不了,網(wǎng)上查可能是版本不對(duì),又重新下了一個(gè))
在matlab命令行窗口輸入 compiler.runtime.download 會(huì)開(kāi)啟下載,文件2、3個(gè)G,如果網(wǎng)不好可能會(huì)斷掉,重新下就行,最好在matlab里用指令下,下載的版本是匹配的,如果自己另外找很可能跟安裝的matlab版本對(duì)不上。已經(jīng)下載了就會(huì)顯示下載路徑。

安裝方法詳情見(jiàn)官網(wǎng):https://ww2.mathworks.cn/help/compiler_sdk/ml_code/install-the-matlab-runtime.html,)
如果想生成exe調(diào)用的話(見(jiàn)下文方案三),runtime壓縮包最好不要?jiǎng)h掉,因?yàn)樵诖虬黣xe時(shí)如果選擇了 Runtime included in package 的話,系統(tǒng)會(huì)去找本地壓縮包,所以需要提前在matlab中添加runtime安裝包的路徑,點(diǎn)擊【主頁(yè)】-【預(yù)設(shè)】,在彈出窗口中選擇【MATLAB Compiler】,在右側(cè)輸入框輸入安裝包的完整路徑+文件名,例如:D:\Matlab2020b\MATLAB Runtime\MATLAB_Runtime_R2020b_win64.zip(zip也要帶?。。?/span>
如果刪掉了,沒(méi)有現(xiàn)成的壓縮包的話可以選擇Runtime downloaded from web,系統(tǒng)會(huì)提示重新下載 runtime安裝包,打包的時(shí)候就要等很久(如果沒(méi)有在MATLAB Compiler中添加對(duì)runtime壓縮包儲(chǔ)存路徑,系統(tǒng)搜索不到,也會(huì)給同樣的提示)。



二、配置系統(tǒng)、打包生成dll:
參考 https://blog.csdn.net/weixin_40699340/article/details/79855169 里的“2.配置和3.matlab端即可(下方也是里面粘過(guò)來(lái)的)
(1) 添加MATLAB路徑:一定要添加,我就是這一步?jīng)]做,一直調(diào)用不了

(2) 對(duì)mwcomutil.dll進(jìn)行注冊(cè)。這個(gè)dll文件位于E:\MATLAB\R2016b\bin\win64文件夾中(不用找出來(lái)):
以管理員的身份注冊(cè):輸入:regsvr32 mwcomutil.dll

注意:一定要添加matlab路徑然后注冊(cè) regsvr32 mwcomutil.dll 不然unity運(yùn)行會(huì)顯示如下報(bào)錯(cuò):

(3) 生成matlab的dll文件
編寫(xiě).m文件,在matlab中調(diào)試運(yùn)行通了:

如果是第一次編譯,同時(shí)存在多個(gè)編譯器的話,則需要提前設(shè)置好編譯器跟語(yǔ)言(我選擇的VS跟C++):

生成dll文件:matlab命令行窗口輸入 deploy tool ,在彈出窗口選擇 Library Compiler(如果選擇的是Application Compiler 就是生成exe)

選擇 Library Compiler 之后,會(huì)彈出下方窗口,【TYPE】中選擇【.NET Assembly】,然后EXPORTED FUNCTIONS中點(diǎn)擊右上角【+】,選擇編寫(xiě)好的.m文件,下方【命名空間】和【Class Name】可以修改(非必須,但還是好好命名會(huì)便于管理),點(diǎn)擊【Package】等待打包完成。

點(diǎn)擊【打開(kāi)輸出文件夾】或勾選下方【處理完成后打開(kāi)輸出文件夾】會(huì)打開(kāi)打包好的文件夾,文件夾會(huì)以【命名空間】的名字命名,【for_testing】(有的低版本可能叫 for_test)文件夾里就有生成好的dll文件,我下方截圖實(shí)例中命名叫Untitled2.dll。



三、Unity中添加引用
注意:unity中調(diào)用dll并不是將dll掛到VS的C#項(xiàng)目里,而是要在Assets文件夾中一級(jí)目錄新建Plugins文件夾,然后放在里面,添加之后打開(kāi)C#腳本編輯的時(shí)候會(huì)自動(dòng)加到引用里。
在C#項(xiàng)目中添加引用沒(méi)用?。?!這里不加,每次unity中點(diǎn)擊運(yùn)行的時(shí)候都會(huì)掉掉!
上述打包完成后找出 MWArray.dll 和自己在matlab中生成的.dll,拖到Plugins文件夾內(nèi)即可。添加MWArray.dll 適用于數(shù)據(jù)轉(zhuǎn)化的,由于C#與matlab數(shù)據(jù)類型不同,Matlab MathWorks 提供了兩個(gè)API(對(duì)應(yīng)不同.net版本)用來(lái)作為中間類處理 .NET 應(yīng)用程序和matlab之間的數(shù)據(jù)交換,.net 4.X版本的用 MWArray.dll 。

新建C#腳本文件并打開(kāi)可以發(fā)現(xiàn)右側(cè)引用自動(dòng)添加上了,在頂部添加Matlab數(shù)據(jù)轉(zhuǎn)換用的聲明(紅框框選的部分,就是MWArray.dll 中提供的,還有其他可用的接口,可以在下方“編程參考”里看)和自己編寫(xiě)的函數(shù)聲明(黃框框選的部分)即可。
這一步如果下方編寫(xiě)的代碼里提醒【找不到命名空間】,有可能就是頂部聲明引用錯(cuò)了,沒(méi)有很復(fù)雜的原因 T T

網(wǎng)上有人說(shuō)下方截圖內(nèi)的內(nèi)容必須得確認(rèn):
(來(lái)源:https://blog.csdn.net/weixin_42432227/article/details/103876304)

但我這調(diào)用的時(shí)候,unity2020.3中創(chuàng)建的C#項(xiàng)目默認(rèn)是AnyCPU,沒(méi)改,同時(shí)我的Matlab Runtime(MCR)是x64,unity項(xiàng)目用的.net4.0,一樣可以正常調(diào)用,C#項(xiàng)目平臺(tái)不用改成x64。但有的人會(huì)出問(wèn)題,需要改成一致的(MCR是x64的就改為x64):




按上面操作完下方紅框處就變成x64了。

四、調(diào)試程序參考:
matlab里.m文件“trytest”:

function y = trytest(x)
y = x+5;
end
unity里的C#文件:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility;
using trytest;
public class testttt : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
MWArray a = 1;
Class1 d = new Class1();
MWArray e = d.trytest(a);
Debug.Log(e);
Debug.Log("b");
}
// Update is called once per frame
void Update()
{
}
}
打包的時(shí)候設(shè)置的內(nèi)容,全部是默認(rèn)的,我沒(méi)改,但最好認(rèn)真起名,方便后續(xù)管理:

其他注意事項(xiàng):
1、引用dll之后,由于C#與matlab數(shù)據(jù)類型不同,需要先進(jìn)行C#與matlab數(shù)據(jù)轉(zhuǎn)化,Matlab MathWorks 提供了兩個(gè)API,設(shè)計(jì)了中間類處理 .NET 應(yīng)用程序和matlab之間的數(shù)據(jù)交換(不了解的話可以搜索C#與matlab數(shù)據(jù)轉(zhuǎn)換),注意選擇對(duì)應(yīng)版本:
MWArray API :適用于 .NET Framework 4.0 或更高版本。(我的是.net 4.8,所以用的這個(gè),這就是為什么上面在unity中添加引用的時(shí)候要添加MWArray.dll
MATLAB Data API:適用于 .NET 5.0 或更高版本
2、引用之后在C#里調(diào)用的時(shí)候注意添加下方兩個(gè)聲明,這兩個(gè)是最常用的C#與matlab進(jìn)行數(shù)據(jù)轉(zhuǎn)化的接口:
using MathWorks.MATLAB.NET.Arrays;
官方介紹文檔:https://ww2.mathworks.cn/help/dotnetbuilder/MWArrayAPI/html/N_MathWorks_MATLAB_NET_Arrays.htm#!
using MathWorks.MATLAB.NET.Utility;
官方介紹文檔:https://www.mathworks.com/help/dotnetbuilder/MWArrayAPI/html/N_MathWorks_MATLAB_NET_Utility.htm
3、跨電腦調(diào)用時(shí)注意事項(xiàng)

編程參考:
1、在.net中調(diào)用matlab的所有API、類和功能:https://ww2.mathworks.cn/help/matlab/call-matlab-from-net.html

2、Matlab mwArray類用法:https://ww2.mathworks.cn/help/compiler_sdk/cxx/mwarray.html
方案二:編寫(xiě)適用于 MATLAB 的 COM 應(yīng)用程序,通過(guò)MLAPP調(diào)用
方法見(jiàn)鏈接:https://blog.csdn.net/zhupumao/article/details/51996113
(鼓搗了老半天沒(méi)法添加MLAPP引用放棄了,但后來(lái)方法一跑通之后突然就能添加上MLAPP引用了,具體能不能實(shí)現(xiàn)也懶得再試了)
添加引用方法:
VS中【解決方案資源管理器】里右鍵【Assembly-CSharp】/【Assembly-CSharp下的引用】-【添加分析器】搜索Matlab Application查找不到


從菜單欄【視圖】-【對(duì)象瀏覽器】-【···】

,選中【com】,下拉找到【Matlab Application】,點(diǎn)擊【添加】下方自動(dòng)添加”Matlab Automation Server Type Library“,點(diǎn)擊【確定】

對(duì)象瀏覽器變成如下界面,點(diǎn)擊紅框處添加引用即可。


上面這一步添加引用一開(kāi)始不行,后來(lái)突然成功,可能原因是注冊(cè)了下圖的mwcomutil.dll:
(與系統(tǒng)環(huán)境變量是否添加matlab相關(guān)路徑無(wú)關(guān),后來(lái)找原因的時(shí)候我把matlab路徑全刪了也一樣能添加上,跟下圖解決方案選擇Any CPU還是x64也無(wú)關(guān),因?yàn)槲业腗CR是x64)


https://ww2.mathworks.cn/help/matlab/matlab_external/call-matlab-function-from-c-client.html
(上述鏈接是matlab官方關(guān)于如何用C#客戶端調(diào)用matlab的方法)
https://ww2.mathworks.cn/help/matlab/call-matlab-com-automation-server.html
(上述鏈接是matlab官方給出的編寫(xiě)適用于 MATLAB 的 COM 應(yīng)用程序的教程)
https://forum.unity.com/threads/creating-dll-to-use-matlab-from-unity-issue.1109870/#post-7149559
(上述鏈接是unity論壇中采用此方法調(diào)用matlab遇到的問(wèn)題討論)
方案三:生成exe調(diào)用 (未嘗試,跟.dll比較類似,在matlab打包階段選擇Application compiler 即可)
方法參考:http://blog.chinaunix.net/uid-22982394-id-2871946.html
marlab官方文檔:https://ww2.mathworks.cn/help/compiler_sdk/gs/create-a-dotnet-application-with-matlab-code.html
https://ww2.mathworks.cn/help/compiler_sdk/gs/customizing-the-installer.html#mw_00353f1c-87a4-49ee-93dd-f086935c7bf9
方案四:通過(guò)TCP、UDP協(xié)議通信(必須安裝matlab)(未嘗試)
TCP?(看不懂):
https://stackoverflow.com/questions/35976685/how-unity-can-read-data-from-matlab-socket/35987432#35987432
matlab官方工作人員給的解決方案:
https://ww2.mathworks.cn/matlabcentral/answers/196774-connection-between-matlab-and-unity3d
UDP:
https://blog.csdn.net/huowanli/article/details/122415545
https://blog.csdn.net/S_fenguangyi/article/details/106269514?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-106269514-blog-115905327.pc_relevant_landingrelevant&spm=1001.2101.3001.4242.1&utm_relevant_index=3
(不用看,只是自己做個(gè)記錄)其他可能有用的相關(guān)的:
MATLAB 編譯器 SDK官方介紹文檔:https://ww2.mathworks.cn/help/compiler_sdk/index.html?s_tid=CRUX_lftnav
為 Unity 的 C# 項(xiàng)目添加 dll 引用或安裝 NuGet 包:https://blog.csdn.net/WPwalter/article/details/106335261
生成 .NET 引擎程序的要求:https://ww2.mathworks.cn/help/matlab/matlab_external/requirements-to-build-net-engine-programs.html
在 Unity 中使用 .NET 4.x:https://learn.microsoft.com/zh-cn/visualstudio/gamedev/unity/unity-scripting-upgrade
compiler.build.dotNETAssembly 創(chuàng)建用于在 MATLAB 外部部署的 .NET 程序集:
https://ww2.mathworks.cn/help/compiler_sdk/dotnet/compiler.build.dotnetassembly.html#mw_c0be9ce0-13c9-4b15-a646-dec66431f0b9文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-421813.html
據(jù)說(shuō) .net編譯速度比com快,也更穩(wěn)定:https://www.cnblogs.com/MarshallL/p/4043082.html文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-421813.html

到了這里,關(guān)于純小白新人菜鳥(niǎo)第一次unity VR項(xiàng)目與matlab聯(lián)動(dòng)調(diào)試過(guò)程記錄超詳細(xì)版本2023.3.12的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!