关于Unity导出PC包用到的工具类总结

2020-11-2 雨辰

导出pc版,我们会遇到控制窗口的变化,监听窗口变化等需求,我这边整理下需要用的工具类:


public class PcMonitorSys : MonoBehaviour
    {
#if UNITY_STANDALONE_WIN
        private IntPtr myintptr;
        private WindowsPcUtil.RECT rect;
        private int w;
        private int h;
        private int x;
        private int y;

        //变化后的值
        private int w_c;
        private int h_c;
        private int x_c;
        private int y_c;

        private float aspect19_9;
        public int screenWidth = 1520;
        public int screenHeight = 720;
        public int widthScal = 19;
        public int heightScal = 9;

        public float w_min = 760.0f;
        public float h_min = 360.0f;

        private float old_w;
        private float old_h;

        private TimerExt _timer;
        /// <summary>
        /// 进程检查间隔
        /// </summary>
        public float _intervalCheckProcess = 10.0f;

        private bool isApplicationQuit = false;

        /// <summary>
        /// 非法进程
        /// </summary>
        private List<string> PcIllicitProcessList;

        /// <summary>
        /// 检查到非法进程是否直接杀死
        /// </summary>
        public bool IsKillIllicitProcess = false;
        
        void Awake()
        {
            AppValues.IsPcWindowChangeTipUi = false;
            isApplicationQuit = false;
            //pc端只允许启动一个游戏窗口
            Process[] gameProcess = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
            if (gameProcess.Length > 1)
            {
                isApplicationQuit = true;
                Application.Quit();
                return;
            }

            //19:9固定比例
            aspect19_9 = (float)widthScal / heightScal;
            //获取当前应用窗口
            myintptr = WindowsPcUtil.GetActiveWindow();
            //设置窗口标题
            string titleName = LocalizationService.Instance.GetFromFile(LocalizationFiles.LoginUi, LocalizationKey.PcWindowTitle);
            WindowsPcUtil.SetWindowText(myintptr, titleName);
            //启动检查游戏环境进程
            StartCheckProcess();
        }

        void Start()
        {
            WindowsPcUtil.GetWindowRect(myintptr, ref rect);
            //窗口的宽度
            w = rect.Right - rect.Left;
            //窗口的高度
            h = rect.Bottom - rect.Top;
            //窗口的位置
            x = rect.Left;
            y = rect.Top;
        }
        void LateUpdate()
        {
            SetResolution();

            WindowsPcUtil.GetWindowRect(myintptr, ref rect);
            //窗口的宽度
            w_c = rect.Right - rect.Left;
            if (w_c != w)
            {
                //提示窗口发生变化
                TipWindowChange();
                w = w_c;
                return;
            }
            //窗口的高度
            h_c = rect.Bottom - rect.Top;
            if (h_c != h)
            {
                //提示窗口发生变化
                TipWindowChange();
                h = h_c;
                return;
            }

            //x_c = rect.Left;
            //if (x_c != x)
            //{
            //    //应用窗口位置发生变化
            //    return;
            //}
            //y_c = rect.Top;
            //if (y_c != y)
            //{
            //    return;
            //}
        }

        /// <summary>
        /// 游戏窗口按19:9比例显示
        /// </summary>
        void SetResolution()
        {
            if (!AppValues.IsPcSetResolution)
            {
                return;
            }

            int curScreenWidth = Screen.width;
            int curScreenHeight = Screen.height;

            if (old_w != curScreenWidth || old_h != curScreenHeight)
            {
                old_w = curScreenWidth;
                old_h = curScreenHeight;
                return;
            }

            if (curScreenWidth <= w_min || curScreenHeight <= h_min)
            {
                curScreenWidth = (int)w_min;
                curScreenHeight = (int)h_min;
            }

            float curScale = (float)curScreenWidth / curScreenHeight;

            if (curScale > aspect19_9 + 0.01f || curScale < aspect19_9 - 0.01f)
            {
                curScreenHeight = (int)(curScreenWidth / aspect19_9);
            }

            Screen.SetResolution(curScreenWidth, curScreenHeight, false);
        }

        /// <summary>
        /// 启动检查游戏运行进程
        /// </summary>
        private void StartCheckProcess()
        {
            CheckProcess();
            RemoveCheckTimer();
            //检查游戏运行环境进程情况
            _timer = TimerExt.Register(_intervalCheckProcess, true, () =>
            {
                //10秒钟检查一次
                CheckProcess();
            });
        }

        /// <summary>
        /// 检查游戏运行环境的进程
        /// </summary>
        private void CheckProcess()
        {
            if (!AppValues.IsStartPcCheckProcess)
            {
                return;
            }

            if (PcIllicitProcessList == null || PcIllicitProcessList.Count == 0)
            {
                string pcIllicitProcessListStr = DbHelper.GetConstString(ConstClientIds.PcIllicitProcessList);
                Log.Info(string.Format("CheckProcess PcIllicitProcessList {0}", pcIllicitProcessListStr));
                PcIllicitProcessList = pcIllicitProcessListStr.Split(Constants.Comma).ToList();
            }

            //检测加速器
            Process[] sysProcess = Process.GetProcesses();
            if (sysProcess != null)
            {
                Process fristProcess = null;
                foreach (Process pro in sysProcess)
                {
                    //UnityEngine.Debug.Log("----------------------------------------------");
                    if (pro != null)
                    {
                        try
                        {
                            string processName = pro.ProcessName;
                            int processId = pro.Id;
                            if (!string.IsNullOrEmpty(processName))
                            {
                                //UnityEngine.Debug.Log("GetProcesses ProcessNameId : " + processId);
                                //UnityEngine.Debug.Log("GetProcesses ProcessName : " + processName);
                                if (PcIllicitProcessList.IndexOf(processName) != -1)
                                {
                                    fristProcess = pro;
                                    break;
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            //进程已过期失效
                            UnityEngine.Debug.Log(e.ToString());
                            continue;
                        }
                    }
                    //UnityEngine.Debug.Log("----------------------++++++------------------------");
                }
                if (fristProcess != null)
                {
                    //提示关闭加速器继续游戏,或者直接杀死进程
                    if (!NewGameUiManager.IsActive(UiElementIds.PcCheckProcessTipUi))
                    {
                        NewGameUiManager.Show(UiElementIds.PcCheckProcessTipUi, fristProcess);
                    }
                    //TODO
                    if (IsKillIllicitProcess)
                    {
                        fristProcess.Kill();
                    }
                }
            }
        }

        /// <summary>
        /// 停止检查进程timer
        /// </summary>
        private void RemoveCheckTimer()
        {
            if (_timer != null)
            {
                _timer.Cancel();
                _timer = null;
            }
        }

        /// <summary>
        /// 提示玩家窗口变化
        /// </summary>
        private void TipWindowChange()
        {
            if (AppValues.IsPcWindowChangeTipUi)
            {
                return;
            }

            if (!AppValues.IsStartPcCheckProcess)
            {
                return;
            }

            if (NewGameUiManager.IsActive(UiElementIds.PcWindowChangeTipUi))
            {
                return;
            }

            AppValues.IsPcWindowChangeTipUi = true;
            NewGameUiManager.Show(UiElementIds.PcWindowChangeTipUi);
        }

        /// <summary>
        /// 退出引用window提示
        /// </summary>
//        public void OnApplicationQuit()
//        {
//            if (isApplicationQuit)
//            {
//                return;
//            }

////#if !UNITY_EDITOR
////            Application.CancelQuit();
////            string tip = LocalizationService.Instance.GetFromFile(LocalizationFiles.LoginUi, LocalizationKey.PcWindowQuitTip);
////            string titleName = LocalizationService.Instance.GetFromFile(LocalizationFiles.LoginUi, LocalizationKey.PcWindowTitle);
////            WindowsPcUtil.MessageReturnType returnType = WindowsPcUtil.MessageBoxShow(titleName, tip, WindowsPcUtil.MessageBoxTyoe.ConfirmAndCancel);
////            if (returnType == WindowsPcUtil.MessageReturnType.OK)
////            {
////                //点击确定按钮
////                Application.Quit();
////            }
////#endif
//        }
#endif
    }



-------------------------------------------------------------------我是分割线----------------------------------------------------------------------
 public class WindowsPcUtil
    {

#if UNITY_STANDALONE_WIN
        [DllImport("User32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
        public static extern int MessageBox(IntPtr handle, string message, string title, int type);

        [DllImport("user32.dll")]
        public static extern IntPtr GetActiveWindow();

        //获取当前激活窗口
        [DllImport("user32.dll", EntryPoint = "GetForegroundWindow")]
        public static extern System.IntPtr GetForegroundWindow();

        //设置窗口边框
        [DllImport("user32.dll")]
        public static extern IntPtr SetWindowLong(IntPtr hwnd, int _nIndex, int dwNewLong);

        //更改标题栏
        [DllImport("user32.dll", ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
        public static extern int SetWindowText(IntPtr hWnd, string text);

        //使用查找任务栏
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string strClassName, int nptWindowName);

        //获取窗口位置以及大小
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);

        //设置当前窗口的显示状态
        [DllImport("user32.dll")]
        public static extern bool ShowWindow(System.IntPtr hwnd, int nCmdShow);

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left; //最左坐标
            public int Top; //最上坐标
            public int Right; //最右坐标
            public int Bottom; //最下坐标
        }

        //最大最小化
        private const int SW_SHOWMINIMIZED = 2;//最小化窗口
        private const int SW_SHOWMAXIMIZED = 3;//最大化窗口

        /// <summary>
        /// 系统消息框的类型
        /// </summary>
        public enum MessageBoxTyoe
        {
            Confirm = 0,
            ConfirmAndCancel = 1,
        }

        /// <summary>
        /// 系统消息框返回类型
        /// </summary>
        public enum MessageReturnType
        {
            OK = 1,
            NO = 2,
        }

        /// <summary>
        /// 弹出window 提示框
        /// </summary>
        /// <param name="title"></param>
        /// <param name="tip"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static MessageReturnType MessageBoxShow(string title, string tip, MessageBoxTyoe type)
        {
            IntPtr myintptr = GetActiveWindow();
            MessageReturnType returnType = (MessageReturnType)MessageBox(myintptr, tip, title, (int)type);
            return returnType;
        }

        /// <summary>
        /// 最小化窗口
        /// </summary>
        public static void SetMinWindows()
        {
            ShowWindow(GetForegroundWindow(), SW_SHOWMINIMIZED);
        }

        /// <summary>
        /// 最大化窗口
        /// </summary>
        public static void SetMaxWindows()
        {
            ShowWindow(GetForegroundWindow(), SW_SHOWMAXIMIZED);
        }

        /// <summary>
        /// 改变标题栏标题
        /// </summary>
        public static void ChangeTitleText(string titleName)
        {
            SetWindowText(GetActiveWindow(), titleName);
        }

        /// <summary>
        /// 系统级别提示退出游戏
        /// </summary>
        public static void ApplicationQuit()
        {
            string tip = LocalizationService.Instance.GetFromFile(LocalizationFiles.LoginUi, LocalizationKey.PcWindowQuitTip);
            string titleName = LocalizationService.Instance.GetFromFile(LocalizationFiles.LoginUi, LocalizationKey.PcWindowTitle);
            MessageReturnType returnType = MessageBoxShow(titleName, tip, MessageBoxTyoe.ConfirmAndCancel);
            if (returnType == MessageReturnType.OK)
            {
                //点击确定按钮
                Application.Quit();
            }
        }
#endif
    }


发表评论:

朱文华 joyimp|@2011-2020 京ICP备16030765号