嵌入方式两种,官方的-parentHandle和我的WinAPI嵌入。
问题1.主程序卡死
[-parentHandle]:主程序打开3D后,切换到其他程序,再切换回来,卡死。
[WinAPI]:主程序打开3D后,过一段时间卡死。其实这里的打开的Unity程序也算是其他程序了。
这个问题结果发现是主程序其他部分导致的。
问题2.嵌入Unity的控件隐藏后,GPU使用率达到99%。
所谓的Unity控件隐藏是指嵌入Unity程序的Panel,这里命名为UnityPanel,在主程序中不显示时,最小化没关系。
两种都会有。
考虑修改Unity的打包方式。
感觉相关的属性有 Run In Background和 Visible In Background。
生成4种情况
True True:会99%,原来打包的方式
True False:会99%
False True:不会99%,但是,一旦失去焦点,Unity程序就停止运行了,就算是焦点在主程序也一样。
False False:和上面一个一样。
单独的Unity程序不会有问题,考虑在控件隐藏时让Unity程序独立出来。
独立出来后还要隐藏,不然突然多出一个窗口。
隐藏和显示用User32.dll的ShowWindow,不过隐藏不是用SW_HIDE而是用,SW_MINIMIZE。SW_HIDE本身就会导致那个99%的问题。
但是嵌入的控件无法自动识别是否显示的状态,必须通过在主程序的各个地方添加调用函数主动控制Unity程序的状态。
public void SetVisible(bool isVisible)
{
if (isVisible == false)
{
NoEmbedWnd();//独立显示
ShowMini();//最小化
//HideTaskBarIcon();//隐藏任务栏图标,但是用了的话GPU就还是99%了
}
else
{
EmbedWnd();
ShowNormal();
}
}
public void HideTaskBarIcon()
{
User32.SetWindowLong(WndHandle, User32.GWL_EXSTYLE, User32.WS_EX_TOOLWINDOW);
}
public void EmbedWnd()
{
if (IsEmbeded == true) return;
IsEmbeded = true;
User32.SetParent(WndHandle, ParentWnd);
}
public void NoEmbedWnd()
{
if (IsEmbeded == false) return;
IsEmbeded = false;
User32.SetParent(WndHandle, IntPtr.Zero);
}
public void ShowMini()
{
User32.ShowWindow(WndHandle, User32.SW_MINIMIZE);
}
public void ShowNormal()
{
User32.ShowWindow(WndHandle, User32.SW_NORMAL);
}
扩展问题:任务栏图标怎么隐藏?将Unity独立出来后,点击任务栏上的图标就能单独看到Unity的程序了。
放弃隐藏任务栏菜单的情况下,可以让窗口看不到。通过设置窗口的边框位置,让窗口处于显示器外面。不过要在设置窗口独立前设置,独立后设置就没有效果了。为什么呢?
既然是因为控件隐藏导致的,让控件不隐藏就好了,或者该控件隐藏时让Unity嵌入到另一个不会被隐藏的控件中:在主程序的一个现实区域添加一个小块的WindowsFormsHost,里面放一块Panel,这里命名为UnityHidePanel,让UnityPanel隐藏时将Unity程序嵌入到UnityHidePanel中。GPU99%和任务栏图标问题就解决了。
将该WindowsFormsHost的长宽设置为0,不用看到。另外发现,设置为1,即有长宽时GPU是30%;设置为0时,是14%,即Unity程序单独运行时最小化时的状态。
不过在切换的一瞬间GPU会提高一下,稍微卡一下,1s左右。这个是概率出现的和下面的闪一下一样看电脑的状态的。
问题3.[WinAPI]:打开Unity时,Unity程序可能会闪一下。
从上的问题的处理方法想到,能否先用[-parentHandle]嵌入到一个控件中,再用[WinAPI]方式嵌入到另一个控件中。这样就不会闪一下,而且,也能输入中文了。
结果发现不行,用-parentHandle方式打开的Unity程序,就是独立出来,也是无法输入的。别说中文了,英文也无法输入。
问题4.[-parentHandle]:无法输入中文。
暂时没找到办法,只能改用WinAPI方式了。
问题5.主程序意外关闭后,Unity程序还在后台运行。
要不要弄个心跳包之类的,主程序不在了,Unity程序也就自己退出。