2017-01-19 11:23:39 ckpckp 阅读数 2602
  • Unity3D入门精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4711 人正在学习 去看看 张刚

http://www.cnblogs.com/NuclearBoy/p/6092221.html

写在前面:

 

把Unity3D嵌入winform或者wpf程序,过去大部分使用UnityWebPlayer插件来实现,这个插件其实就是网页上播放unity页游的插件。

但是使用UnityWebPlayer嵌入桌面开发有各种问题,我认为最大的问题是效率问题(加载缓慢),毕竟是网页的加载方式,而且可以确认未来也不会得到任何优化。

由于WebGL的高速发展,unity公司认识到了webplayer十分鸡肋,毕竟WebGL不需要任何插件可以直接显示3d内容了,所以Unity3D在5.4.x版本以后明确表示

不再支持webplayer了,所以桌面上UnityWebPlayer插件能不用也就别用了吧。所以大家不要走弯路!!

 

主要内容:

 

将Unity嵌入桌面程序最好的方式是嵌入unity生成的exe程序,winform程序和unity之间通过socket进行通讯,我认为

这也是效率最高,效果最好和最好实现的方式。在Unity程序脚本中,嵌入socket内容,我推荐做成客户端(client),使用wpf程序做服务器端,这是一个谁是主体的问题。

这样wpf可以加载多个unity程序。

 

嵌入后的结果如下图所示(请无视具体内容):

下面简单写了一个脚本,其中man是游戏中的一个gameobject对象。就是上图中穿蓝衣服的男人。在他身上挂着socket脚本如下:

复制代码
using UnityEngine;
using System.Collections;
using System.Net.Sockets;
using System;

public class demoshows : MonoBehaviour {
    public GameObject man;



    const int portNo = 500;
    private TcpClient _client;
    byte[] data;

    string Error_Message;

    void Start () {
        try
        {
            this._client = new TcpClient();
            this._client.Connect("127.0.0.1", portNo);
            data = new byte[this._client.ReceiveBufferSize];
            //SendMessage(txtNick.Text);
            SendMessage("Unity Demo Client is Ready!");
            this._client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);
        }
        catch (Exception ex)
        {


        }
       


    }
    

    void Update () {        
        transform.Rotate(new Vector3(0, 1, 0),0.1f);
    }


    public void rotation()

    {

        transform.Rotate(new Vector3(0, 10, 0));
        //targetRotation = Quaternion.Euler(45.0f, 45.0f, 45.0f);
        //// 直接设置旋转角度 
        //transform.rotation = targetRotation;
        ////man.transform.rotation.SetAxisAngle(new Vector3(0, 1, 0), 30);;                                                                                                                      
    }



    public void translateX(float x)

    {

        transform.Translate(new Vector3(x,0,0));
                                                                                                                      
    }

    public void translateY(float y)

    {

        transform.Translate(new Vector3(0, y, 0));
                                                                                                         
    }


    public void translateZ(float z)

    {

        transform.Translate(new Vector3(0, 0, z));
                                                                                                                   
    }



    void OnGUI()
    {
        GUI.Label(new Rect(50, 50, 150,50 ), Error_Message);
    }


    public new void SendMessage(string message)
    {
        try
        {
            NetworkStream ns = this._client.GetStream();
            byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
            ns.Write(data, 0, data.Length);
            ns.Flush();
        }
        catch (Exception ex)
        {
            Error_Message = ex.Message;
            //MessageBox.Show(ex.ToString());
        }
    }
    public void ReceiveMessage(IAsyncResult ar)
    {
        try
        {
            //清空errormessage
            Error_Message = "";
            int bytesRead;
            bytesRead = this._client.GetStream().EndRead(ar);
            if (bytesRead < 1)
            {
                return;
            }
            else
            {
                Debug.Log(System.Text.Encoding.ASCII.GetString(data, 0, bytesRead));
                string message = System.Text.Encoding.ASCII.GetString(data, 0, bytesRead);
                switch (message)
                {
                    case "1":
                        translateX(1);
                    break;

                    case "2":
                        translateX(-1);
                        break;
                    case "3":
                        translateY(1);
                        break;
                    case "4":
                        translateY(-1);
                        break;
                    case "5":
                        translateZ(1);
                        break;
                    case "6":
                        translateZ(-1);
                        break;
                    default:
                        Error_Message = "unknown command";
                        break;


                }




            }
            this._client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);
        }
        catch (Exception ex)
        {
            Error_Message = ex.Message;
        }
    }


    void OnDestroy()
    {

        this._client.Close();
    }




}
复制代码

 

