纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12

本人是个超级菜鸟,因为项目需要用到unity、matlab并且实现两者联动,才刚开始接触Unity、Matlab,以前只有一点C/C++和Java基础(好几年前学的,只会加减乘除、连dll是什么都不懂),花了好几天时间根据网上、文献里的各种教程,踩了很多无法言说的小白坑,特此把过程中遇到的问题和原因记录一下,给自己做个备忘(标红的都是我踩的重点坑!!),以下内容全是各大佬教程与官方文档的拼接汇总以及自己踩的坑!!!有任何描述有误的地方欢迎指正!!

记录在飞书文档里,在这里蛮发一下,后续可能会继续在飞书文档里维护:https://qgg997k2aa.feishu.cn/docx/Wew3dfr7Ko14HKxaDKrcyw1KnEb

我用的是matlab2020b,VS2019,电脑系统.net4.8,Unity项目 unity2020.3.44f1c1版本、项目设置里player Api兼容级别是 .net4.x 、脚本后端用的是Mono。目前实现了在unity中调用带参matlab函数,输出矩阵跟进行简单计算,更复杂的后头具体实践的时候再学吧。。。

方案一:将matlab文件转化成.dll引用

小伙伴总结的方法(如果下文中 “一、前期软件准备” 里相关软件都安装了的话全程看这个链接就行,unity中引用跟vs里C#项目有一点差别,具体见下文“三、Unity中添加引用”,其他都完全一样):https://blog.csdn.net/weixin_40699340/article/details/79855169

matlab官方文档(完整详细,就是看起来比较晦涩):https://ww2.mathworks.cn/help/compiler_sdk/gs/create-a-dotnet-application-with-matlab-code.html

一、前期软件准备:

1、需安装matlab、matlab compiler、matlab compiler SDK 。用安装程序安装就行,或者在matlab命令行窗口 deploytool 点击 matlab compiler SDK 安装就可以(会自动安装matlab compiler)

matlab compiler SDK的兼容详情:https://ww2.mathworks.cn/help/compiler_sdk/dotnet/matlab-builder-ne-prerequisites.html

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第1张图片

2、安装 Visual Studio ,不同版本对matlab功能的支持情况不同,具体可参考下方链接查看自己安装的vs版本是否支持想要调用的matlab产品:https://ww2.mathworks.cn/support/requirements/supported-compilers.html

3、安装MATLAB Runtime。(按理说安装matlab的时候就会自动安装,但是我自动安装的用不了,网上查可能是版本不对,又重新下了一个)

在matlab命令行窗口输入 compiler.runtime.download 会开启下载,文件2、3个G,如果网不好可能会断掉,重新下就行,最好在matlab里用指令下,下载的版本是匹配的,如果自己另外找很可能跟安装的matlab版本对不上。已经下载了就会显示下载路径。

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第2张图片

安装方法详情见官网:https://ww2.mathworks.cn/help/compiler_sdk/ml_code/install-the-matlab-runtime.html,)

如果想生成exe调用的话(见下文方案三),runtime压缩包最好不要删掉,因为在打包exe时如果选择了 Runtime included in package 的话,系统会去找本地压缩包,所以需要提前在matlab中添加runtime安装包的路径,点击【主页】-【预设】,在弹出窗口中选择【MATLAB Compiler】,在右侧输入框输入安装包的完整路径+文件名,例如:D:\Matlab2020b\MATLAB Runtime\MATLAB_Runtime_R2020b_win64.zip(zip也要带!!)

如果删掉了,没有现成的压缩包的话可以选择Runtime downloaded from web,系统会提示重新下载 runtime安装包,打包的时候就要等很久(如果没有在MATLAB Compiler中添加对runtime压缩包储存路径,系统搜索不到,也会给同样的提示)。

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第3张图片
纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第4张图片
纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第5张图片


二、配置系统、打包生成dll:

参考 https://blog.csdn.net/weixin_40699340/article/details/79855169 里的“2.配置和3.matlab端即可(下方也是里面粘过来的)

(1) 添加MATLAB路径:一定要添加,我就是这一步没做,一直调用不了

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第6张图片

(2) 对mwcomutil.dll进行注册。这个dll文件位于E:\MATLAB\R2016b\bin\win64文件夹中(不用找出来):

以管理员的身份注册:输入:regsvr32 mwcomutil.dll

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第7张图片

注意:一定要添加matlab路径然后注册 regsvr32 mwcomutil.dll 不然unity运行会显示如下报错:

(3) 生成matlab的dll文件

编写.m文件,在matlab中调试运行通了:

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第8张图片

如果是第一次编译,同时存在多个编译器的话,则需要提前设置好编译器跟语言(我选择的VS跟C++):

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第9张图片

生成dll文件:matlab命令行窗口输入 deploy tool ,在弹出窗口选择 Library Compiler(如果选择的是Application Compiler 就是生成exe)

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第10张图片

选择 Library Compiler 之后,会弹出下方窗口,【TYPE】中选择【.NET Assembly】,然后EXPORTED FUNCTIONS中点击右上角【+】,选择编写好的.m文件,下方【命名空间】和【Class Name】可以修改(非必须,但还是好好命名会便于管理),点击【Package】等待打包完成。

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第11张图片

点击【打开输出文件夹】或勾选下方【处理完成后打开输出文件夹】会打开打包好的文件夹,文件夹会以【命名空间】的名字命名,【for_testing】(有的低版本可能叫 for_test)文件夹里就有生成好的dll文件,我下方截图实例中命名叫Untitled2.dll。

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第12张图片
纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第13张图片
纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第14张图片


三、Unity中添加引用

注意:unity中调用dll并不是将dll挂到VS的C#项目里,而是要在Assets文件夹中一级目录新建Plugins文件夹,然后放在里面,添加之后打开C#脚本编辑的时候会自动加到引用里。

在C#项目中添加引用没用!!!这里不加,每次unity中点击运行的时候都会掉掉!

上述打包完成后找出 MWArray.dll 和自己在matlab中生成的.dll,拖到Plugins文件夹内即可。添加MWArray.dll 适用于数据转化的,由于C#与matlab数据类型不同,Matlab MathWorks 提供了两个API(对应不同.net版本)用来作为中间类处理 .NET 应用程序和matlab之间的数据交换,.net 4.X版本的用 MWArray.dll 。

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第15张图片

新建C#脚本文件并打开可以发现右侧引用自动添加上了,在顶部添加Matlab数据转换用的声明(红框框选的部分,就是MWArray.dll 中提供的,还有其他可用的接口,可以在下方“编程参考”里看)和自己编写的函数声明(黄框框选的部分)即可。

这一步如果下方编写的代码里提醒【找不到命名空间】,有可能就是顶部声明引用错了,没有很复杂的原因 T T

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第16张图片

网上有人说下方截图内的内容必须得确认:

(来源:https://blog.csdn.net/weixin_42432227/article/details/103876304)

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第17张图片

但我这调用的时候,unity2020.3中创建的C#项目默认是AnyCPU,没改,同时我的Matlab Runtime(MCR)是x64,unity项目用的.net4.0,一样可以正常调用,C#项目平台不用改成x64。但有的人会出问题,需要改成一致的(MCR是x64的就改为x64):

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第18张图片
纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第19张图片
纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第20张图片

按上面操作完下方红框处就变成x64了。

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第21张图片

四、调试程序参考:

matlab里.m文件“trytest”:

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第22张图片
function y = trytest(x)
y = x+5;
end

unity里的C#文件:

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第23张图片
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()
    {
        
    }
}

打包的时候设置的内容,全部是默认的,我没改,但最好认真起名,方便后续管理:

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第24张图片

其他注意事项:

1、引用dll之后,由于C#与matlab数据类型不同,需要先进行C#与matlab数据转化,Matlab MathWorks 提供了两个API,设计了中间类处理 .NET 应用程序和matlab之间的数据交换(不了解的话可以搜索C#与matlab数据转换),注意选择对应版本:

  • MWArray API :适用于 .NET Framework 4.0 或更高版本。(我的是.net 4.8,所以用的这个,这就是为什么上面在unity中添加引用的时候要添加MWArray.dll

  • MATLAB Data API:适用于 .NET 5.0 或更高版本

2、引用之后在C#里调用的时候注意添加下方两个声明,这两个是最常用的C#与matlab进行数据转化的接口:

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、跨电脑调用时注意事项

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第25张图片


编程参考:

1、在.net中调用matlab的所有API、类和功能:https://ww2.mathworks.cn/help/matlab/call-matlab-from-net.html

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第26张图片

2、Matlab mwArray类用法:https://ww2.mathworks.cn/help/compiler_sdk/cxx/mwarray.html


方案二:编写适用于 MATLAB 的 COM 应用程序,通过MLAPP调用

方法见链接:https://blog.csdn.net/zhupumao/article/details/51996113

(鼓捣了老半天没法添加MLAPP引用放弃了,但后来方法一跑通之后突然就能添加上MLAPP引用了,具体能不能实现也懒得再试了)

添加引用方法:

VS中【解决方案资源管理器】里右键【Assembly-CSharp】/【Assembly-CSharp下的引用】-【添加分析器】搜索Matlab Application查找不到

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第27张图片
纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第28张图片

从菜单栏【视图】-【对象浏览器】-【···】

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第29张图片

,选中【com】,下拉找到【Matlab Application】,点击【添加】下方自动添加”Matlab Automation Server Type Library“,点击【确定】

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第30张图片

对象浏览器变成如下界面,点击红框处添加引用即可。

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第31张图片
纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第32张图片

上面这一步添加引用一开始不行,后来突然成功,可能原因是注册了下图的mwcomutil.dll:

(与系统环境变量是否添加matlab相关路径无关,后来找原因的时候我把matlab路径全删了也一样能添加上,跟下图解决方案选择Any CPU还是x64也无关,因为我的MCR是x64)

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第33张图片

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第34张图片

https://ww2.mathworks.cn/help/matlab/matlab_external/call-matlab-function-from-c-client.html

(上述链接是matlab官方关于如何用C#客户端调用matlab的方法)

https://ww2.mathworks.cn/help/matlab/call-matlab-com-automation-server.html

(上述链接是matlab官方给出的编写适用于 MATLAB 的 COM 应用程序的教程)

https://forum.unity.com/threads/creating-dll-to-use-matlab-from-unity-issue.1109870/#post-7149559

(上述链接是unity论坛中采用此方法调用matlab遇到的问题讨论)

方案三:生成exe调用 (未尝试,跟.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

方案四:通过TCP、UDP协议通信(必须安装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

(不用看,只是自己做个记录)其他可能有用的相关的:

MATLAB 编译器 SDK官方介绍文档:https://ww2.mathworks.cn/help/compiler_sdk/index.html?s_tid=CRUX_lftnav

为 Unity 的 C# 项目添加 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 创建用于在 MATLAB 外部部署的 .NET 程序集:

https://ww2.mathworks.cn/help/compiler_sdk/dotnet/compiler.build.dotnetassembly.html#mw_c0be9ce0-13c9-4b15-a646-dec66431f0b9

据说 .net编译速度比com快,也更稳定:https://www.cnblogs.com/MarshallL/p/4043082.html

纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12_第35张图片

你可能感兴趣的:(unity开发学习,unity,matlab,c#,vr)