QT+Unity3D 超详细(将unity3D与QT进行连接,并实现信息传递)

QT+Unity3D连接

在QT中连接unity3D,首先要有一个unity.exe执行文件。在这里不提供unity执行文件的编写,只提供QT这边与unity3D连接和信息传递。

创建项目

创建一个新的项目,我创建的项目名称如下。
Alt
下图是我建立新项目的文件。APP文件就是我的unity.exe执行文件。
Alt
打开APP文件,里面就是关于unity3D的东西了。
Alt

直接上代码(看注释更通透)

unityConnect.pro文件中添加QT += network模块。

QT       += core gui
QT       += network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    UnityConfigure.cpp \
    main.cpp \
    UnityShow.cpp

HEADERS += \
    UnityConfigure.h \
    UnityShow.h

FORMS += \
    UnityShow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

UnityConfigure.h中。

#ifndef UNITYCONFIGURE_H
#define UNITYCONFIGURE_H

#include <QObject>
#include <QProcess>
#include <windows.h>
#include <winuser.h>
#include <qDebug>
class UnityConfigure : public QObject
{
    Q_OBJECT
public:
    explicit UnityConfigure(QObject *parent = nullptr);
    ~UnityConfigure();
    void startUnityProgram(const QString& unityExePath);

    void setWindowParent(HWND parentWidgetHandle, const QString& sonWindowTitleName);
    QProcess* process;
signals:
    void unityProgramStarted();
};

#endif // UNITYCONFIGURE_H

UnityConfigure.cpp中。

#include "UnityConfigure.h"

UnityConfigure::UnityConfigure(QObject *parent)
    : QObject{parent}
{
    process = new QProcess(this);//创建一个新的进程
    connect(process, &QProcess::started, this, &UnityConfigure::unityProgramStarted);//将进程与unity连接起来
}
UnityConfigure::~UnityConfigure()//用于关闭
{
    process->kill();//关闭进程
}
void UnityConfigure::startUnityProgram(const QString& unityExePath)
{
    process->setProgram(unityExePath);//设置unity路径
    process->start(QIODevice::Truncate);//启动进程
}

void UnityConfigure::setWindowParent(HWND parentWidgetHandle, const QString& sonWindowTitleName)//设置unity窗口属性
{
    std::wstring titleName = sonWindowTitleName.toStdWString();//设置unity标题
    HWND hfigure = nullptr;
    while (true)
    {
        hfigure = FindWindowW(nullptr, titleName.c_str());
        if (hfigure != nullptr)
        {
            break;
        }
    }
    RECT rect;
    GetWindowRect(parentWidgetHandle, &rect);//得到你要嵌入QT控件窗口的大小
    SetParent(hfigure, parentWidgetHandle);//将unity嵌入到QT控件中

    LONG_PTR dwStyle = GetWindowLongPtr(hfigure, GWL_STYLE);//子窗口样式
    dwStyle = dwStyle & ~(WS_THICKFRAME | WS_CAPTION | WS_SIZEBOX | WS_MAXIMIZEBOX | WS_MINIMIZEBOX);//移除子窗口的移动和调整大小的样式
    //如果想要使用unity缩放功能,就需要把"dwStyle |= WS_CHILD | WS_CLIPCHILDREN;"这行注释掉就可以了
    dwStyle |= WS_CHILD | WS_CLIPCHILDREN;//添加固定位置的样式。WS_CHILD 表示这是一个子窗口,WS_CLIPCHILDREN 表示绘制子窗口时,只绘制子窗口区域内的内容。
    SetWindowLongPtr(hfigure, GWL_STYLE, dwStyle);//更新子窗口的样式

    //这段代码用于改变unity窗口在QT控件中的位置以及大小。
//    MoveWindow(hfigure, 0, 0, 1400, 870, false);
//    SetWindowPos(hfigure, HWND_TOP, 0, 0, 1400, 870, SWP_SHOWWINDOW |SWP_HIDEWINDOW);
//    ShowWindow(hfigure, SW_SHOW);
//    SetFocus(hfigure);
}

UnityShow.h中。

#ifndef UNITYSHOW_H
#define UNITYSHOW_H

#include <QMainWindow>
#include "UnityConfigure.h"
#include <QTcpSocket>

QT_BEGIN_NAMESPACE
namespace Ui { class UnityShow; }
QT_END_NAMESPACE

class UnityShow : public QMainWindow
{
    Q_OBJECT
    UnityConfigure* unity;
    QTcpSocket* tcpSocket;
public:
    UnityShow(QWidget *parent = nullptr);
    ~UnityShow();
    void onReceive();//接收数据
    void onSend();//发送数据
private slots:
    void onConnected();//连接建立时的处理
    void onDisconnected();//连接断开时的处理
private:
    Ui::UnityShow *ui;
};
#endif // UNITYSHOW_H

UnityShow.cpp中。

#include "UnityShow.h"
#include "ui_UnityShow.h"

