环境:
- 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.cs
using 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) - 灰信网(软件开发博客聚合)