简述:在Unity中实现Camera画面输出到虚拟摄像头,然后让其他应用程序来读取虚拟摄像头画面(如:OBS)。
原生Unity是实现不了这个功能的,只能使用第三方语言来操作。
1. 下载UnityCam并运行
- 下载此工程压缩包,然后解压缩。
- 进入RunMe First文件夹,根据电脑版本选择x32还是x64。
- 以管理员运行Register.bat,会出现弹窗提示成功。
- Unity打开运行UnitySample工程。
- 运行CubeScene。
- 打开第三方程序(OBS),捕获UnityCam摄像头,然后启动虚拟摄像头。

这样就能看到Unity输出了一个虚拟摄像头,并能让第三方应用程序进行获取。
UnityCam默认输出的是1280*720的分辨率,所以第三方应用程序捕获的也是这个分辨率。
但是项目中往往需要1920*1080的分辨率,所以就需要修改一下c++工程并重新编译一个dll。
2. 重新编译
进入UnityWebcam文件夹,使用VS2017打开UnityWebcam.sln。
2.1 重定向解决方案
- 找到解决方案资源管理器,右键UnityWebcam解决方案,选择属性,可以在常规中看到Windows SDK版本为10.0.18362.0。
- 点击工具栏中的项目,选择重定解决方案目标。根据自己的VS环境选择一个Windows SDK版本(本文使用的是10.0.19041.0)。点击确定按钮。
2.2 编译UnityWebCam解决方案(可选)
UnityWebCam解决方案并不涉及虚拟摄像头分辨率相关的东西,所以如果不想编译的话可以略过。
2.2.1 添加目录
在解决方案资源管理器中,右键UnityWebcam解决方案,选择属性。找到VC++目录,将包含目录、引用目录、库目录,都添加一个UnityCam→UnityWebcam→UnityWebcam这个目录(就是选择UnityCam工程里面的文件夹目录)。

2.2.2 解决报错问题
这个时候选择重新生成,还是会报上面的错误。
2.2.2.1 “SendTexture”:不允许重载函数的第二个C链接
在UnityWebcam解决方案中,分别找到UnityAPI.cpp、UnityAPI.h并双击打开。
注释掉UnityAPI.h文件中的第11行:
//extern "C" __declspec(dllexport) bool SendTexture(const unsigned char* data, int width, int height);
注释掉UnityAPI.cpp文件中的33-38行:
//extern "C" __declspec(dllexport) bool SendTexture(const unsigned char* data, int width, int height)
//{
// if (!wrapper)
// wrapper = new SharedImageWrapper();
// wrapper->SendImage(data, width, height);
//}
2.2.2.2 语法错误:缺少";"(在"*"的前面);缺少类型说明符 - 假定为int。注意:c++不支持默认int
打开UnityAPI.h文件,在顶部添加代码:
#include "SharedImageWrapper.h"
using namespace mray;
2.2.3 编译
根据需要选择Debug、Release的Win32或x64版本。编译最终输出的文件夹就在Win32或x64文件夹中。
编译好后文件夹中会有一个UnityWebcam.dll的文件,但是在RunMe First文件夹中却是UnityCamService.dll文件,所以最后需要再编译UnityCamService解决方案。
2.3 编译UnityCamService解决方案*
2.3.1 解决报错问题
此时右键UnityCamService解决方案并选择重新生成,会出现一些错误:

- 和编译UnityWebcam解决方案的添加目录一样,右键UnityCamService解决方案,然后给三个目录都添加UnityWebcam→UnityCamService这个文件夹。
- 右键UnityCamService解决方案,找到链接器→输入→附加依赖项,添加legacy_stdio_definitions.lib。
2.3.2 修改虚拟摄像头输出的分辨率
找到CaptureSource.cpp文件并双击打开。
- 修改第7行的DEFAULT_WIDTH参数为1920。
- 修改第8行的DEFAULT_HEIGHT参数为1080。
- 修改第11行(MAX_WIDTH)、第12行(MAX_HEIGHT)的参数分别为1920、1080。
- (可选)第13行(MAX_FPS)、第14行(MIN_FPS)、第18行(DEFAULT_FPS)可设置为自己需要的FPS。
- 修改第539行、第540行分别为m_iPrefWidth、m_iPrefHeight。下图是修改后的样子:

重新生成 UnityCamService解决方案,并选择Debug或Release的Win32或x64版本。
将生成好的UnityCamService.dll复制到RunMe First文件夹中并替换旧有的dll。先Unregister.bat再Register.bat。
到此,虚拟摄像头的分辨率就重新设置好了。
3. dll复制到新设备使用
经过上面的步骤重新编译了dll后,可能需要把新的dll放到另外一台电脑上进行使用。当双击运行Register.bat时有可能会出现dll注册失败的弹窗提示。
这时就需要在使用的电脑上安装VS(2017、2019、2022都行),然后勾选.Net桌面开发、使用C++的桌面开发,并根据编译时使用的Windows 10 SDK 版本来勾选对应的版本。
如:编译时使用的Win10 SDK是10.0.19041.0,那么就勾选右侧的10.0.17134.0。总之就是要选一个最靠近你编译版本的win10 SDK。
4. OBS代码自动运行虚拟摄像头(可选)
obs软件的设置里面是没有自动运行操作的,某些场景下:如电脑开机后自动运行Unity程序并且运行obs来获取Unity虚拟摄像头的话,那么就需要obs在被打开后自动运行虚拟摄像头。
操作步骤:
- obs先设置好场景,也就是要打开的摄像头之类的。
- 设置websocket。在"工具"→"WebSocket服务器设置"中进行设置。
- 运行python脚本。点击下载工程→ObsVirtualCam.zip
Python工程目录如下:

venv是虚拟环境,可以自行删除或重新设置。
config.ini是连接obs的websocket配置。配置项主要是ip、端口、websocket密码。
requirements.txt是依赖性。工程初始化的时候可以重新安装一次。
StartVirtualCam.py、StopVirtualCam.py两个脚本分别是控制obs虚拟摄像头开关的。