winform 封装unity web player 用户控件

环境:

  • VS2015
  • Unity 5.3.6f1 (64-bit)

目的:

Unity官方提供的UnityWebPlayer控件在嵌入Winform时要求读取的.unity3d文件路径(Src)必须是绝对路径,如果移动代码到另一台电脑,需要重新修改src。于是考虑使用winform用户控件来进行封装,以实现读取存放在工程文件夹下的.unity3d文件的效果。

参考:

过程

首先新建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) - 灰信网(软件开发博客聚合)

相关推荐
道友可好19 分钟前
AI 是最好的混乱放大器:代码熵管理实战
前端·人工智能·后端
猩猩程序员1 小时前
前端学习 AI Agent 开发
前端
Younglina2 小时前
打了3年羽毛球球才发现:我对自己的装备和胜率一无所知
前端·后端
风骏时光牛马2 小时前
Bash脚本高阶实战与常见报错完整代码案例详解
前端
kartjim2 小时前
我用 AI 一小时写了一个世界杯数据可视化平台|前端 VibeCoding 初体验
前端·程序员·ai编程
lichenyang4532 小时前
从一个 WebView Demo 开始,理解 ASCF 小程序底座到底在做什么
前端
牧艺2 小时前
用 Next.js 搭建 AI Agent 前端编排:从 Plan 到 SSE Trace 的完整实践
前端·agent
行者全栈架构师2 小时前
UniApp集成vk-uview-ui组件库详解:打造高效UI开发体验
前端·vue.js
林希_Rachel_傻希希2 小时前
js里面的proxy理解。以及vue3响应式数据设计底层
前端·javascript·面试
sunrains2 小时前
uniapp x 动态Tabbar(切换无闪烁)+动角标+主题切换+自定义tabbar页面导航栏样式设置 支持服务端动态配置根据角色动态设置Tabbar
前端