unity3D嵌入Winform、MFC的实现方式_洛北辰南的博客-程序员信息网_unity嵌入winform

技术标签: winform  Unity3D  嵌入  通讯  unity3D  mfc  

前言

大概是去年还没开学的时候,提前到校,给老师干活拿到的需求,可能也跟我说对unity3D有兴趣有关系吧。总之就是unity3D做模拟环境,但是呢,要嵌入要其他的软件中去使用,窗口环境,也就是题目上的那几种,Winform、MFC。
先写一写印象中的思路,代码还要再找找…电脑数据丢过,不太好找到了。
就在这个时候…我翻了一下聊天记录,梳理了思路。

unity嵌入Winform

在winform中可以嵌入unity专用插件
在这里插入图片描述

unity相对路径的设置

大家都知道,在插件初始化的时候,会直接加载完成这个插件的内容,也就是说,如果直接用插件本身去读取unity,需要使用绝对路径,这样就无法实现分布式了,肯定是不能直接提交给上级的。
所以,思路大概是这样的,首先在界面中加入一个窗口的控件,在这个空间里加载一个UnityWebPlayer Control,由于是在空白控件上生成一个新的控件,所以可以在代码中对unity路径进行设置,也就实现了相对路径。
也可借鉴WinFrom内嵌Unity3D
具体代码找不到了…只有一部分PPT讲解时候的记录

private void InitUnity()
{
    
    var unity = new AxUnityWebPlayerAXLib.AxUnityWebPlayer();
    ((System.ComponentModel.ISupportInitialize)(unity)).BeginInit();
    Controls.Add(unity);
    ((System.ComponentModel.ISupportInitialize)(unity)).EndInit();
    unity.src = Application.StartupPath + "\\u.unity3d";  //改成自己想要的路径
    AxHost.State state = unity.OcxState;
    unity.Dispose();
    unity = new AxUnityWebPlayerAXLib.AxUnityWebPlayer();
    (System.ComponentModel.ISupportInitialize)(unity)).BeginInit();
    this.SuspendLayout();
    unity.Dock = DockStyle.Fill;
    unity.Name = "Unity";
    unity.OcxState = state;
    unity.TabIndex = 0;
    this.Controls.Add(unity); 
    ((System.ComponentModel.ISupportInitialize)(unity)).EndInit();
    this.ResumeLayout(false);
}

unity与winform的通讯过程

由于嵌入winform的是unity的专用控件,所以通讯方式也是内部直接写好的

//winfrom向unity的名为air的gameobject的Channel方法,发送task消息
private void button_Click(object sender, EventArgs e)
{
    
    axUnityWebPlayer1.SendMessage("air", "Channel", task);
}
//unity接收winform发给Channel方法的消息string c
public void Channel(string c) {
    
    StartCoroutine(GetRoutine(c));
}
//unity向winform中unity控件的LOAD_COMPLETE方法发送""消息
    Application.ExternalCall("LOAD_COMPLETE", "");
//winform接收unity发来的消息
//e.value == "LOAD_COMPLETE()"
//e.value.StartsWith("LOAD_COMPLETE") == true
private void axUnityWebPlayer1_OnExternalCall(object sender, AxUnityWebPlayerAXLib._DUnityWebPlayerAXEvents_OnExternalCallEvent e)
{
    
    this.label1.Text = e.value;
}

unity嵌入MFC

这里由于UnityWebPlayer Control并不兼容MFC,所以需要借用另外的方式来实现这一需求,UnityWebPlayer原本就是为网页游戏提供的一种插件,自然可以在网页控件上实现,这里我在MFC中加入web browser也就是浏览器的意思。unitywebplayer在导出的时候,会有html、js、unity3d等多个文件,html是静态文件,所以选用js来跟unity做交互,通过js对unity、mfc的消息进行转发,来达到unity与mfc互通的目标。

unity→js→mfc