脚本很简单,就是通过向unity程序发送消息(1~6)实现模型的平移。

 

服务器端,在wpf程序中简单建立一个socket类,ip和端口要和unity对应,在程序启动时先建立服务器端。

 

复制代码
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Diagnostics;
using System.Text;
using System;


namespace Demo_Song
{
    class TcpServer
    {
        //私有成员
        private static byte[] result = new byte[1024];
        private int myProt = 500;   //端口  
        static Socket serverSocket;
        static Socket clientSocket;

        Thread myThread;
        static Thread receiveThread;

        //属性

        public int port { get; set; }
        //方法


        
        internal void StartServer()
        {
            //服务器IP地址  
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            serverSocket.Bind(new IPEndPoint(ip, myProt));  //绑定IP地址:端口  
            serverSocket.Listen(10);    //设定最多10个排队连接请求  

            Debug.WriteLine("启动监听{0}成功", serverSocket.LocalEndPoint.ToString());
       
            //通过Clientsoket发送数据  
            myThread = new Thread(ListenClientConnect);
            myThread.Start();
            
        }


        internal void QuitServer()
        {

            serverSocket.Close();
            clientSocket.Close();
            myThread.Abort();
            receiveThread.Abort();


        }


        internal void SendMessage(string msg)
        {
                clientSocket.Send(Encoding.ASCII.GetBytes(msg));
        }



        /// <summary>  
        /// 监听客户端连接  
        /// </summary>  
        private static void ListenClientConnect()
        {
            while (true)
            {
                try
                {
                    clientSocket = serverSocket.Accept();
                    clientSocket.Send(Encoding.ASCII.GetBytes("Server Say Hello"));
                    receiveThread = new Thread(ReceiveMessage);
                    receiveThread.Start(clientSocket);
                }
                catch (Exception)
                {

                }

            }
        }

        /// <summary>  
        /// 接收消息  
        /// </summary>  
        /// <param name="clientSocket"></param>  
        private static void ReceiveMessage(object clientSocket)
        {
            Socket myClientSocket = (Socket)clientSocket;
            while (true)
            {
                try
                {
                    //通过clientSocket接收数据  
                    int receiveNumber = myClientSocket.Receive(result);
                    Debug.WriteLine("接收客户端{0}消息{1}", myClientSocket.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(result, 0, receiveNumber));
                }
                catch (Exception ex)
                {
                    try
                    {
                        Debug.WriteLine(ex.Message);
                        myClientSocket.Shutdown(SocketShutdown.Both);
                        myClientSocket.Close();
                        break;
                    }
                    catch (Exception)
                    {
                    }

                }
            }
        }
    }
}  

复制代码

 

使用socket一定要注意使用线程,并且退出时及时结束,我这里实现的也不是很好,谁有更好的方法可以告诉我。

下面大概就是server的启动和释放,效果还好,至少不卡死....

 

 

复制代码
        TcpServer WpfServer;
        int size_state = 0;
        public MainWindow()
        {
            InitializeComponent();


            this.Closed += MainWindow_Closed;
            this.Activated += MainWindow_Activated;
            this.Deactivated += MainWindow_Deactivated;



            WpfServer = new TcpServer();
            WpfServer.StartServer();


        }


        void MainWindow_Closed(object sender, EventArgs e)
        {
            unityhost.Form1_FormClosed();


            WpfServer.QuitServer();

        }
