一键多截图

原理:

  1. 使用代码控制GameView窗口,自动增加窗口,切换窗口,进行截图;

 

          使用方 将GameViewTools.cs 以及Jietu.cs放入 Edit 目录下

 

  1. 创建一个空物体,并把Jietu.cs脚本挂上

 

  1. 在ScreenSizeAndBind Events 添加你需要的屏幕尺寸,设置SelectDo 事件,可以让执行变换视图的后 进行截图前,对场景进行一些指定的触发事件;

 

  1. 运行程序,按下鼠标中键即可截图;

  5.源码

/****************************************************
    文件:jietu.cs
   功能:场景运行时截图
*****************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Experimental.PlayerLoop;

namespace zjf_tools
{
    public class Jietu : MonoBehaviour
    {

        public  ScreenSizeAndBindEvent[] screenSizeAndBindEvents = new ScreenSizeAndBindEvent[4]
        {
            new ScreenSizeAndBindEvent("-iPad",GameViewTools.GameViewSizeType.FixedResolution,GameViewSizeGroupType.Android,2048,2732), 
            new ScreenSizeAndBindEvent("-iPhoneXs Max",GameViewTools.GameViewSizeType.FixedResolution,GameViewSizeGroupType.Android,1242,2688),
            new ScreenSizeAndBindEvent("-iPhone 8Plus",GameViewTools.GameViewSizeType.FixedResolution,GameViewSizeGroupType.Android,1242,2208),
            new ScreenSizeAndBindEvent("-Andriod",GameViewTools.GameViewSizeType.FixedResolution,GameViewSizeGroupType.Android,1080,1920),
        };
        
        
        public int count; 
        private int curIndex;
        private void OnEnable()
        {
            
            GameViewTools.Init();//初始化
            foreach (var screenInfo in screenSizeAndBindEvents)
            {
                GameViewTools.AddCustomSize(screenInfo.gameViewSizeType,screenInfo.gameViewSizeGroupType,screenInfo.width,screenInfo.height,screenInfo.name);
            }
            count = screenSizeAndBindEvents.Length;
            isShooting = false;
        }

        public void ShowTxt(string txt)
        {
            Debug.Log("t---->"+txt);
        }
        

        private void OnDisable()
        {
            GameViewTools.Remove();//移除
        }


        private void UpdateSelectView()
        {
            if (!isShooting)
            {
                isShooting = true;
                StartCoroutine(ShootView(count, () => { isShooting = false; }));
            }
        }

        private bool isShooting = false;
        
        IEnumerator ShootView(int count, System.Action callback)
        {
           // var  wait = new Wa;
            var wait2 = new WaitForEndOfFrame();
            int num = count;
            while (num >0)
            {
                GameViewTools.Next();//更换窗口
                screenSizeAndBindEvents[num-1].selectDo?.Invoke();
                yield return wait2;
                yield return wait2;
                Shoot();
                num--;
            }
            callback?.Invoke();
        }
        
        //修改协程添加方案
        

        //截图
        private void Shoot()
        {
            string directoryName = Screen.width + "x" + Screen.height;
            string path = Application.dataPath.Replace("/Assets", "/" + Application.productName + "_Screenshot/" + directoryName);
            int fileCount;
            if (!System.IO.File.Exists(path))
                fileCount = System.IO.Directory.CreateDirectory(path).GetFiles().Length;
            else
                fileCount = new System.IO.DirectoryInfo(path).GetFiles().Length;
            string imageName = directoryName + "_" + System.Guid.NewGuid() + ".png";
            ScreenCapture.CaptureScreenshot(path + "/" + imageName);
            Debug.Log("***Screenshot" + imageName + "***");
        }
        
        void Update()
        {
            if (Input.GetMouseButtonDown(2))
            {
                UpdateSelectView();
            }
            
            if(Input.GetKeyDown(KeyCode.F))
                Shoot();
            

            if (Input.GetKeyDown(KeyCode.Space))
            {
                Time.timeScale = 0;
            }

            if (Input.GetKeyDown(KeyCode.A))
            {
                Time.timeScale = 1;
            }
        }
    }
    
    [Serializable]
    public class ScreenSizeAndBindEvent
    {
        public string name;
        public GameViewTools.GameViewSizeType gameViewSizeType;
        public GameViewSizeGroupType gameViewSizeGroupType;
        public int height;
        public int width;
        public UnityEvent selectDo;

        public ScreenSizeAndBindEvent(string name, GameViewTools.GameViewSizeType gameViewSizeType,
            GameViewSizeGroupType gameViewSizeGroupType, int width, int height)
        {
            this.name = name
            this.gameViewSizeType = gameViewSizeType;
            this.gameViewSizeGroupType = gameViewSizeGroupType;
            this.height = height;
            this.width = width;
        }

        public void BindEvent(UnityAction action)
        {
            selectDo.AddListener(action);
        }

        public void UnBindEvent(UnityAction action)
        {
            selectDo.RemoveListener(action);
        }


    }
}

 切换视图

using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;
/**
 * @colorzore
 * 控制窗口GameView的切换、添加、删除;
 */
namespace zjf_tools
{
    public class GameViewTools
    {
        private static object gameViewSizesInstance; // GameViewSizes的引用

