反射UnityEditor.GameView设置GamePlayMode分辨率

现在很有游戏考虑横屏适配、竖屏适配、阿拉伯语适配(横竖屏)导致拼界面变得越来越繁琐。

有很多时候需要记录各个控件的状态。

为了减少操作,特意制作了这个工具,点击用x配置可以自动切换到 宽高分辨率,如果当前没有则会自动添加到编辑器中。这里特别感谢开源社区https://github.com/akof1314/Unity-EditorInternalsVisibleDemo/blob/main/EditorInternalsVisibleDemo/PackagesCustom/com.wuhuan.internalsvisibledemo/Editor/PickViewSize/PickGameViewSizeWindow.csusing System;

using System.Reflection;
using UnityEditor;
using UnityEngine;

public class GameViewTools
{
    public enum GameViewSizeType
    {
        AspectRatio,
        FixedResolution
    }
    public static int devWidth = 1624;
    public static int devHeight = 750;
    private static object gameViewSizesInstance; // GameViewSizes的引用
    private static bool isInited = false;
    public static int  landScapeIndex = 1;
    public static int portraitIndex = 1;
    private static MethodInfo getGroup; 
    public static object curGroup;
    public static MethodInfo curGroupFunc;
    public static MethodInfo getGameViewSizeFunc; // 获取索引x的分辨率
    private static MethodInfo addCustomSize; //添加方法
    private static MethodInfo removeCustomSize; //添加方法
    private static MethodInfo getCustomCount; //引用获取当前自定义数量
    private static MethodInfo getTotakCount; //获取所以的数量
    private static MethodInfo getBuiltinCount; //获取基础数量

