UnityEditor内部GameView信息获取

in 编程
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

编者注

由于需要多屏幕的需求,这里在UnityEditor端实现相对简单,则需要获取并控制UnityEditor的Game窗口以及相关信息内容

信息搜索

通过Google查询到如下连接:
Game window size from editor window in editor mode
获得核心代码如下:

public static Vector2 GetMainGameViewSize()
{
    System.Type T = System.Type.GetType("UnityEditor.GameView,UnityEditor");
    System.Reflection.MethodInfo GetSizeOfMainGameView = T.GetMethod("GetSizeOfMainGameView",System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
    System.Object Res = GetSizeOfMainGameView.Invoke(null,null);
    return (Vector2)Res;
}

实施思路

编写全局单例

public class GameViewManager : SingletonTemplate<GameViewManager>, ILifecycle
    {
        private Type GameViewType;
        
        public GameViewManager()
        {
            Awake();
        }
    }

获取GameView的Type

public void Awake()
        {
            this.GameViewType = Type.GetType("UnityEditor.GameView,UnityEditor");
        }

GameView源代码分析

通过ILSpy找到如下路径找到UnityEditor.dll

C:\Program Files\Unity\Hub\Editor\2018.1.9f2\Editor\Data\Managed\UnityEditor.dll

通过查看发现静态获取MainGameView的方法的实现

internal static GameView GetMainGameView()
{
    if ((UnityEngine.Object)s_LastFocusedGameView == (UnityEngine.Object)null && s_GameViews != null && s_GameViews.Count > 0)
    {
        s_LastFocusedGameView = s_GameViews[0];
    }
    return s_LastFocusedGameView;
}

分析在GameView当中存在如下内容

private static List<GameView> s_GameViews = new List<GameView>();

通过反射获取s_GameViews

this.s_GameViews = ReflectionUtils.PrivateStaticField(GameViewHook.GameViewType, "s_GameViews") as IList;

反射工具类的一部分

public static object PrivateStaticField(Type type, string field_name)
        {
            BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Static;
            FieldInfo fieldInfo = type.GetField(field_name, bindingAttr);
            
            if(fieldInfo == null) throw new DeveloperException();

            return fieldInfo.GetValue(null);
        }

反射获取GameView操作权

通过反射获取GameView的title、targetDisplay、targetSize的操作权限

using System;
using System.Reflection;
using UnityEngine;
using Utils.StandardUtils.ExceptionUtils;

namespace Business.ScreenDisplay.Editor.GameView.Entity
{
    public static class GameViewHook
    {
        public static Type GameViewType;
        
        private static PropertyInfo titleProperty;
        private static FieldInfo targetDisplayField;
        private static PropertyInfo targetSizeProperty;

        // 略
    }
}

可操作的查询

我们需要维护一个可以操作的Display列表

public void Awake()
        {
            GameViewHook.GameViewType = Type.GetType("UnityEditor.GameView,UnityEditor");
            // private static List<GameView> s_GameViews
            this.s_GameViews = ReflectionUtils.PrivateStaticField(GameViewHook.GameViewType, "s_GameViews") as IList;

            EditorApplication.update += LateUpdate;
            
            this.timer = new Timer(state => { Update(); });
        }

当关闭时,自动清理

private void LateUpdate()
        {
            if (EditorApplication.isPlaying == false)
            {
                for (int i = displays.Count - 1; i >= 0; i--)
                {
                    if (!displays[i].getActive())
                        displays.Remove(displays[i]);
                }
            }
        }
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9
扫一扫关注公众号添加购物返利助手,领红包
Comments are closed.

推荐使用阿里云服务器

超多优惠券

服务器最低一折,一年不到100!

朕已阅去看看