0


Unity+QT, 如何把Unity打包出的exe嵌入QT程序中,并且使用Socket进行交互

文章目录

概要

在 VR 开发中,常常需要桌面窗口和 VR 头盔使用者进行交互。通过将 Unity制作的 VR 程序嵌入到 QT 应用程序窗口中,并使用 Socket进行通信,可以实现这种交互。本文将介绍如何实现这一功能。

前期准备

  1. Unity 项目打包 首先,在 Unity 中开发并打包您的项目为可执行文件(EXE)。确保您已经测试过独立运行的 EXE 并且一切正常。
  2. QT 环境设置 安装并配置好 QT 开发环境。如果您还没有 QT 安装,可以访问 QT 官方网站 下载和安装。

QT 与 Unity 的 Socket 通信

  1. QT 服务器设置 在 QT 中,使用 QUdpSocket 创建一个 UDP 服务器来接收来自 Unity 的数据,在QT程序初始化时用QProcess启动Unity程序,并且等待Unity程序连接,Unity程序连接后获取Unity程序的窗口句柄,并把这个窗口嵌入到QT中:
#include<QPushButton>#include<QVBoxLayout>#include<QtNetwork>#include"QProcess"classMainWindow:publicQMainWindow{
    Q_OBJECT

public:MainWindow(QWidget *parent =nullptr):QMainWindow(parent){
        QUdpSocket* socket =newQUdpSocket(this);
        socket->bind(QHostAddress("127.0.0.1"),6060);connect(socket,SIGNAL(readyRead()),this,SLOT(readData()));

        QProcess* process =newQProcess(this);
        QString cmd ="path/to/your/VRUnityApp.exe";
        process->start(cmd,QStringList()<<"");
 
        QVBoxLayout *layout =new QVBoxLayout;
        QWidget *centralWidget =newQWidget(this);
        centralWidget->setLayout(layout);setCentralWidget(centralWidget);

        QPushButton *switchSceneButton =newQPushButton("Switch Scene",this);
        QPushButton *createObjectButton =newQPushButton("Create Object",this);

        layout->addWidget(switchSceneButton);
        layout->addWidget(createObjectButton);connect(switchSceneButton,&QPushButton::clicked,[server](){sendData("switch_scene");});connect(createObjectButton,&QPushButton::clicked,[server](){sendData("create_object");});}voidsendData(const QString& data){for(int i =0; i < m_client.count(); i++){
            QString str = m_client.at(i);
            QStringList list = str.split(":");
            QByteArray buffer;
            buffer = data.toUtf8();
            socket->writeDatagram(buffer,QHostAddress(list.at(0)), list.at(1).toInt());}}voidOnDataRecived(const QString& msg){if(msg =="Connect"){
            WId wid =(WId)FindWindow(L"XXXXX",NULL);//获取窗口句柄
            m_window =QWindow::fromWinId(wid);
            m_window->setFlags(m_window->flags()| Qt::CustomizeWindowHint | Qt::WindowTitleHint);
    
            QWidget* m_widget;
            m_widget =QWidget::createWindowContainer(m_window,this);
            ui->containerWidget->layout()->addWidget(m_widget);}}private slots:voidreadData(){
        QHostAddress host;
        quint16 port;
        QByteArray data;
        QString buffer;while(socket->hasPendingDatagrams()){
            data.resize(socket->pendingDatagramSize());
            socket->readDatagram(data.data(), data.size(),&host,&port);
        
            buffer =QString(data);OnDataRecived(buffer);
            QString ip = host.toString();
            ip = ip.replace("::ffff:","");if(ip.isEmpty()){continue;}
        
            QString str =QString("[%1:%2] %3").arg(ip).arg(port);//先过滤重复的
            str =QString("%1:%2").arg(ip).arg(port);for(int i =0; i < m_client.count(); i++){if(str == m_client.at(i)){return;}}//添加到列表
            m_client.push_back(str);}}};
  1. Unity 客户端设置 在 Unity 中,使用 System.Net.Sockets.UdpClient 创建一个 UDP 客户端,并向 QT 服务器发送数据:
publicclassUnityClient:MonoBehaviour{privateUdpClient client;voidStart(){
        client =newUdpClient();SendMessageToServer("Connect");
        client.BeginReceive(OnReceive,null);}voidSendMessageToServer(string message){byte[] data = Encoding.UTF8.GetBytes(message);
        client.Send(data, data.Length,"127.0.0.1",12345);}privatevoidOnReceive(IAsyncResult ar){IPEndPoint endpoint =newIPEndPoint(System.Net.IPAddress.Any,54321);byte[] data = client.EndReceive(ar,ref endpoint);string command = Encoding.UTF8.GetString(data);

        Debug.Log("Received command: "+ command);// 根据命令执行相应的操作if(command =="switch_scene"){SwitchScene();}elseif(command =="create_object"){CreateObject();}// 继续接收下一个命令
        client.BeginReceive(OnReceive,null);}voidSwitchScene(){// 切换到另一个场景
        SceneManager.LoadScene("AnotherScene");}voidCreateObject(){// 创建一个简单的游戏物体GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
        cube.transform.position =newVector3(0,1,0);}voidOnDestroy(){
        client.Close();}}

此脚本在 Unity 中启动时会向 QT 服务器发送一条消息。QT收到消息后会获取Unity程序的窗口句柄,并把这个窗口嵌入到QT中

实际应用场景

通过上述设置,QT 程序可以在桌面上实时控制 VR 场景中的行为,例如切换场景或创建游戏物体。这种交互方式适用于各种需要实时控制 VR 场景的应用场景,比如 VR 培训、虚拟展览等。

总结

本文详细介绍了如何通过 QT 服务器向 Unity VR 程序发送命令,以实现场景切换和游戏物体创建等交互功能。通过 UDP 进行通讯,您可以实现桌面和 VR 头盔之间的无缝互动,提升用户体验。如果您在实施过程中遇到问题或有其他需求,欢迎交流讨论。

标签: unity qt 交互

本文转载自: https://blog.csdn.net/fuchenyang01/article/details/141719776
版权归原作者 爱写代码的辰洋 所有, 如有侵权,请联系我们删除。

“Unity+QT, 如何把Unity打包出的exe嵌入QT程序中,并且使用Socket进行交互”的评论:

还没有评论