2017-05-18 37 views
6

WPFで新しいCADソフトウェアを開発したいのですが、WPF 3Dを使用する代わりに、3Dグラフィックオブジェクトを回転、パン、ズーム、表示できるグラフィックエンジンとしてUnity3Dを使用することができますWPFの私のデータオブジェクトに基づいて?Unity3DアプリをWPFアプリケーションに埋め込む

Unityはゲームエンジンですが、C#をスクリプトとして使用しますが、WPFアプリケーションからの統合は行いません(UnityをWPFに埋め込む)。

私はユニティフォーラムで質問しましたが、良い答えが見つかりませんでしたので、より多くの聴衆にお尋ねください。

+0

はい、これはUnityで行うことができます。真剣にでも、3Dゲームエンジンでパン、回転、ズームすることができますので、この質問のポイントを教えていただけません。 – Programmer

+0

ありがとうございました。私は私の質問を修正しました。一見してください。メインアプリケーションとしてWPFを使用し、Unity3Dにグラフィック表示を表示しようとしたことがありますか? – ParkAtStreet

+0

Unityで使用する前にWPFを使用しましたが、使用しませんでした。 WPFはWindows用です。あなたがそれを使用したい場合は、それを使用してください。 Unityを使用したい場合は、Unityに進みます。私は2つを混ぜる必要はないと思う。あなたはWindows上でしか動作しない複雑なアプリケーションに終わるでしょう。 – Programmer

答えて

8

これは実行できますが、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; 

2つの間の整流については、TCPまたはNamed Pipesのいずれかを使用できます。

以下はUnityのウェブサイトの埋め込みコードの完全なサンプルです。あなたはプロジェクト全体を得ることができますhere。ユニティのビルド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(); 
     } 
    } 
} 
+1

ありがとうございました... – ParkAtStreet

関連する問題