Unity中的多屏以及最大化最小化

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity中的多屏以及最大化最小化相关的知识,希望对你有一定的参考价值。

一 多屏

首先是多屏,我的需求是只显示在第二块屏幕上,而且第一块屏幕上的操作不能影响到第二块屏幕.

如果连了另一块屏幕,在打开exe的时候的配置框可以选择显示在哪块屏幕上

技术分享

 

如果选择了第二块,不删除Data文件夹,回到Unity取消勾选Display Resolution Diag,下次打开直接跳到第二快屏幕上.

二 解决第二块屏幕的后台

但是如果仅仅这样,会遇到一个不大大小的问题-在主屏幕点击一下,第二块屏幕的显示就跑到后台去了.

我是想让第二块屏幕,不受第一块屏幕的影响而跑到后台.

经过尝试,

技术分享

如果勾选就可以了.

三.获取当前窗口句柄

当前窗口就是它的进程,之前一直搜索窗口的办法,没有啥好办法

然后用了进程解决了.

参照:http://www.jb51.net/article/36226.htm

代码:

public class User32API
{
    private static Hashtable processWnd = null;

    public delegate bool WNDENUMPROC(IntPtr hwnd, uint lParam);

    static User32API()
    {
        if (processWnd == null)
        {
            processWnd = new Hashtable();
        }
    }

    [DllImport("user32.dll", EntryPoint = "EnumWindows", SetLastError = true)]
    public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, uint lParam);

    [DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)]
    public static extern IntPtr GetParent(IntPtr hWnd);

    [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId")]
    public static extern uint GetWindowThreadProcessId(IntPtr hWnd, ref uint lpdwProcessId);

    [DllImport("user32.dll", EntryPoint = "IsWindow")]
    public static extern bool IsWindow(IntPtr hWnd);

    [DllImport("kernel32.dll", EntryPoint = "SetLastError")]
    public static extern void SetLastError(uint dwErrCode);

    public static IntPtr GetCurrentWindowHandle()
    {
        IntPtr ptrWnd = IntPtr.Zero;
        uint uiPid = (uint)Process.GetCurrentProcess().Id;  // 当前进程 ID
        object objWnd = processWnd[uiPid];

        if (objWnd != null)
        {
            ptrWnd = (IntPtr)objWnd;
            if (ptrWnd != IntPtr.Zero && IsWindow(ptrWnd))  // 从缓存中获取句柄
            {
                return ptrWnd;
            }
            else
            {
                ptrWnd = IntPtr.Zero;
            }
        }

        bool bResult = EnumWindows(new WNDENUMPROC(EnumWindowsProc), uiPid);
        // 枚举窗口返回 false 并且没有错误号时表明获取成功
        if (!bResult && Marshal.GetLastWin32Error() == 0)
        {
            objWnd = processWnd[uiPid];
            if (objWnd != null)
            {
                ptrWnd = (IntPtr)objWnd;
            }
        }

        return ptrWnd;
    }

    private static bool EnumWindowsProc(IntPtr hwnd, uint lParam)
    {
        uint uiPid = 0;

        if (GetParent(hwnd) == IntPtr.Zero)
        {
            GetWindowThreadProcessId(hwnd, ref uiPid);
            if (uiPid == lParam)    // 找到进程对应的主窗口句柄
            {
                processWnd[uiPid] = hwnd;   // 把句柄缓存起来
                SetLastError(0);    // 设置无错误
                return false;   // 返回 false 以终止枚举窗口
            }
        }

        return true;
    }
} 

 四.最大化和最小化

 [DllImport("user32.dll")]
    public static extern bool ShowWindow(System.IntPtr hwnd, int nCmdShow);

 public void SetWindowMin()
    {
        ShowWindow(User32API.GetCurrentWindowHandle(), 2);//最小化
    }

    public void SetWindowMax()
    {
        ShowWindow(User32API.GetCurrentWindowHandle(), 3);//最小化
    }

 五.定义接口