UnityShow::UnityShow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::UnityShow)
{
    ui->setupUi(this);
    unity = new UnityConfigure(this);
    QString titleName("1025using");//创建标题,切记要与unity执行文件名字相同,要不然无法嵌入到QT中

    QString unityExePath("./APP/1025using.exe");//读取unity路径
    //将QT与unity进行连接
    connect(unity, &UnityConfigure::unityProgramStarted, this, [&]()
            {
                unity->setWindowParent((HWND)ui->unityWidget->winId(),titleName);
            });
    unity->startUnityProgram(unityExePath);//启动unity
    tcpSocket = new QTcpSocket(this);//创建TCP通信
    tcpSocket->connectToHost("127.0.0.1", 9999);//进行和unity接口连接,这个接口是在unity里面进行设置的,QT直接用就行。
    connect(tcpSocket, &QTcpSocket::connected, this, &UnityShow::onConnected);
    connect(tcpSocket, &QTcpSocket::disconnected, this, &UnityShow::onDisconnected);
    onSend();//进行发送消息
}

UnityShow::~UnityShow()
{
    delete ui;
}

void UnityShow::onConnected()
{
    // 连接建立时的处理
    qDebug()<<"Connected successfully!";
}

void UnityShow::onDisconnected()
{
    // 连接断开时的处理
    qDebug()<<"disConnected successfully!";
}

void UnityShow::onReceive()
{
    // 接收unity发送的命令,收到命令之后去执行QT这边的操作。
    QByteArray data = tcpSocket->readAll();
}
void UnityShow::onSend()
{
    /*
     * 发送信息,BulletEyeRendezvous这条信息是在unity中进行设置的,
     * 然后在QT中进行发送这条消息即可。发完之后unity会执行这条信息,
     * 去执行unity接下来的程序。
    */
    QString msg="BulletEyeRendezvous";//unity设置的命令
    tcpSocket->write(msg.toUtf8());//进行发送命令
}

UnityShow.ui中,定义一个Widget控件即可。
Alt

运行结果

Alt

如果不想出现下面的unity边框,就在UnityConfigure.cpp中加上这行代码dwStyle |= WS_CHILD | WS_CLIPCHILDREN; 加完之后就不能使用unity缩放功能。
如果想要使用unity缩放功能,就需要把dwStyle |= WS_CHILD | WS_CLIPCHILDREN; 这行注释掉就可以了,但会出现unity边框。
目前我还没找到两全其美的办法,如果哪位大佬有更好的解决方法,欢迎您在评论区留言。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/224353.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python查看文件列表

os.listdir 是 Python 的一个内置函数&#xff0c;用于列出指定目录中的所有文件和子目录。它接受一个字符串参数&#xff0c;即要列出内容的目录的路径。 列出当前工作目录中的所有文件和子目录 files_and_dirs os.listdir() print(files_and_dirs) 列出指定目录中的所…

User: zhangflink is not allowed to impersonate zhangflink

使用hive2连接进行添加数据是报错&#xff1a; [08S01][1] Error while processing statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask. User: zhangflink is not allowed to impersonate zhangflink 有些文章说需要修…

解决:spring boot+mybatis进行增删改查的时候,接收到前端数据,并且执行成功了,但是数据库里面添加的内容都是空值

在写spring boot整合mybatis的时候&#xff0c;我在Apifox里面测试&#xff0c;数据也传递过去了&#xff0c;后端服务器也接收到了参数&#xff0c;就是数据库里面添加的都是空值&#xff1f;&#xff1f;&#xff1f; 前端接收到了数据&#xff0c;并且没有报错 Apifox里面也…

Kubernetes入门笔记——(2)k8s设计文档

​k8s最初源自谷歌的Brog项目&#xff0c;架构与其类似&#xff0c;主要包括etcd、api server、controller manager、scheduler、kubelet和kube-proxy等组件 etcd&#xff1a;分布式存储&#xff0c;保存k8s集群的状态 api server&#xff1a;资源操作的唯一入口&#xff0c;…

使用GPT-4V解决Pycharm设置问题

pycharm如何实现关联&#xff0c;用中文回答 在PyCharm中关联PDF文件类型&#xff0c;您可以按照以下步骤操作&#xff1a; 1. 打开PyCharm设置&#xff1a;点击菜单栏中的“File”&#xff08;文件&#xff09;&#xff0c;然后选择“Settings”&#xff08;设置&#xff09;。…

STM32——震动传感器点亮LED灯

震动传感器简单介绍 若产品不震动&#xff0c;模块上的 DO 口输出高电平&#xff1b; 若产品震动&#xff0c;模块上的 DO 口输出低电平&#xff0c;D0-LED绿色指示灯亮。 震动传感器与STM32的接线 编程实现 需求&#xff1a;当震动传感器接收到震动信号时&#xff0c;使用中断…

同旺科技 USB TO RS-485 定制款适配器--- 拆解(四)

内附链接 1、USB TO RS-485 定制款适配器 ● 支持USB 2.0/3.0接口&#xff0c;并兼容USB 1.1接口&#xff1b; ● 支持USB总线供电&#xff1b; ● 支持Windows系统驱动&#xff0c;包含WIN10 / WIN11系统32 / 64位&#xff1b; ● 支持Windows RT、Linux、Mac OS X、Windo…