    public static bool IsHorizonal()
    {
        var vec = GameViewSize();
        return vec.x > vec.y;
    }
    public  static Vector2 GameViewSize()
    {
        var mouseOverWindow = UnityEditor.EditorWindow.mouseOverWindow;
        System.Reflection.Assembly assembly = typeof(UnityEditor.EditorWindow).Assembly;
        System.Type type = assembly.GetType("UnityEditor.PlayModeView");

        Vector2 size = (Vector2)type.GetMethod(
            "GetMainPlayModeViewTargetSize",
            System.Reflection.BindingFlags.NonPublic |
            System.Reflection.BindingFlags.Static
        ).Invoke(mouseOverWindow, null);

        return size;
    }

public static void ChangeResolution(int index)
{
    var type = typeof(Editor).Assembly.GetType("UnityEditor.GameView");
    var window = EditorWindow.GetWindow(type);

      

    var SizeSelectionCallback = type.GetMethod("SizeSelectionCallback",
        System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
    SizeSelectionCallback.Invoke(window, new object[] { index, null });
}

public static void InitiaLized()
{
    if (isInited) return;
    isInited = true;
    var gvSize = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizes");
    var singleType = typeof(ScriptableSingleton<>).MakeGenericType(gvSize);
    var instacnceProp = singleType.GetProperty("instance");
    getGroup = gvSize.GetMethod("GetGroup");
    curGroupFunc = gvSize.GetMethod("get_currentGroup");
    curGroup = curGroupFunc.Invoke(instacnceProp.GetValue(null, null), null);       
    gameViewSizesInstance = instacnceProp.GetValue(null, null); //获取单例
    getGameViewSizeFunc = curGroup.GetType().GetMethod("GetGameViewSize");
    getCustomCount = getGroup.ReturnType.GetMethod("GetCustomCount");
    getTotakCount = getGroup.ReturnType.GetMethod("GetTotalCount");
    getBuiltinCount = getGroup.ReturnType.GetMethod("GetBuiltinCount");
    addCustomSize = getGroup.ReturnType.GetMethod("AddCustomSize");
    removeCustomSize = getGroup.ReturnType.GetMethod("RemoveCustomSize");
    CheckCustomSizeEveryOnce();
}
public static void CheckCustomSizeEveryOnce()
{
    var buildInCount = (int)getBuiltinCount.Invoke(curGroup, null);//内建分辨率数量
    int count = (int)getCustomCount.Invoke(curGroup, null);  //自定义分辨率数量
    int totalCount = (int)getTotakCount.Invoke(curGroup, null); //累计分辨率数量 
    landScapeIndex = 0;
    portraitIndex = 0;
    for (int i = buildInCount; (landScapeIndex == 0 || portraitIndex == 0) && i < totalCount; i++)
    {
        var viewSize = getGameViewSizeFunc.Invoke(curGroup, new object[] { i });
        var w = (int)viewSize.GetType().GetProperty("width").GetValue(viewSize, null);
        var h = (int)viewSize.GetType().GetProperty("height").GetValue(viewSize, null);
        if (w == devWidth && h == devHeight)
        {
            landScapeIndex = i;
        }
        else if (w == devHeight && h == devWidth)
        {
            portraitIndex = i;
        }
    }
    if (landScapeIndex == 0 || portraitIndex == 0)
    {
        AddCustomSize(GameViewSizeType.FixedResolution, GameViewSizeGroupType.Android, devWidth, devHeight, "(code added)");
        AddCustomSize(GameViewSizeType.FixedResolution, GameViewSizeGroupType.Android, devHeight, devWidth, "(code added)");
    }
}
    public static void AddCustomSize(GameViewSizeType viewSizeType, GameViewSizeGroupType gameViewSizeGroupType,
        int width, int height, string text)
    {
           
        //获取类GameViewSize
        var gvsType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSize");

        //找到 构造方法 public GameViewSize(GameViewSizeType type, int width, int height, string baseText)
        var ctor = gvsType.GetConstructor(new Type[]
        {
            typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizeType"),
            typeof(int),
            typeof(int),
            typeof(string)
        });

        //找到enum 类型 GameViewSizeType
        var newGvsType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizeType");

        int enumGvsType = 0;

        // //获取enum中的类型
        if (viewSizeType == GameViewSizeType.AspectRatio)
        {
            var aspectRatio = newGvsType.GetField("AspectRatio", BindingFlags.Static | BindingFlags.Public);
            //newGvsType =aspectRatio.GetType() ; //typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizeType.AspectRatio");
            enumGvsType = (int)aspectRatio.GetValue(null);
        }
        else
        {
            var fixedResolution = newGvsType.GetField("FixedResolution", BindingFlags.Static | BindingFlags.Public);
            // newGvsType = fixedResolution.GetType(); //typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizeType.FixedResolution");
            enumGvsType = (int)fixedResolution.GetValue(null);
        }

        var newSize = ctor.Invoke(new object[] { enumGvsType, width, height, text });


        // //执行 添加到 group 中 GameViewSizeType m_SizeType;
        var sizetype = gvsType.GetField("m_SizeType", BindingFlags.NonPublic | BindingFlags.Instance);

        //获取 GameViewSizeGroup
        var gameViewSizes = getGroup.Invoke(gameViewSizesInstance, new object[] { (int)gameViewSizeGroupType });

        addCustomSize.Invoke(gameViewSizes, new object[] { newSize });
    }
}
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/298199.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

简易视频播放器(案例)

介绍 本篇Codelab使用ArkTS语言实现视频播放器&#xff0c;主要包括主界面和视频播放界面&#xff0c;我们将一起完成以下功能&#xff1a; 主界面顶部使用Swiper组件实现视频海报轮播。主界面下方使用List组件实现视频列表。播放界面使用Video组件实现视频播放。在不使用视频组…

程序员必知!命令模式的实战应用与案例分析

命令模式是一种行为设计模式&#xff0c;它将请求封装为对象以实现客户端参数化、请求排队、日志记录及撤销操作&#xff0c;旨在解耦调用者与操作实现者&#xff0c;以智能家居为例&#xff0c;用户通过界面发送命令对象&#xff0c;设备作为接收者执行相应操作&#xff0c;无…

物理与网络安全

物流环境安全 场地选择考虑抗震、承重、防火、防水、供电、空气调节、电磁防护、雷击及静电 场地因素&#xff1a; 自然灾害&#xff0c;社会因素&#xff08;加油站、化工厂&#xff09;&#xff0c;配套条件&#xff08;消防&#xff0c;交通&#xff0c;电力&#xff0c;…

QT项目中添加资源文件和使用qss样式

时间记录&#xff1a;2024/1/6 一、添加使用资源文件 1.1 创建项目并打开项目&#xff08;带ui界面的项目&#xff09; 1.2 使用快捷键Ctrln创建文件&#xff0c;选择"QT"下面的"QT Resource File" 1.3 输入文件名和文件保存路径 1.4 将需要添加的文件…

钡铼网关 只需一台,解锁智慧无人搅拌站系统,绿色又环保

行业需求 为了提高搅拌站的自动化&#xff0c;减少人工繁琐的操作&#xff0c;同时记录物料的增减记录&#xff0c;实现对于物料从进场到出场的全周期管理。 系统介绍 针对搅拌站各个环节的需求大致相同&#xff0c;市场中逐渐流行一整套基本的智慧搅拌站解决方案。各种搅拌站…

水母目标检测数据集VOC格式500张

水母&#xff0c;一种美丽而神秘的海洋生物&#xff0c;以其独特的形态和生态习性而备受瞩目。 水母的体型呈伞状&#xff0c;身体透明&#xff0c;有各种颜色和花纹。它们没有骨骼&#xff0c;身体由胶状物质组成&#xff0c;非常柔软和脆弱。水母通过触手上的刺细胞释放毒素…

哪个洗地机质量好?2024年洗地机推荐

如今&#xff0c;家用洗地机已经成为越来越多家庭的不可或缺之物。然而&#xff0c;在市场上琳琅满目的洗地机品牌和型号中&#xff0c;究竟哪一个性价比高、质量好&#xff0c;很多消费者常常陷入选择困难。为了帮助大家能够更加轻松地购买到适合自己的洗地机&#xff0c;我们…

dotdotdot插件快速实现多行文本的省略

jQuery.dotdotdot 前言 在“css新增文本样式&#xff08;完整&#xff09;”这篇&#xff0c;我们介绍了text-overflow属性省略多余的文本。用text-overflow属性可以直接省略单行文本&#xff0c;但省略多行文本&#xff0c;单独使用CSS是无法实现&#xff0c;今天我们介绍一…

【Linux 内核源码分析】关于Linux内核源码目录结构

Linux内核源码采用树形结构。功能相关的文件放到不同的子目录下面&#xff0c;使程序更具有可读行。 使用Source Insight打开源码&#xff0c;如下图所示&#xff0c;可以看到源码是树形结构。 目录含义描述arch存放与体系结构相关的代码&#xff0c;包括不同硬件平台的特定代…

深度解析分布式算法:构建高效稳定的分布式系统

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

高校选课系统需求分析开发源码

高校学生选课报名系统包括学生、教师和管理员三方的功能需求&#xff0c;学生的需求是查询院系的课程、选课情况及个人信息修改&#xff1b;教师则需要查看和查询所有课程信息及自己的课程信息以及教师信息的修改&#xff1b;管理员则负责更为复杂的任务&#xff0c;包括对学生…

2023年阿里云云栖大会:前沿技术发布与未来展望

在2023年的阿里云云栖大会上&#xff0c;我见证了云计算和人工智能领域的又一历史性时刻。这次大会不仅是对未来科技趋势的一次深入探索&#xff0c;更是阿里云技术实力和创新能力的集中展示。 首先&#xff0c;千亿级参数规模的大模型通义千问2.0的发布&#xff0c;无疑将人工…

【大厂秘籍】系列 - Java多线程面试题

Java多线程面试题 友情提示&#xff0c;看完此文&#xff0c;在Java多线程这块&#xff0c;基本上可以吊打面试官了 线程和进程的区别 进程是资源分配的最小单位&#xff0c;线程是CPU调度的最小单位 线程是进程的子集&#xff0c;一个进程可以有很多线程&#xff0c;每条线…

【MongoDB】MongoDB查询语句find的使用,和提高查询速度的游标的使用,非常详细!!!

&#x1f601; 作者简介&#xff1a;一名大四的学生&#xff0c;致力学习前端开发技术 ⭐️个人主页&#xff1a;夜宵饽饽的主页 ❔ 系列专栏&#xff1a;MongoDB数据库 &#x1f450;学习格言&#xff1a;成功不是终点&#xff0c;失败也并非末日&#xff0c;最重要的是继续前…

MySQL基础篇(三)约束

一、概述 概念&#xff1a;约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。 目的&#xff1a;保证数据库中数据的正确、有效性和完整性。 分类&#xff1a; 注意&#xff1a;约束是作用于表中字段上的&#xff0c;可以在创建表/修改表的时候添加约束。 二…

Java BIO、NIO、AIO、Netty知识详解(值得珍藏)

1. 什么是IO Java中I/O是以流为基础进行数据的输入输出的&#xff0c;所有数据被串行化(所谓串行化就是数据要按顺序进行输入输出)写入输出流。简单来说就是java通过io流方式和外部设备进行交互。 在Java类库中&#xff0c;IO部分的内容是很庞大的&#xff0c;因为它涉及的领…

【每日一题】在链表中插入最大公约数

文章目录 Tag题目来源解题思路方法一&#xff1a;迭代 写在最后 Tag 【迭代】【辗转相除法】【链表】【2024-01-06】 题目来源 2807. 在链表中插入最大公约数 解题思路 方法一&#xff1a;迭代 思路 首先需要求两个数的最大公约数&#xff0c;使用辗转相除法。实现代码如下…

PyQT 多进程

在PyQt中&#xff0c;图形化界面&#xff08;GUI&#xff09;是运行在主线程中的&#xff0c;而多进程是在独立的进程中执行的。默认情况下&#xff0c;多进程之间是无法直接共享图形化界面的。 然而&#xff0c;有几种方法可以在多进程中与PyQt的图形化界面进行通信&#xff…

【大数据】Zookeeper 客户端的命令行操作

Zookeeper 客户端的命令行操作 1.显示某个路径下的所有节点&#xff1a;ls2.显示某个路径下的所有节点&#xff0c;以及当前节点的详细信息&#xff1a;ls23.创建节点&#xff1a;create4.创建临时节点&#xff1a;create -e5.创建顺序&#xff08;带编号&#xff09;节点&…

程序员副业之无人直播助眠

介绍和概览 大家好&#xff0c;我是小黑&#xff0c;本文给大家介绍一个比较轻松简单的副业&#xff0c;无人直播助眠副业。 这个项目的核心就是通过直播一些助眠素材来赚钱。比如你可以放一些舒缓的雨声之类的&#xff0c;吸引观众进来。然后&#xff0c;咱们可以挂个小程序…