本地Unity程序作为服务端(C#做服务端比较扯淡)

 

 private Socket m_server;

    void Start ()
	{
	    IPAddress local = IPAddress.Parse("127.0.0.1");
        IPEndPoint iep=new IPEndPoint(local,5099);
        m_server=new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
        m_server.Bind(iep);
        m_server.Listen(5);
        Thread ServerThread=new Thread(ServerAccept);
        ServerThread.Start();
      

    }
	
	
	void Update () {
		
	}

    private void ServerAccept()
    {
        while (true)
        {
            Debug.Log("开始接收客户端信息");
            // 得到包含客户端信息的套接字
            Socket client = m_server.Accept();
            Debug.Log("接收到客户端");
            //创建消息服务线程对象
            ServerThread newclient = new ServerThread(client);

            //把ClientThread 类的ClientService方法委托给线程
            Thread newthread = new Thread(newclient.ClientService);
            // 启动消息服务线程
            newthread.Start(20);//接收的长度大小
        }
    }

    public void OnApplicationQuit()
    {
        Debug.Log("exit");
        m_server.Close();

    }

 

using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine;

public class ServerThread
{


    private Socket m_client;
    public ServerThread(Socket client)
    {
        this.m_client = client;
    }

    public void ClientService(object param)
    {
        int fixedsize = (int)param;
        string data = null;
        byte[] bytes = null;

        Debug.Log("新客户连接建立:" + ((IPEndPoint)m_client.RemoteEndPoint).Address);
        while ((bytes = ReceiveMessage(m_client, fixedsize)).Length != 0)
        {
            data = System.Text.Encoding.ASCII.GetString(bytes, 0, fixedsize);
            Debug.Log("收到的数据:" + data);
            // 处理客户端发来的消息,这里是转化为大写字母
            data=data.Trim( ‘\\0‘);
            ExecuteOrder(data);


        }
        //关闭套接字
        m_client.Close();
        Debug.Log("客户关闭连接:" + ((IPEndPoint)m_client.RemoteEndPoint).Address);
    }


    byte[] ReceiveMessage(Socket s, int size)
    {
        size = 20;
        int offset = 0;
        int recv;
        int dataleft = size;
        byte[] msg = new byte[size];
        while (dataleft > 0)
        {
            recv = s.Receive(msg, offset, dataleft, 0);
            if (recv == 0)
            {
                break;
            }
            offset += recv;
            dataleft -= recv;
        }
        return msg;
    }

    public void ExecuteOrder(string order)
    {
        
        //Debug.Log(sb.ToString().Length);
        switch (order)
        {
            case "start":
                Debug.Log("进入start case");
                Loom.QueueOnMainThread(
                    () =>
                    {
                        CharacterManager.Instance.GetComponent<CharacterManager>().isSpeaking = true;
                    });

                break;
            case "stop":
                Loom.QueueOnMainThread(
        () =>
        {
            CharacterManager.Instance.GetComponent<CharacterManager>().isSpeaking = false;
        });
                Debug.Log("stop case");
                break;
            case "max":
                Loom.QueueOnMainThread(
       () =>
       {
          DisplayScript.Instance.SetWindowMax();
       });
                break;
            case "min":
                Loom.QueueOnMainThread(
                () =>
                                {
                                    DisplayScript.Instance.SetWindowMin();
                                });
                break;

        }
    }

}


注意:            data=data.Trim( ‘\\0‘);

因为byte中的0转换为char是 ‘\\0‘,而不是‘ ‘,‘ ‘的ascii码是32.

 









































































































以上是关于Unity中的多屏以及最大化最小化的主要内容,如果未能解决你的问题,请参考以下文章

unity多屏ui不能交互

如何使用 Unity3D 为 iPad Pro 创建多屏体验?

Unity实战篇 |Unity 打包exe 实现隐藏窗口标题栏隐藏最小化最大化关闭按钮

Unity实战篇 |Unity 打包exe 实现隐藏窗口标题栏隐藏最小化最大化关闭按钮

Unity实战篇 |Unity 打包exe 实现隐藏窗口标题栏隐藏最小化最大化关闭按钮

Cg入门20:Fragment shader - 片段级模型动态变色(实现汽车动态换漆)