//unity
Application.ExternalCall("SayHello_From_Unity", "The game says hello!");
//js
function SayHello_From_Unity(args) {
    
			alert(args);
			o.ShowMessageBox("~~~");
}
//mfc
void CRobotteach::ShowMessageBox(const wchar_t *msg)
{
    
	MessageBox(msg, L"这是来自javascript的消息");
}

mfc→js→unity

//mfc
//m_unity是一个WebBrowser的Activex控件对象。  
CComQIPtr<IHTMLDocument2> spDoc = m_unity.get_Document();
CComDispatchDriver spScript;
spDoc->get_Script(&spScript);

//代码更新于VS2017
CComVariant var1 = 10, var2 = 20, varRet;
spScript.Invoke2(L"Add", &var1, &var2, &varRet);

//代码更新于VS2015
CString hello = L"Hello--MFC";
VARIANT res = _variant_t(hello);
HRESULT hr = spScript.Invoke1(L"SayHello_From_MFC",&res);
//js
function SayHello_From_MFC(args) {
    
	alert(args);
	u.getUnity().SendMessage("arm", "Hello", "Hello from a web page!");
}
//unity
public void Hello(string args) {
    
    DebugConsole.Log(args);
}

js主动向unity,是需要一定基础的,在这篇文章中可以找到答案。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_18941713/article/details/84652412

智能推荐

栈和深度优先搜索(DFS)_你的游戏我的妃的博客-程序员信息网_栈 深度优先

如上图: 使用 DFS 找出从根结点 A 到目标结点 G 的路径 步骤如下: 1:从根节点A开始,选择节点B的路径,继续深入,直到E,无法更进一步深入,此时栈内容为ABE 依次退栈EB 2:回溯到A节点,选择第二条路径C入栈,E入栈,但E已被访问过,弹出E,回溯到C节点;选择另一条路径 F入栈,G入栈。此时我们找到了G。此时栈内容(路径)为ACFG总的来说,在我...

利用typedef定义函数指针_weixin_41632560的博客-程序员信息网_typedef定义函数指针

利用typedef定义函数指针2015年08月18日 10:56:46阅读数:4151利用typedef定义函数指针进入正文: 代码简化, 促进跨平台开发的目的. typedef 行为有点像 #define 宏,用其实际类型替代同义字。 不同点:typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换。用法一:typedef int (*MYFUN)(int, int); 这种...

杭州PHP语言程序,PHP语言做网站入门指引-杭州做网站_Adn无解的博客-程序员信息网

PHP语言做网站入门指引2020-02-18 来源:PHP(“PHP: Hypertext Preprocessor”,超文本预处理器的字母缩写)是一种被广泛应用的开放源代码的多用途脚本语言,它可嵌入到 HTML中,尤其适合 web 开发。以上是一个简单的回答,不过这是什么意思呢?请看如下例子:Example #1 一个介绍性的范例Exampleecho "Hi,I'maPH...

思科《计算机网络》第二章测试答案_廾匸φ蓉珊的博客-程序员信息网_一位技术人员使用以下命令来配置交换机

1.口令可用于限制对 Cisco IOS 所有或部分内容的访问。请选择可以用口令保护的模式和接口。(请选择三项。)选择一项或多项:VTY 接口控制台接口以太网接口启动 IOS 模式特权 EXEC 模式路由器配置模式2.技术人员为什么要输入命令 copy startup-config running-config?选择一项:从交换机删除所有配置将一个活动配置保存到 NVRAM将一个现有配置复制到 RAM使一个已更改配置成为新的启动配置3.Cisco IOS CLI 的上下文相关帮助

Unity3D研究院之Assetbundle的原理(六十一)_lzkqcc的博客-程序员信息网

