環境:
- VS2015
- Unity 5.3.6f1 (64-bit)
目的:
Unity官方提供的UnityWebPlayer控件在嵌入Winform時要求讀取的.unity3d文件路徑(Src)必須是絕對路徑,如果移動代碼到另一臺電腦,需要重新修改src。于是考慮使用winform用戶控件來進行封裝,以實現讀取存放在工程文件夾下的.unity3d文件的效果。
參考:
-
WinForm內嵌Unity3D_winform嵌入unity3d并交互__學而時習之_的博客-CSDN博客
-
https://www.cnblogs.com/xieyulin/p/7050618.html
過程
首先新建windows用戶窗體庫。
然后在空白控件上添加UnityWebPlayer,這一步是為了添加Interop.UnityWebPlayerAXLib.dll、AxInterop.UnityWebPlayerAXLib.dll兩個引用。
當引用列表里出現這兩個引用時,把剛才添加的UnityWebPlayer控件刪除。
然后修改控件的.cs文件,代碼如下
//U3DPlayer.csusing System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace UnityPlayer
{public partial class U3Dplayer: UserControl{#region 自定義事件//委托public delegate void ExternalCallHandler(object sender, AxUnityWebPlayerAXLib._DUnityWebPlayerAXEvents_OnExternalCallEvent e);/// <summary>/// 接收Unity調用宿主函數的消息/// </summary>[Browsable(true), Description("接收Unity調用宿主(如WinForm)函數的消息")]public event ExternalCallHandler UnityCall;//方法public void OnUnityCall(object sender, AxUnityWebPlayerAXLib._DUnityWebPlayerAXEvents_OnExternalCallEvent e){if (UnityCall != null){UnityCall(sender, e);}}#endregion#region 內部變量private AxUnityWebPlayerAXLib.AxUnityWebPlayer _axUnityWebPlayer = null;#endregion/// <summary>/// 用戶控件函數/// </summary>public U3Dplayer(){InitializeComponent();string src = Application.StartupPath + "\\unity.unity3d";//在這里設置路徑_axUnityWebPlayer = CreateUnity(this, src);OnExternalCallCheck();this.Controls.Add(_axUnityWebPlayer);//在原控件上添加UnityWebPlayer控件}/// <summary>/// 建立一個新的unity控件并設置一些屬性/// </summary>/// <param name="form"></param>/// <param name="src"></param>/// <returns></returns>public static AxUnityWebPlayerAXLib.AxUnityWebPlayer CreateUnity(Control form, string src){var unity = new AxUnityWebPlayerAXLib.AxUnityWebPlayer();((System.ComponentModel.ISupportInitialize)(unity)).BeginInit();form.Controls.Add(unity);((System.ComponentModel.ISupportInitialize)(unity)).EndInit();unity.src = src;AxHost.State state = unity.OcxState;//最關鍵的是OcxState,必須使用AxUnityWebPlayer才能依據Src動態產生。unity.Dispose();unity = new AxUnityWebPlayerAXLib.AxUnityWebPlayer();((System.ComponentModel.ISupportInitialize)(unity)).BeginInit();form.SuspendLayout();unity.Dock = DockStyle.Fill;//unity.Size = new System.Drawing.Size(720, 450);unity.Name = "Unity";unity.OcxState = state;unity.TabIndex = 0;//unity.Location = new System.Drawing.Point(0, 0);((System.ComponentModel.ISupportInitialize)(unity)).EndInit();form.ResumeLayout(false);return unity;}private void OnExternalCallCheck(){if (_axUnityWebPlayer == null){throw new Exception("_axUnityWebPlayer init fail");}else{_axUnityWebPlayer.OnExternalCall += _axUnityWebPlayer_OnExternalCall;}}void _axUnityWebPlayer_OnExternalCall(object sender, AxUnityWebPlayerAXLib._DUnityWebPlayerAXEvents_OnExternalCallEvent e){if (e.value.StartsWith("LOAD_COMPLETE")){if (!_axUnityWebPlayer.Visible){_axUnityWebPlayer.Width = this.Width;_axUnityWebPlayer.Height = this.Height;_axUnityWebPlayer.Show();}}OnUnityCall(sender, e);}#region SendMessage/// <summary>/// 發送消息給Unity/// </summary>/// <param name="unityObjName">Unity中的對象名稱</param>/// <param name="unityScriptyMethod">Unity腳本中的方法</param>/// <param name="val">傳送的值.僅限于int、float、string</param>public void SendMessage(string unityObjName, string unityScriptyMethod, object val){if (_axUnityWebPlayer == null){return;}_axUnityWebPlayer.SendMessage(unityObjName, unityScriptyMethod, val);}#endregion}
}
然后選擇生成動態鏈接庫。
在Winform工程中選擇“工具”–“選擇工具箱項”–導入,即可使用
轉 :Winform基于UnityWebplayer封裝用戶控件以實現.unity3d文件相對路徑(動態src) - 灰信網(軟件開發博客聚合)