我想在WPF中開發一個新的CAD軟件,而不是使用WPF 3D,是否可以使用Unity3D作爲我的圖形引擎,可以旋轉,平移,縮放和查看3D圖形對象基於我在WPF中的數據對象?在WPF應用程序內嵌入Unity3D應用程序
我問這個問題的原因是,Unity是一個遊戲引擎,它使用C#作爲腳本,但它沒有提供任何WPF應用程序的集成(將Unity嵌入到WPF中)。
我在統一論壇上問過這個問題,找不到任何好的答案,所以要求更多的觀衆。
我想在WPF中開發一個新的CAD軟件,而不是使用WPF 3D,是否可以使用Unity3D作爲我的圖形引擎,可以旋轉,平移,縮放和查看3D圖形對象基於我在WPF中的數據對象?在WPF應用程序內嵌入Unity3D應用程序
我問這個問題的原因是,Unity是一個遊戲引擎,它使用C#作爲腳本,但它沒有提供任何WPF應用程序的集成(將Unity嵌入到WPF中)。
我在統一論壇上問過這個問題,找不到任何好的答案,所以要求更多的觀衆。
這可以做到,但值得注意的是它只能在Windows上工作。
它曾經很難做到這一點,但最近Unity(4.5.5p1)添加了-parentHWND
命令,可用於將其程序嵌入到另一個程序中。所有你需要做的就是構建你的Unity應用程序,然後從WPF開始,使用Process
API。然後,您可以將-parentHWND
參數傳遞給Unity應用程序。
process.StartInfo.FileName = "YourUnityApp.exe";
process.StartInfo.Arguments = "-parentHWND " + panel1.Handle.ToInt32() + " " + Environment.CommandLine;
對於兩者之間的換向,可以使用TCP或Named Pipes。
下面是來自Unity網站的嵌入代碼的完整示例。你可以得到整個項目here。確保命名Unity的構建EXE文件「UnityGame.exe」然後將其放在與WPF EXE程序相同的目錄中。
namespace Container
{
public partial class Form1 : Form
{
[DllImport("User32.dll")]
static extern bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw);
internal delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam);
[DllImport("user32.dll")]
internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam);
[DllImport("user32.dll")]
static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
private Process process;
private IntPtr unityHWND = IntPtr.Zero;
private const int WM_ACTIVATE = 0x0006;
private readonly IntPtr WA_ACTIVE = new IntPtr(1);
private readonly IntPtr WA_INACTIVE = new IntPtr(0);
public Form1()
{
InitializeComponent();
try
{
process = new Process();
process.StartInfo.FileName = "UnityGame.exe";
process.StartInfo.Arguments = "-parentHWND " + panel1.Handle.ToInt32() + " " + Environment.CommandLine;
process.StartInfo.UseShellExecute = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.WaitForInputIdle();
// Doesn't work for some reason ?!
//unityHWND = process.MainWindowHandle;
EnumChildWindows(panel1.Handle, WindowEnum, IntPtr.Zero);
unityHWNDLabel.Text = "Unity HWND: 0x" + unityHWND.ToString("X8");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + ".\nCheck if Container.exe is placed next to UnityGame.exe.");
}
}
private void ActivateUnityWindow()
{
SendMessage(unityHWND, WM_ACTIVATE, WA_ACTIVE, IntPtr.Zero);
}
private void DeactivateUnityWindow()
{
SendMessage(unityHWND, WM_ACTIVATE, WA_INACTIVE, IntPtr.Zero);
}
private int WindowEnum(IntPtr hwnd, IntPtr lparam)
{
unityHWND = hwnd;
ActivateUnityWindow();
return 0;
}
private void panel1_Resize(object sender, EventArgs e)
{
MoveWindow(unityHWND, 0, 0, panel1.Width, panel1.Height, true);
ActivateUnityWindow();
}
// Close Unity application
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
try
{
process.CloseMainWindow();
Thread.Sleep(1000);
while (!process.HasExited)
process.Kill();
}
catch (Exception)
{
}
}
private void Form1_Activated(object sender, EventArgs e)
{
ActivateUnityWindow();
}
private void Form1_Deactivate(object sender, EventArgs e)
{
DeactivateUnityWindow();
}
}
}
非常感謝... – ParkAtStreet
是的,它可以處理Unity。儘管如此,你可以用任何3D遊戲引擎進行平移,旋轉和縮放,所以我不能說出這個問題的關鍵。 – Programmer
非常感謝。我修改了我的問題,請看看。你有沒有試過使用WPF作爲你的主應用程序,並調用Unity3D來顯示圖形顯示? – ParkAtStreet
之前使用過WPF,但沒有使用Unity。 WPF僅適用於Windows。如果你想使用它,然後使用它。如果你想使用Unity,那麼去Unity。我認爲沒有必要混合兩者。您最終將只能在Windows上運行一個複雜的應用程序。 – Programmer