Windows Installer服务启动不了问题解决办法

本章教程主要提供在win10和win11 系统服务Windows Installer&#xff0c;处于灰色状态&#xff0c;无法启动的时候的一种解决方法。 目录 解决办法 1、进入注册表 2、找到以下路径 解决办法 1、进入注册表 regedit 2、找到以下路径 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet00…

bert其他内容个人记录

Pre-training a seq2seq model BERT只是一个预训练Encoder&#xff0c;有没有办法预训练Seq2Seq模型的Decoder&#xff1f; 在一个transformer的模型中&#xff0c;将输入的序列损坏&#xff0c;然后Decoder输出句子被破坏前的结果&#xff0c;训练这个模型实际上是预训练一个…

OpenHarmony北向-让更广泛的应用开发者更容易参与

一、标准系统的体验 按照官方文档指导&#xff0c;这样操作&#xff0c;OH标准系统开发板就可以运行开发者开发的OpenHarmony应用了。 二、实际情况 按照开发文档上的说明&#xff0c;肯定是装不上的。因为OH不同的发行版&#xff0c;不同发行板不同的设备&#xff0c;IDE&…

使用Java8的Stream流的Collectors.toMap来生成Map结构

问题描述 在日常开发中总会有这样的代码&#xff0c;将一个List转为Map集合&#xff0c;使用其中的某个属性为key&#xff0c;某个属性为value。 常规实现 public class CollectorsToMapDemo {DataNoArgsConstructorAllArgsConstructorpublic static class Student {private…

java设计模式学习之【装饰器模式】

文章目录 引言装饰器模式简介定义与用途实现方式 使用场景优势与劣势装饰器模式在Spring中的应用画图示例代码地址 引言 在日常生活中&#xff0c;我们常常对基本事物添加额外的装饰以增强其功能或美观。例如&#xff0c;给手机加一个保护壳来提升其防护能力&#xff0c;或者在…

fastapi.templating与HTMLResponse

要声明一个模板对象&#xff0c;应将存储html模板的文件夹作为参数提供。在当前工作目录中&#xff0c;我们将创建一个 “templates “目录。 templates Jinja2Templates(directory“templates”) 我们现在要把这个页面的HTML代码渲染成HTMLResponse。让我们修改一下hello()函…

软考高项第四版五组十域表+ITTO背诵笔记及助记

基于第四版做的笔记&#xff0c;助记是自己编的 还是得靠理解记忆&#xff0c;下面是文档&#xff0c;也用anki制作了记忆卡片&#xff0c;需要的可以自行导入卡包

使用NimoShake将数据从AWS DynamoDB迁移至阿里云MongoDB

本文介绍从AWS DynamoDB到阿里云MongoDB的迁移框架。 它概述了以下步骤&#xff1a; 在阿里云上配置云数据库MongoDB版并应用公网终端节点在 AWS EC2 上安装 Nimoshake将AWS EC2访问阿里云MongoDB版列入白名单配置 Nimoshake 并开始迁移过程验证目标数据库上的增量数据 1. 创…

有什么可视化数据管理工具?

有什么可视化数据管理工具&#xff1f; 相信大家对数据分析并不陌生。数据可视化不仅可以使得数据更加直观、易于理解&#xff0c;而且可以帮助用户发现数据中的潜在规律和趋势。 但是&#xff0c;对于不熟悉编程的用户来说&#xff0c;如何将枯燥的大数据转化为可视化的图和…

苹果ios的系统app应用WebClip免签应用开源及方式原理

在移动设备上&#xff0c;为了方便访问我们经常使用的网站或服务&#xff0c;我们经常会希望将其添加到主屏幕上&#xff0c;以便快速启动。虽然我们可以通过使用浏览器书签实现这一目标&#xff0c;但添加一个图标到主屏幕上&#xff0c;使得它看起来与原生App无异&#xff0c…

数字工厂时代,如何实现3D数据访问与发布、WEB大模型可视化?

Tech Soft 3D的HOOPS 3D CAD SDK为现代工厂工作流程奠定了基础&#xff0c;通过最快、最准确的CAD数据访问和动态3D可视化支持数字孪生、机器人仿真、设计、流程和规划、IIoT和操作辅助应用程序。 本文将和您详细探讨。如何利用HOOPS技术来增强您的应用程序。 HOOPS_HOOPS试…

点滴生活记录1

2023/10/10 今天骑小电驴上班&#xff0c;带着小鸭子一起。路上的时候&#xff0c;我给小鸭子说&#xff0c;你要帮我看着点路&#xff0c;有危险的时候提醒我&#xff0c;也就刚说完没几分钟&#xff0c;一个没注意&#xff0c;直接撞到一个拦路铁墩子上&#xff0c;车子连人歪…

Django 模型操作(六)

Django通过Model操作数据库, 不管你数据库的类型是MySql或者Sqlite, Django自动帮你生成相应数据库类型的SQL语句,所以不需要关注SQL语句和类型,对数据的操作Django帮我们自动完成。只要会写Model就可以了。 django使用对象关系映射 (Object Relational Mapping, 简称ORM)框…