unity3d winform_unity3d 嵌入winform - CSDN
  • 转载自: https://blog.csdn.net/xxdddail/article/details/49890643代码下载: http://download.csdn.net/detail/xxdddail/9277447Unity3D可以C#脚本进行开,使用vstu2013.msi插件,可以实现在VS2013中的调试。...

    转载自:          https://blog.csdn.net/xxdddail/article/details/49890643

    代码下载:      http://download.csdn.net/detail/xxdddail/9277447


    Unity3D可以C#脚本进行开,使用vstu2013.msi插件,可以实现在VS2013中的调试。在开发完成后,由于项目需要,需要将Unity3D嵌入到WinForm中。WinForm中的UnityWebPlayer Control可以载入Unity3D。先看效果图。


    一、为了能够动态设置axUnityWebPlayer的Src,我使用用户控件来封装。看下面的代码。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Threading;


    namespace UnityHost
    {
        public partial class U3DPlayer : UserControl, IMessageFilter
        {
            #region 属性
            private String _src;
            /// <summary>
            /// Unity3D文件的路径
            /// </summary>
            public String Src
            {
                get { return _src; }
                private set { _src = value; }
            }


            private bool _disableMouseRight = true;
            /// <summary>
            /// 禁用鼠标右键
            /// </summary>
            public bool DisableMouseRight
            {
                get { return _disableMouseRight; }
                set { _disableMouseRight = value; }
            }


            #endregion


            #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;
            private ProgressBar _progressBarLoad=null;
            #endregion


            public U3DPlayer()
            {
                InitializeComponent();
                InitProgressBar();
            }


            private void InitProgressBar()
            {
                if (_progressBarLoad == null)
                {
                    _progressBarLoad = new ProgressBar();
                    _progressBarLoad.Height = 100;
                    _progressBarLoad.Style = ProgressBarStyle.Marquee;
                    _progressBarLoad.Top = (this.Height - _progressBarLoad.Height) / 2;
                    Controls.Add(_progressBarLoad);
                }
            }


            #region InitUnity
            /// <summary>
            /// 初始化UnityWebPlayer
            /// </summary>
            /// <param name="src">Unity3D文件的路径</param>
            public void InitUnity(String src)
            {
                Src = src;
                if (!File.Exists(Src))
                {
                    return;
                }
                var unity = new AxUnityWebPlayerAXLib.AxUnityWebPlayer();
                ((System.ComponentModel.ISupportInitialize)(unity)).BeginInit();
                Controls.Add(unity);
                ((System.ComponentModel.ISupportInitialize)(unity)).EndInit();
                unity.src = Src;//Application.StartupPath + "\\u.unity3d";  //改成自己想要的路径
                AxHost.State state = unity.OcxState;
                Controls.Remove(unity);
                unity.Dispose();
                unity = new AxUnityWebPlayerAXLib.AxUnityWebPlayer();
                ((System.ComponentModel.ISupportInitialize)(unity)).BeginInit();
                this.SuspendLayout();
                unity.Dock = DockStyle.Fill;
                //unity.Name = "Unity";
                unity.OcxState = state;
                unity.TabIndex = 0;
                this.Controls.Add(unity); //panel1是我用的一个容器,改成this.Controls也可以
                ((System.ComponentModel.ISupportInitialize)(unity)).EndInit();
                this.ResumeLayout(false);
                _axUnityWebPlayer = unity;
                if (_axUnityWebPlayer == null)
                {
                    throw new Exception("_axUnityWebPlayer init fail");
                }
                else
                {
                    _axUnityWebPlayer.OnExternalCall += _axUnityWebPlayer_OnExternalCall;
                    _axUnityWebPlayer.Hide();
                    ShowProgressBar();
                }
            }
            #endregion


            #region 进度条
            private void ShowProgressBar()
            {           
                _progressBarLoad.Visible = true;
                _progressBarLoad.Left = 0;
                _progressBarLoad.Width = this.Width;
            }


            private void HideProgressBar()
            {
                if (_progressBarLoad!=null)
                {
                    _progressBarLoad.Visible = false;    
                }            
            }
            #endregion


            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();
                        HideProgressBar();
                    }
                }
                OnUnityCall(sender, e);
            }




            private void U3DPlayer_Load(object sender, EventArgs e)
            {
                Graphics g = this.CreateGraphics();
                g.Clear(this.BackColor);


                if (DisableMouseRight)
                {
                    Application.AddMessageFilter(this);
                    this.Disposed += U3DPlayer_Disposed;
                }
            }


            void U3DPlayer_Disposed(object sender, EventArgs e)
            {
                if (DisableMouseRight)
                {
                    Application.RemoveMessageFilter(this);
                }
            }


            #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


            private void U3DPlayer_MouseDown(object sender, MouseEventArgs e)
            {


            }


            /// <summary>
            /// 过滤鼠标右键
            /// </summary>
            /// <param name="m"></param>
            /// <returns></returns>
            public bool PreFilterMessage(ref System.Windows.Forms.Message m)
            {
                if (_axUnityWebPlayer == null)
                {
                    return false;
                }
                const int WM_RBUTTONDOWN = 0x204;
                const int WM_RBUTTONUP = 0x205;
                const int WM_RBUTTONDBLCLK = 0x206;
                // 屏蔽右键消息区域。
                System.Drawing.Rectangle my_Area = new System.Drawing.Rectangle(_axUnityWebPlayer.Location, _axUnityWebPlayer.Size);


                if (my_Area.Contains(this.PointToClient(Control.MousePosition)))
                {
                    switch (m.Msg)
                    {
                        case WM_RBUTTONDOWN:
                            return true;
                        case WM_RBUTTONUP:
                            return true;
                        case WM_RBUTTONDBLCLK:
                            return true;
                        default:
                            return false;
                    }
                }


                return false;
            }


        }

    }


    注:代码中还实现了其他的功能,如下

    1.增加InitUnity方法,方便外层控件调用。这里最关键的是OcxState,必须使用AxUnityWebPlayer才能依据Src动态产生。

    2.动态增加进度条。

    3.在实始化后对_axUnityWebPlayer进行隐藏,同时启动进度条,并绑定Unity的回调事件OnExternalCall。在OnExternalCall事件中,监听Unity发来的LOAD_COMPLETE值,然后判断是否显示_axUnityWebPlayer.

    4.为了能让外层也收到Unity发来的消息,使用委托二次实现了OnExternalCall,也就是OnUnityCall方法。

    5.SendMessage的实现,第一个参数为Unity中的对象名称,第二个参数为Unity脚本中的方法,第三个参数是传送的值(仅限于int、string,其他的会失败或者异常)。

    6.继承IMessageFilter接口,捕获消息,然后过滤_axUnityWebPlayer区域内产生的鼠标右键消息,同时增加DisableMouseRight属性来控制。

    7.一定要将项目调成x86的模式,否则会报“没有注册类XXX”的信息。

    8.axUnityWebPlayer控件需要在工具箱中添加,如下图。


    二、窗体界面的代码

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;


    namespace UnityHost
    {
        public partial class FormHost : Form
        {
            public FormHost()
            {
                InitializeComponent();
            }


            private void buttonSendToUnity_Click(object sender, EventArgs e)
            {
                String info = textBoxSendMessage.Text;
                if (String.IsNullOrWhiteSpace(info))
                {
                    MessageBox.Show("请输入内容");
                    return;
                }
                u3DPlayer1.SendMessage("Main Camera", "CallUnity", info);
            }


            private void FormHost_Load(object sender, EventArgs e)
            {
                String src = Application.StartupPath + "\\UnityWeb\\UnityWeb.unity3d";
                u3DPlayer1.InitUnity(src);
            }


            private void u3DPlayer1_UnityCall(object sender, AxUnityWebPlayerAXLib._DUnityWebPlayerAXEvents_OnExternalCallEvent e)
            {
                this.Text = "收到Unity的消息:" + e.value;
            }
        }

    }

    三、Unity3D的C#脚本


    using UnityEngine;

    using System.Collections;
    using System;


    public class Main : MonoBehaviour
    {


        private string _messageReceive = string.Empty;
        private bool _isButtonClick = false;
        private int _notifyTimeAfterLoadComplete = 3;


        // Use this for initialization
        void Start()
        {


        }


        // Update is called once per frame
        void Update()
        {


        }


        void OnGUI()
        {
            if (GUI.Button(new Rect(100, 10, 80, 20), "测试"))
            {
                _isButtonClick = !_isButtonClick;
            }


            GUI.Label(new Rect(50, 30, 150, 30), _messageReceive);


            if (_isButtonClick)
            {
                Application.ExternalCall("ToWinform", Guid.NewGuid().ToString());
                _isButtonClick = false;
            }


            if (_notifyTimeAfterLoadComplete>0)
            {
                Application.ExternalCall("LOAD_COMPLETE", "");
                _notifyTimeAfterLoadComplete--;
            }
        }


        void CallUnity(object val)
        {
            _messageReceive = string.Format("{0}", val);
        }
    }

    注:

    1.CallUnity是响应WinForm发来消息的函数。

    2.Application.ExternalCall是向WinForm发出消息,第一参数是函数的名称,第二个之后的参数是函数的参数。

    四、Unity3D要在WebPlayer模式下编译


    转载请注明出处

    请耐心读完





    展开全文
  • 1.Unity按键事件的实现 2.WinForm内嵌Unity3D 3.axUnityWebPlayer的Src的动态设置,右键禁用,隐藏图标实现进度条加载
  • WinFormUnity3d互操作

    2020-07-30 23:32:25
    Unity3D嵌入Winform或是在Winform中嵌入Unity3D,并让二者相互通信。很多人会用得到的,很详细,希望大家喜欢。
  • 网上对于Unity3DWinForm的通信文章不少https://www.cnblogs.com/cnxkey/articles/5394378.html,我对我最近在这方面所作的研究和应用做一个总结,供大家参考。 1 Unity3D Unity3D由Unity Technologies开发的一个...

    网上对于Unity3D与WinForm的通信文章不少https://www.cnblogs.com/cnxkey/articles/5394378.html,我对我最近在这方面所作的研究和应用做一个总结,供大家参考。

    1 Unity3D

    Unity3D由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。Unity类似于Director、Blender game engine、Virtools或Torque Game Builder等利用交互的图形化开发环境为首要方式的软件。其编辑器运行在Windows和Mac OS X下,可发布游戏至Windows、Mac、Wii、Iphone、WegGL(需要HTML5)、Windows phone 8和Android平台。也可以利用Unity web player插件发布网页游戏,支持Mac和Windows的网页浏览。

    2 UnityWebPlayer

    Unity开发网页游戏,发布的时候可以选择Web Player和WebGL。Unity5.4版本以后发布只能选择WebGL,WebPalyer能用的最高版本是5.3.8。

    3 在WinForm程序中使用Unity3D控件

    Unity3D虽然有自己的UI控件,但是有些时候开发人员还是希望能把Unity3D场景嵌入到WinForm中,以结果其他三维显示组件针对不同的需求使用不同的组件显示。WinForm是可以通过UnityWebPlayer控件和Unity3D发布的网页版进行通信的。

    (1)安装和引入UnityWeb Player插件

    需准备UnityWebPlayer的32位和64位(鉴于有些软件发布为64位的版本)两个版本,先安装32位,再安装64位。在程序中引入UnityWebPlayer的DLL文件。
    (2)在程序中添加Unity项目发布的网页版本:

    (3)向Untiy项目发送消息:
    m_unity.SendMessage("Quad_bird","NewFunc",null);
    其中,"Quad_bird"为Unity中对象名;"NewFunc"为附在"Quad_bird"对象上的方法名;null为方法的输入参数.
    (4)Unity项目对WinForm消息的反馈
    在Unity脚本中,自定义一个发送消息事件(当鼠标单击时发出):
    Public  void OnMouseUp(){Application.ExternalCall("IP",aaa);} //向客户端发送消息
    (5)WinForm通过UnityWebPlayer注册一个事件:publicevent _DUnityWeb PlayerAXEvents_OnExternalCallEventHandler
    OnExternalCall即可接收到Unity项目发出的消息,如图:

    4 Unity消息解译器

    以上研究了Unity与WinForm之间的信息通信问题,这只能说明Unity和WinForm之间是能够进行消息交互的。要实现Unity和
    WinForm之间比较一致的操作,还需要一个标准统一的“契约”(配置文件)。这个契约需要定义不同消息和字符的映射关系,
    Unity和WinForm则通过这些字符来解译消息含义,其结构如下:

    展开全文
  • WinForm内嵌Unity3D

    2015-11-17 18:08:18
    在开发完成后,由于项目需要,需要将Unity3D嵌入到WinForm中。WinForm中的UnityWebPlayer Control可以载入Unity3D。先看效果图。 一、为了能够动态设置axUnityWebPlayer的Src,我使用用户控件来封装。看下面的代码...

    Unity3D可以C#脚本进行开,使用vstu2013.msi插件,可以实现在VS2013中的调试。在开发完成后,由于项目需要,需要将Unity3D嵌入到WinForm中。WinForm中的UnityWebPlayer Control可以载入Unity3D。先看效果图。


    一、为了能够动态设置axUnityWebPlayer的Src,我使用用户控件来封装。看下面的代码。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Threading;
    
    namespace UnityHost
    {
        public partial class U3DPlayer : UserControl, IMessageFilter
        {
            #region 属性
            private String _src;
            /// <summary>
            /// Unity3D文件的路径
            /// </summary>
            public String Src
            {
                get { return _src; }
                private set { _src = value; }
            }
    
            private bool _disableMouseRight = true;
            /// <summary>
            /// 禁用鼠标右键
            /// </summary>
            public bool DisableMouseRight
            {
                get { return _disableMouseRight; }
                set { _disableMouseRight = value; }
            }
    
            #endregion
    
            #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;
            private ProgressBar _progressBarLoad=null;
            #endregion
    
            public U3DPlayer()
            {
                InitializeComponent();
                InitProgressBar();
            }
    
            private void InitProgressBar()
            {
                if (_progressBarLoad == null)
                {
                    _progressBarLoad = new ProgressBar();
                    _progressBarLoad.Height = 100;
                    _progressBarLoad.Style = ProgressBarStyle.Marquee;
                    _progressBarLoad.Top = (this.Height - _progressBarLoad.Height) / 2;
                    Controls.Add(_progressBarLoad);
                }
            }
    
            #region InitUnity
            /// <summary>
            /// 初始化UnityWebPlayer
            /// </summary>
            /// <param name="src">Unity3D文件的路径</param>
            public void InitUnity(String src)
            {
                Src = src;
                if (!File.Exists(Src))
                {
                    return;
                }
                var unity = new AxUnityWebPlayerAXLib.AxUnityWebPlayer();
                ((System.ComponentModel.ISupportInitialize)(unity)).BeginInit();
                Controls.Add(unity);
                ((System.ComponentModel.ISupportInitialize)(unity)).EndInit();
                unity.src = Src;//Application.StartupPath + "\\u.unity3d";  //改成自己想要的路径
                AxHost.State state = unity.OcxState;
                Controls.Remove(unity);
                unity.Dispose();
                unity = new AxUnityWebPlayerAXLib.AxUnityWebPlayer();
                ((System.ComponentModel.ISupportInitialize)(unity)).BeginInit();
                this.SuspendLayout();
                unity.Dock = DockStyle.Fill;
                //unity.Name = "Unity";
                unity.OcxState = state;
                unity.TabIndex = 0;
                this.Controls.Add(unity); //panel1是我用的一个容器,改成this.Controls也可以
                ((System.ComponentModel.ISupportInitialize)(unity)).EndInit();
                this.ResumeLayout(false);
                _axUnityWebPlayer = unity;
                if (_axUnityWebPlayer == null)
                {
                    throw new Exception("_axUnityWebPlayer init fail");
                }
                else
                {
                    _axUnityWebPlayer.OnExternalCall += _axUnityWebPlayer_OnExternalCall;
                    _axUnityWebPlayer.Hide();
                    ShowProgressBar();
                }
            }
            #endregion
    
            #region 进度条
            private void ShowProgressBar()
            {           
                _progressBarLoad.Visible = true;
                _progressBarLoad.Left = 0;
                _progressBarLoad.Width = this.Width;
            }
    
            private void HideProgressBar()
            {
                if (_progressBarLoad!=null)
                {
                    _progressBarLoad.Visible = false;    
                }            
            }
            #endregion
    
            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();
                        HideProgressBar();
                    }
                }
                OnUnityCall(sender, e);
            }
    
    
            private void U3DPlayer_Load(object sender, EventArgs e)
            {
                Graphics g = this.CreateGraphics();
                g.Clear(this.BackColor);
    
                if (DisableMouseRight)
                {
                    Application.AddMessageFilter(this);
                    this.Disposed += U3DPlayer_Disposed;
                }
            }
    
            void U3DPlayer_Disposed(object sender, EventArgs e)
            {
                if (DisableMouseRight)
                {
                    Application.RemoveMessageFilter(this);
                }
            }
    
            #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
    
            private void U3DPlayer_MouseDown(object sender, MouseEventArgs e)
            {
    
            }
    
            /// <summary>
            /// 过滤鼠标右键
            /// </summary>
            /// <param name="m"></param>
            /// <returns></returns>
            public bool PreFilterMessage(ref System.Windows.Forms.Message m)
            {
                if (_axUnityWebPlayer == null)
                {
                    return false;
                }
                const int WM_RBUTTONDOWN = 0x204;
                const int WM_RBUTTONUP = 0x205;
                const int WM_RBUTTONDBLCLK = 0x206;
                // 屏蔽右键消息区域。
                System.Drawing.Rectangle my_Area = new System.Drawing.Rectangle(_axUnityWebPlayer.Location, _axUnityWebPlayer.Size);
    
                if (my_Area.Contains(this.PointToClient(Control.MousePosition)))
                {
                    switch (m.Msg)
                    {
                        case WM_RBUTTONDOWN:
                            return true;
                        case WM_RBUTTONUP:
                            return true;
                        case WM_RBUTTONDBLCLK:
                            return true;
                        default:
                            return false;
                    }
                }
    
                return false;
            }
    
        }
    }
    
    注:代码中还实现了其他的功能,如下

    1.增加InitUnity方法,方便外层控件调用。这里最关键的是OcxState,必须使用AxUnityWebPlayer才能依据Src动态产生。

    2.动态增加进度条。

    3.在实始化后对_axUnityWebPlayer进行隐藏,同时启动进度条,并绑定Unity的回调事件OnExternalCall。在OnExternalCall事件中,监听Unity发来的LOAD_COMPLETE值,然后判断是否显示_axUnityWebPlayer.

    4.为了能让外层也收到Unity发来的消息,使用委托二次实现了OnExternalCall,也就是OnUnityCall方法。

    5.SendMessage的实现,第一个参数为Unity中的对象名称,第二个参数为Unity脚本中的方法,第三个参数是传送的值(仅限于int、string,其他的会失败或者异常)。

    6.继承IMessageFilter接口,捕获消息,然后过滤_axUnityWebPlayer区域内产生的鼠标右键消息,同时增加DisableMouseRight属性来控制。

    7.一定要将项目调成x86的模式,否则会报“没有注册类XXX”的信息。

    8.axUnityWebPlayer控件需要在工具箱中添加,如下图。


    二、窗体界面的代码

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace UnityHost
    {
        public partial class FormHost : Form
        {
            public FormHost()
            {
                InitializeComponent();
            }
    
            private void buttonSendToUnity_Click(object sender, EventArgs e)
            {
                String info = textBoxSendMessage.Text;
                if (String.IsNullOrWhiteSpace(info))
                {
                    MessageBox.Show("请输入内容");
                    return;
                }
                u3DPlayer1.SendMessage("Main Camera", "CallUnity", info);
            }
    
            private void FormHost_Load(object sender, EventArgs e)
            {
                String src = Application.StartupPath + "\\UnityWeb\\UnityWeb.unity3d";
                u3DPlayer1.InitUnity(src);
            }
    
            private void u3DPlayer1_UnityCall(object sender, AxUnityWebPlayerAXLib._DUnityWebPlayerAXEvents_OnExternalCallEvent e)
            {
                this.Text = "收到Unity的消息:" + e.value;
            }
        }
    }
    
    三、Unity3D的C#脚本

    using UnityEngine;
    using System.Collections;
    using System;
    
    public class Main : MonoBehaviour
    {
    
        private string _messageReceive = string.Empty;
        private bool _isButtonClick = false;
        private int _notifyTimeAfterLoadComplete = 3;
    
        // Use this for initialization
        void Start()
        {
    
        }
    
        // Update is called once per frame
        void Update()
        {
    
        }
    
        void OnGUI()
        {
            if (GUI.Button(new Rect(100, 10, 80, 20), "测试"))
            {
                _isButtonClick = !_isButtonClick;
            }
    
            GUI.Label(new Rect(50, 30, 150, 30), _messageReceive);
    
            if (_isButtonClick)
            {
                Application.ExternalCall("ToWinform", Guid.NewGuid().ToString());
                _isButtonClick = false;
            }
    
            if (_notifyTimeAfterLoadComplete>0)
            {
                Application.ExternalCall("LOAD_COMPLETE", "");
                _notifyTimeAfterLoadComplete--;
            }
        }
    
        void CallUnity(object val)
        {
            _messageReceive = string.Format("{0}", val);
        }
    }
    
    注:

    1.CallUnity是响应WinForm发来消息的函数。

    2.Application.ExternalCall是向WinForm发出消息,第一参数是函数的名称,第二个之后的参数是函数的参数。

    四、Unity3D要在WebPlayer模式下编译


    转载请注明出处

    代码下载http://download.csdn.net/detail/xxdddail/9277447


    展开全文
  • winform内嵌unity

    2017-02-23 13:18:43
    都是为了学习,转载时不用打招呼,标明出处就行,实在不想标明,也可以!

        公司3D仿真产品的开发全部基于Unity3Dunity作为游戏引擎在3D端的开发优势不言而喻,unity开发3D虚拟产品的市场占有率几乎80%。但是作为物流教学仿真产品或者其他行业仿真产品的展现层面我们发现游戏UI和业务系统的UI还是有一定的差别,很多的用户还是比较习惯WinForm或者WPF中的UI形式,游戏化的UI适合单独功能展现,而业务系统的UI更侧重数据间的逻辑与分析的展现,,我们需要的就是这种业务化的UI交互。

    于是在网上搜了一下WinFormUnity3D如何集成,有人给出了使用WebBrowser控件的形式,这种形式之前在做公司3D产品WEB版转换时使用过不管是嵌入winform的方式以及嵌入后unitywinform的通信都遵循webplayeru.getUnity().SendMessageApplication.ExternalCall那一套,用起来还算相当方便的。但是unity5.0以后抛弃webpalyer了。

    webplayer方式肯定走不通了,除非你继续用unity4.6。有了另外一种思路,winform的窗体打包成动态链接库,然后在unity中调用自己打包的dll。界面用winform做好,打包动态链接库,导入unity,调用,确实行的通。通信有两种方式,一种是通过委托,另外一种是winform中引用unityEngine.dll后直接使用sendmessage。很便捷的一种方案。

    继续百度,发现了更好的一种方式,winform嵌入unity打包的exe,这种形式从展现层面使得3D场景和业务系统界面不再孤立,并且winform的开发与unity相互独立,只需要提前约定好通信协议。通信方式有好几种,win32窗口句柄、内存共享,socket通信,我们选择socket去搞了。

    嵌入只是形式,通信才是核心,不说废话了,直接上通信方案。

    2、Unity结合winform的实践


    这就是我们想看到的样子,嵌入,并且功能独立,更重要的是可以相互通信!!!

    a) 方式1winform嵌入webpalyer

    i. 新建winform项目

    ii. 在工具箱里引入UnityWebPlayer Control控件

    通信:

    1Unity->winform

    unity发送


    Winform接收


    2、winform->unity

    Winform发送:


    Unity接收:

    b) 方式2unity调用winform动态链接库

    i. 新建winform项目,做好界面部分

    ii. 修改项目属性中的输出类型为类库,并生成

    iii. 将生成的dll导入unity并引用

    完成以上三步,其实功能只完成了一半,最重要的解决通信问题。

    1、unity->winform

    winform打包为动态链接库之前,写好接收函数,引入库第一个用来支持winform下的方法,第二个是我打包的dll文件。


    Unity引用并发送:


    Winform接收:


    2、Winform->Unity

       Winformunity通信有两种比较快捷的方式,第一种winform引用unityEngine库,调用sendmessage方法。说到这,突然想到,其实sendmessage这个方法也是unity模仿winform的消息机制搞的一个接口,确实很方便,与unity的组件机制相结合,想往哪个物体上的某一个脚本发消息都很快捷。

    Winform发送:

    Unity接收:首先挂在脚本到li物体上,脚本里定义SetName方法。


    c) 方式3winform打包的exe嵌入unity打包的exe。(推荐方法)

    i. 新建winform程序。

    ii. winform里使用ProcessStartInfo启动外部应用程序,并通过win32提供的窗口控制方法,将此exe嵌入到指定的组件中。详见opexe.cs

    通信问题:

    使用socket方案,winform创建服务器,unity作为客户机去连接。

    服务端:TcpServer.cs





    客户端:MyTcpClient.cs





    展开全文
  • 总之就是unity3D做模拟环境,但是呢,要嵌入要其他的软件中去使用,窗口环境,也就是题目上的那几种,Winform、MFC。 先写一写印象中的思路,代码还要再找找…电脑数据丢过,不太好找到了。 就在这个时候…我翻了...
  • 一般来说,在windows PC端用Unity3D制作的软件都是单窗体,如果要动态创建窗体常用的办法是通过调整摄像机的深度实现窗体的出现和隐藏.可是如果使用这种方式来动态创建Winfrom窗体的话,存在设计繁琐,窗体位置固定...
  • UnityWinform两个应用程序中都引入socket,这里使用TcpClient服务器端我们使用Java的mina长连接框架客户端的通信主体框架有两种,一种是处理器类的,一种是事件绑定的: 服务器端主体通信框架如下,与客户端框架...
  • unitywinform集成问题

    2017-11-28 10:43:43
    AxUnityWebPlayer里src怎么在winform启动的时候给src路径,我是新手!
  • 1.unity服务端,接收来自winform的Picht, Yaw, Roll /// /// scoket服务器监听端口脚本 /// public class SocketServer : MonoBehaviour {  public GameObject obj;  private Thread thStartServer;/...
  • Unity 的 安装目标(一般是”D:\Program Files\Unity\Editor\Data\Mono\lib\mono\2.0“)中有一些直接可以放置在Plugins文件夹下的动态连接库文件,其中System.Drawing和Sytem.Windows.Form是文本的核心。...
  • winform内嵌.exe的方式都大同小异,只不过这里记录一下Unity3D的设置,如果需要程序之间通讯,可以用socket,winform程序开服务器,unity程序客户端连接,这里不再搬砖了。 一、首先是unity build设置 canvas...
  • Unity3D内部串口通信和Unity3DWinForm程序间的串口通信。容易引发的错误、异常,以及串口正常工作的区别。解决方法和思路。
  • 打算使用这个时髦、流行、强大的游戏引擎开发一个三维业务展示系统,不过发现游戏的UI和业务系统的UI还是有一定的差别,很多的用户还是比较习惯WinForm或者WPF中的UI形式,于是在网上搜了一下WinFormUnity3D如何...
  • 实现winform内嵌unity

    2019-04-14 14:26:08
    源码和成品下载地址:... 效果如下: 一、需要下载UnityWebPlayer插件进行安装 下载地址:http://webplayer.unity3d.com/download_webplayer-3.x/UnityWebPlayerFull.exe 如下图所示: 二、...
  • winform C#调用Unity3d的Activex
  • Unity3D里使用WinForm

    2019-07-21 15:19:15
    之前给一个游戏写过MOD,功能大概是在游戏里可以打开一个编辑器,然后可以直接在编辑器里修改到游戏...Unity内部虽然有完善的UGUI系统,但是UGUI的布局,是放在prefab上的(虽然也可以直接代码写UI,但是比较蛋疼)...
  • C# winform嵌入unity3D

    2018-08-25 00:10:46
     最近做项目需要winform嵌入unity的功能,由于完全没接触过这类嵌入的于是在网上搜,有一种方法是UnityWebPlayer插件,也开始琢磨了一段时间,不过一会发现在5.4版本以后这个东西就被淘汰了,所以果断放弃。...
1 2 3 4 5 ... 20
收藏数 1,203
精华内容 481
热门标签
关键字:

unity3d winform