Assetbundle 是Unity Pro提供提供的功能,它可以把多个游戏对象或者资源二进制文件封装到Assetbundle中,提供了封装与解包的方法使用起来很便利。1.预设         Assetbundle可以将Prefab封装起来,这是多么方便啊! 而且我也强烈建议大家将Prefab封装成Assetbundle,因为Prefab可以将游戏对象身上带的游戏游戏组件、游戏脚

用pandas或numpy处理数据中的空值(np.isnan()/pd.isnull())__illusion_的博客-程序员信息网_numpy.isnan

最近在做数据处理的时候,遇到个让我欲仙欲死的问题,那就是数据中的空值该如何获取。我的目的本来是获取数据中的所有非零且非空值,然后再计算获得到的所有数据计算均值,再用均值把0和空值填上。这个操作让我意识到了i is None/np.isnan(i)/i.isnull()之间的差别,再此做简单介绍:1.关于np.nan:先明确一个问题,即空值的产生只有np.nan()一种方法。# n...

随便推点

QueryPerformanceFrequency、QueryPerformanceCounter作用_梦幻DUO的博客-程序员信息网

QueryPerformanceFrequency是操作系统的性能统计分辨率,也就是每秒钟统计多少次的意思。 性能统计频率和应用程序性能没有关系。 顺便说说 QueryPerformanceCounter 是系统性能统计计数器,表示统计了多少次,除以QueryPerformanceFrequency,得到系统运行时间(秒数)。 QueryPerformanceCounter2-QueryPe

python实现邮件自动发送--代码_贪婪的小白的博客-程序员信息网_python自动发送邮件代码

python实现邮件自动发送文章目录python实现邮件自动发送完整代码实现效果具体实现讲解完整代码import smtplibfrom email.mime.text import MIMETextfrom email.header import Headerfrom email.mime.multipart import MIMEMultipart#配置环境 连接服务器server='smtp.qq.com' #smtp.qq.com smtp.126.com ......smtp=

位域外部申明_(外部)域特定语言的完整指南_danpu0978的博客-程序员信息网

位域外部申明 本指南将向您显示: 什么 :定义后,我们将研究19个DSL实例 原因 :使用DSL可以带来哪些具体好处? 方法 :我们将讨论构建DSL的不同方法以及成功的因素是什么 之后,您将获得一系列资源以学习更多内容:书籍,网站,论文,屏幕录像。 这是有关领域特定语言的最完整资源。 我希望你会喜欢它! 只是一件事:在这里,我们尝试变得实用且易于理解。 如果您正在寻找...

数据结构之栈的顺序存储结构实现_Roger-Pang的博客-程序员信息网_实现栈的顺序存储结构

栈的顺序存储结构实现 栈的数据元素之间的一一对应的关系可以利用顺序的存储来表示, 那么可以利用数组来实现栈数据结构.// 栈的数组实现struct stack_record;typedef struct stack_record * stack;stack init_stack(int max_elements); // 初始化操作, 建立空栈void dispose_st...

线性规划单纯形法python实现_梓铭zyb的博客-程序员信息网_python实现单纯形法

用python实现线性规划中的单纯形法例题如下(已是标准形式):maxz=1500x1+1000x2max z=1500x_1+1000x_2maxz=1500x1​+1000x2​{3x1+2x2+x3=652x1+x2+x4=403x2+x5=75x1,x2,x3,x4,x5≥0\left\{ \begin{array}{c} 3x_1+2x_2+x_3=65 \\ 2x_1+x_2+x_4=40 \\ 3x_2+x_5=75\\ x_1,x_2,x_3,x

6个方便的Git Bash脚本_cuml0912的博客-程序员信息网

1. gitlog gitlog根据主版本显示当前补丁的简短列表。 它从最旧到最新打印它们,并显示作者和描述,其中H代表HEAD , ^代表HEAD ^ , 2代表HEAD〜2,依此类推。 例如: $ gitlog-----------------------[ recovery25 ]-----------------------(snip)11 340d27a33895 Bob...

推荐文章

热门文章

相关标签