复制代码

 

 

 

 

关于socket通讯的问题大概就这样,大家估计更关系如何嵌入的问题

 

如何嵌入?

 

首先在wpf程序中建立一个winform的自定义控件(不是wpf控件)usercontrol

在usercontrol内新建一个panel(或者其他带有句柄的控件),并设置dock属性为fill。

启动unity.exe,通过几个api将unity窗口附加在panel句柄上。

(说明:借鉴别人的程序)

需要把unity程序命名为child.exe,放在下面指定位置(Debug\UnityApp\Child.exe,或者release)

process.StartInfo.FileName =Application.StartupPath +@"\UnityApp\Child.exe";

详细代码如下:

复制代码
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;

namespace Demo_Song
{
    public partial class UnityControl : UserControl
    {
        [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 UnityControl()
        {
            InitializeComponent();
            this.Load += UnityControl_Load;
            panel1.Resize+=panel1_Resize;
        }

        private void UnityControl_Load(object sender, EventArgs e)
        {
            try
            {
                process = new Process();
                process.StartInfo.FileName =Application.StartupPath +@"\UnityApp\Child.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)
            {
                unityHWNDLabel.Text = ex.Message;
                //MessageBox.Show(ex.Message);
            }
        }

        internal void ActivateUnityWindow()
        {
            SendMessage(unityHWND, WM_ACTIVATE, WA_ACTIVE, IntPtr.Zero);
        }

        internal 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
        internal void Form1_FormClosed()
        {
            try
            {
                process.CloseMainWindow();

                Thread.Sleep(1000);
                while (process.HasExited == false)
                    process.Kill();
            }
            catch (Exception)
            {

            }
        }

        internal void Form1_Activated()
        {
            ActivateUnityWindow();
        }

        internal void Form1_Deactivate()
        {
            DeactivateUnityWindow();
        }
    }

}
复制代码

 

 

最后附上源码,github重置密码死活连不上,现在就传压缩包到百度云把,vs版本较高(2012)以上可以打开,注意,低版本打不开工程。

 

链接: https://pan.baidu.com/s/1gf4vIiZ

密码: fv9f

 

貌似写得有点长了,能看到这里的人不多吧哈哈,希望有做类似需求的人少走弯路吧,碎觉去,over~。


2017-03-23 13:28:02 barenk 阅读数 3440
  • Unity3D入门精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4711 人正在学习 去看看 张刚

把Unity3D嵌入winform或者wpf程序,过去大部分使用UnityWebPlayer插件来实现,这个插件其实就是网页上播放unity页游的插件。

但是使用UnityWebPlayer嵌入桌面开发有各种问题,我认为最大的问题是效率问题(加载缓慢),毕竟是网页的加载方式,而且可以确认未来也不会得到任何优化。

由于WebGL的高速发展,unity公司认识到了webplayer十分鸡肋,毕竟WebGL不需要任何插件可以直接显示3d内容了,所以Unity3D在5.4.x版本以后明确表示,不再支持webplayer了,所以桌面上UnityWebPlayer插件能不用也就别用了吧。

将Unity嵌入桌面程序最好的方式是嵌入unity生成的exe程序,winform程序和unity之间通过socket进行通讯,我认为

这也是效率最高,效果最好和最好实现的方式。在Unity程序脚本中,嵌入socket内容,我推荐做成客户端(client),使用wpf程序做服务器端,这是一个谁是主体的问题。

这样wpf可以加载多个unity程序。

 


嵌入后的结果如下图所示(请无视具体内容):


下面简单写了一个脚本,其中man是游戏中的一个gameobject对象。

就是上图中穿蓝衣服的男人。在他身上挂着socket脚本如下

using UnityEngine; using System.Collections; using System.Net.Sockets; using System; public class demoshows : MonoBehaviour { public GameObject man; const int portNo = 500; private TcpClient _client; byte[] data; string Error_Message; void Start () { try { this._client = new TcpClient(); this._client.Connect("127.0.0.1", portNo);
            data = new byte[this._client.ReceiveBufferSize]; //SendMessage(txtNick.Text); SendMessage("Unity Demo Client is Ready!"); this._client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);
        } catch (Exception ex)
        {


        }
       


    } void Update () {        
        transform.Rotate(new Vector3(0, 1, 0),0.1f);
    } public void rotation()

    {

        transform.Rotate(new Vector3(0, 10, 0)); //targetRotation = Quaternion.Euler(45.0f, 45.0f, 45.0f); //// 直接设置旋转角度  //transform.rotation = targetRotation; ////man.transform.rotation.SetAxisAngle(new Vector3(0, 1, 0), 30);;   } public void translateX(float x)

    {

        transform.Translate(new Vector3(x,0,0));
                                                                                                                      
    } public void translateY(float y)

    {

        transform.Translate(new Vector3(0, y, 0));
                                                                                                         
    } public void translateZ(float z)

    {

        transform.Translate(new Vector3(0, 0, z));
                                                                                                                   
    } void OnGUI()
    {
        GUI.Label(new Rect(50, 50, 150,50 ), Error_Message);
    } public new void SendMessage(string message)
    { try {
            NetworkStream ns = this._client.GetStream(); byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
            ns.Write(data, 0, data.Length);
            ns.Flush();
        } catch (Exception ex)
        {
            Error_Message = ex.Message; //MessageBox.Show(ex.ToString());  }
    } public void ReceiveMessage(IAsyncResult ar)
    { try { //清空errormessage Error_Message = ""; int bytesRead;
            bytesRead = this._client.GetStream().EndRead(ar); if (bytesRead < 1)
            { return;
            } else {
                Debug.Log(System.Text.Encoding.ASCII.GetString(data, 0, bytesRead)); string message = System.Text.Encoding.ASCII.GetString(data, 0, bytesRead); switch (message)
                { case "1":
                        translateX(1); break; case "2":
                        translateX(-1); break; case "3":
                        translateY(1); break; case "4":
                        translateY(-1); break; case "5":
                        translateZ(1); break; case "6":
                        translateZ(-1); break; default:
                        Error_Message = "unknown command"; break;


                }




            } this._client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(this._client.ReceiveBufferSize), ReceiveMessage, null);
        } catch (Exception ex)
        {
            Error_Message = ex.Message;
        }
    } void OnDestroy()
    { this._client.Close();
    }
}
脚本很简单,就是通过向unity程序发送消息(1~6)实现模型的平移。

服务器端,在wpf程序中简单建立一个socket类,ip和端口要和unity对应,在程序启动时先建立服务器端。


使用socket一定要注意使用线程,并且退出时及时结束

下面大概就是server的启动和释放,效果还好,至少不卡死

TcpServer WpfServer; int size_state = 0; public MainWindow()
        {
            InitializeComponent(); this.Closed += MainWindow_Closed; this.Activated += MainWindow_Activated; this.Deactivated += MainWindow_Deactivated;



            WpfServer = new TcpServer();
            WpfServer.StartServer();


        } void MainWindow_Closed(object sender, EventArgs e)
        {
            unityhost.Form1_FormClosed();


            WpfServer.QuitServer();

        }

如何嵌入?

 

首先在wpf程序中建立一个winform的自定义控件(不是wpf控件)usercontrol

在usercontrol内新建一个panel(或者其他带有句柄的控件),并设置dock属性为fill。

启动unity.exe,通过几个api将unity窗口附加在panel句柄上。

(说明:借鉴别人的程序)

需要把unity程序命名为child.exe,放在下面指定位置(Debug\UnityApp\Child.exe,或者release)

process.StartInfo.FileName =Application.StartupPath +@"\UnityApp\Child.exe";

详细代码如下:

using System; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Diagnostics; using System.Threading; namespace Demo_Song
{ public partial class UnityControl : UserControl
    {
        [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 UnityControl()
        {
            InitializeComponent(); this.Load += UnityControl_Load;
            panel1.Resize+=panel1_Resize;
        } private void UnityControl_Load(object sender, EventArgs e)
        { try {
                process = new Process();
                process.StartInfo.FileName =Application.StartupPath +@"\UnityApp\Child.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)
            {
                unityHWNDLabel.Text = ex.Message; //MessageBox.Show(ex.Message);  }
        } internal void ActivateUnityWindow()
        {
            SendMessage(unityHWND, WM_ACTIVATE, WA_ACTIVE, IntPtr.Zero);
        } internal 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 internal void Form1_FormClosed()
        { try {
                process.CloseMainWindow();

                Thread.Sleep(1000); while (process.HasExited == false)
                    process.Kill();
            } catch (Exception)
            {

            }
        } internal void Form1_Activated()
        {
            ActivateUnityWindow();
        } internal void Form1_Deactivate()
        {
            DeactivateUnityWindow();
        }
    }  }




2016-11-03 16:33:12 pilot10 阅读数 15940
  • Unity3D入门精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4711 人正在学习 去看看 张刚

《一》与你自己开发网页js代码交互:

方向一:你可以调用Application.ExternalCall()Application.ExternalEval()在你嵌入的网页中执行 JavaScript代码.

方向二:在网页的js代码中执行Unity中GameObjects的方法:例如

SendMessage ('MyGameObject', 'MyFunction', 'foobar')

《二》Application.ExternalCall调用JS函数

public static function ExternalCall(functionName: string, params args: object[]): void;

参数:
functionName 调用的函数名称
args 给这个函数传的参数列表

描述:
调用一个包含webGL的网页中的函数

这个函数是非阻塞的函数(不等网页执行结果而继续往下执行)

public class ExampleClass : MonoBehaviour {
    void Example() {
        // Calls MyFunction1 in the web page with no arguments
    Application.ExternalCall ("MyFunction1");
        // Calls MyFunction2 in the web page with a string
        Application.ExternalCall("MyFunction2", "Hello from Unity!");
        // Calls MyFunction3 in the web page with several arguments of different types
        Application.ExternalCall("MyFunction3", "one", 2, 3.0F);
    }
}

网页中的HTML

public static void ExternalEval(string script);

Parameters
script 执行的JS代码
Description

在嵌入WEBGL的页面中执行JS代码


        Application.ExternalEval("history.back()");
2016-05-04 16:55:33 wangxiong_zh 阅读数 1730
  • Unity3D入门精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4711 人正在学习 去看看 张刚
Unity3d Webplayer 屏蔽缓存机制

  前言:   

  在最近的项目中,出现了一个问题就是:使用unity3d webplayer的时候,当用户首次进入游戏的时候,

  如果下载AssetBundle文件失败的话,就会出现后续无法登陆的情况。这个时候客户端需要的操作就

  是删除本地的缓存文件,或者是登陆Unity3d提供的缓存服务器进行删除。这些操作对开发者来说是很

  简单的事情,但是对没有多少计算机操作知识的用户来说就显得很心烦了。

  原因如下:

  1.对于webplayer本地的缓存文件是被隐藏 了,需要进过一系列的操作去找到。这样用户基本是不愿意

  做的事,这样我们的用户就少了很多了。

  2.对于登陆缓存服务器去进行删除的操作,也是同样的道理。同时还是E文的,用户可能看都不看了。

  现在都是流行一条龙的服务,你的服务不好,那就只好下一位了。

  虽然我们现在还没有找到很好的实现方式,但是我们只要屏蔽有关数据的缓存了。缓存这个东西好处是多

  但是坏处也是不少的!

  好了。我们现在谈谈今天的主题:屏蔽缓存机制。

  方式很是简单的:

  在我们发布的html代码中加入一个<meta >标签就可以了。

  我们先看看效果:

    添加标签前的效果:

  979x486

  我们添加标签:

  853x409

  添加标签:

  855x427

  最后的效果:

  997x475

  这样webplayer缓存机制就失去效果了。很简单的操作 呵呵

  结束语:

  对于这样的方式是不好的,正在寻找有关的实现方式。看了看完美世界的页游,在处理这一块的时候做的挺不错的。希望各位大神提供和交流相应的解决方案,在此先谢谢啦!

2016-06-12 13:36:49 libt51 阅读数 745
  • Unity3D入门精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4711 人正在学习 去看看 张刚

简介:

1、Unity3D的游戏引擎是和编辑器集成在一起的,所有它也是一个制作/开发平台。

2、Unity3D是使用JavaScript、C#作为核心脚本语言来驱动事个游戏引擎。

3、平台可以发布Exe执行文件或者打包为可供网页调用的一个独立的包文件。

4、用Unity3D制作的工程具有高度的可移植性,可以在PS xbox360 Android iPhone mac等系统上运行。

嵌入网页:

1、用Unity3D实现嵌入网页和Flash插入网页原理完全一致,也是使用ActiveX控件嵌入在网页中。所以和Flash一样,需要安装一个播放器插件(小于3M)。

 

2、查看页面源码,可以看到如下嵌入部分:

<object id="UnityObject" classid="clsid:444785F1-DE89-4295-863A-D46C3A781394"width="600" height="450"codebase="http://webplayer.unity3d.com/download_webplayer/UnityWebPlayer.cab#version=2,0,0,0">

         <param name="src" value="MyDataFile.unity3d" />

         <embed id="UnityEmbed" src="MyDataFile.unity3d" width="600" height="450"type="application/vnd.unity" pluginspage="http://www.unity3d.com/unity-web-player-2.x" />

</object>

3、和Flash一样,在浏览器中加载3D场景或者读取时的图标进度条都能进行自定义,也可以自定义是否激活是用右键菜单。

 

数据交互

1、在Unity3D中调用网页js函数

         如果我们在html中有脚本函数;则在u3d中我们可用使用Application.ExternalCall调用js函数,该方法只适合在Web3D环境下使用。该方法支持基本类型的传递和数组传递,任何类型都会转换成字符串类型使用。

例子代码:

Application.ExternalCall("SayHello","The game says hello!);//调用SayHello,传递一个字符串

 

2、在Unity3D中直接执行一段脚本代码如:

Application.ExternalEval("if(document.location.host!='unity3d.com'){document.location='http://unity3d.com';}");

 

3、在js中调用Unity3D函数(传递消息等)

如果有Unity3D中有一段用JS写的功能函数:

function MyFunction(param:String)

{

         Debug.Log(param);

}

需要在JS中呼叫这个函数则可以这样写:

<script type="text/javascript" language="javascript">

SaySomethingToUnity(document.getElementById("UnityContent").SendMessage("MyObject","MyFunction","Hello fom a web page!"););

</script>

这里要注意的是MyObject代表Unity3D中的一个场景名称为MyObject,MyFunction是调用的函数,最后一个字符为传递的参数。

 

与php,jsp等的表单数据交互

         与php,jsp等的表单数据交互很可能会是今后用到的主要方式,原理是利用form表彰传递数据,下面以php为例来进行说明。

         Unity3D可以实现向某个指定页面发送表单数据然后在php中使用_POST获取传递回来的表彰数据。比如:

<?php

         $action = $_POST["myform_action"];//定义一个变量$action用来获取页面传递过来的表单数据

         if($action!=""){

                  echo $action;//如果接收到了数据则打印出数据内容

         }

?>

在Unity3D中我们发送数据的代码如下:

var form = new WWWForm();//定义一个网页表单

form.AddField("myform_action","Action1");//添加一个表彰字段名称为myform_action内容是action1

var download = new WWW("www.xxx.com/index.php",form);//发送表单数据到指定网址页面

假如index.php执行的是数据库/统计操作,我们就可以对传递的数据进行保存读取或者其他操作了。

没有更多推荐了,返回首页