        private static MethodInfo
            getGroup; // 方法引用 public GameViewSizeGroup GetGroup(GameViewSizeGroupType gameViewSizeGroupType)

        private static MethodInfo addCustomSize; //添加方法
        private static MethodInfo removeCustomSize; //添加方法
        private static MethodInfo getCustomCount; //引用获取当前自定义数量
        private static MethodInfo getTotakCount; //获取所以的数量
        private static MethodInfo getBuiltinCount; //获取基础数量


        //将数据添加到自定义的位置
        private static int screenIndex = 0;
        private static int minIndex;//
        private static int maxIndex;
        private static bool isChange = false;

        static void InitiaLized()
        {
            var gvSize = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizes");
            var singleType = typeof(ScriptableSingleton<>).MakeGenericType(gvSize);
            var instacnceProp = singleType.GetProperty("instance");
            getGroup = gvSize.GetMethod("GetGroup");

            gameViewSizesInstance = instacnceProp.GetValue(null, null); //获取单例

            /* -GameViewSizes- 方法*/
            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");
        }
        
        

        public enum GameViewSizeType
        {
            AspectRatio,
            FixedResolution
        }

        [MenuItem("Tools2/GameViewSize/Init")]
        public static void Init()
        {
            if (isChange)
            {
                Remove();
                isChange = false;
            }
            
            InitiaLized();
            var gameViewSizes = getGroup.Invoke(gameViewSizesInstance, new object[] {(int)GameViewSizeGroupType.Android});
            var totakCount  = getTotakCount.Invoke(gameViewSizes, null);
            screenIndex = maxIndex = minIndex = (int) totakCount;
        }
        

        [MenuItem("Tools2/GameViewSize/AddAll")]
        public static void Add()
        {
            //将添加的数据
            AddCustomSize(GameViewSizeType.FixedResolution,GameViewSizeGroupType.Android,2048,2732,"-iPad");
            AddCustomSize(GameViewSizeType.FixedResolution,GameViewSizeGroupType.Android,1242,2688,"-iPhoneXs Max");
            AddCustomSize(GameViewSizeType.FixedResolution,GameViewSizeGroupType.Android,1242,2208,"-iPhone 8Plus");
            AddCustomSize(GameViewSizeType.FixedResolution,GameViewSizeGroupType.Android,1080,1920,"-Androdi");
            //四个尺寸
            isChange = true;
        }

        [MenuItem("Tools2/GameViewSize/RemoveAll ")]
        public static void Remove()
        {
            while (maxIndex - minIndex > 0)
            {
                if (screenIndex == maxIndex)
                {
                    screenIndex = maxIndex - 1;
                    SelcetGameView(screenIndex);//
                }
                RemoveCustomSize(GameViewSizeGroupType.Android, maxIndex);
            }
            isChange = false;
        }

        [MenuItem("Tools2/GameViewSize/NextLoop  %&N")]
        public static void Next()
        {
            screenIndex++;
            if (screenIndex > maxIndex)
            {
                screenIndex = minIndex;
            }
            SelcetGameView(screenIndex);
        }

        private static int index = 0;




    //1.增加窗口
        public static void AddCustomSize(GameViewSizeType viewSizeType, GameViewSizeGroupType gameViewSizeGroupType,
            int width, int height, string text)
        {
            InitiaLized();
            //获取类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});

            //获取
            var totakCount = getTotakCount.Invoke(gameViewSizes, null);//没有参数

            maxIndex = (int)totakCount-1;
        }
        


        //2.删除增加的窗口
        public static void RemoveCustomSize(GameViewSizeGroupType gameViewSizeType, int index = -1)
        {
            InitiaLized();
            //bool isLastIndex = index < 0 ? true : false;
            
            //获取 GameViewSizes ->  GetGroup(GameViewSizeGroupType gameViewSizeGroupType)
            //-> GameViewSizeGroup ->
            //        -> GetTotalCount() -> int 所有的数量
            //        -> GetCustomCount() ->int  用户自定的数量
            var gameViewSizes = getGroup.Invoke(gameViewSizesInstance, new object[] {gameViewSizeType});

            var totakCount = getTotakCount.Invoke(gameViewSizes, null);//没有参数

            var customCount = getCustomCount.Invoke(gameViewSizes, null); //无参
            //var builinCount = getBuiltinCount.Invoke(gameViewSizes, null); //无参
            
            // int removeIndex = isLastIndex ? (int) totakCount : index + (int)builinCount;
            //int removeIndex = isLastIndex ? (int) totakCount : index;
            //移除
            removeCustomSize.Invoke(gameViewSizes, new object[] {(int)totakCount-1});
            maxIndex = (int)totakCount -1;

        }

        //3.设置指定的窗口
        public static void SelcetGameView(int index)
        {
            var gvType = typeof(Editor).Assembly.GetType("UnityEditor.GameView");
            var gvWnd = EditorWindow.GetWindow(gvType); //获取窗口

            var sizeSelcetionCallBack = gvType.GetMethod("SizeSelectionCallback",BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            sizeSelcetionCallBack?.Invoke(gvWnd, new object[] {index, null});
        }
    }
}

 

 

posted on 2021-09-01 09:18  冷榷  阅读(419)  评论(0编辑  收藏  举报