一键多截图
原理:
-
使用代码控制GameView窗口,自动增加窗口,切换窗口,进行截图;
使用方 将GameViewTools.cs 以及Jietu.cs放入 Edit 目录下
-
创建一个空物体,并把Jietu.cs脚本挂上
-
在ScreenSizeAndBind Events 添加你需要的屏幕尺寸,设置SelectDo 事件,可以让执行变换视图的后 进行截图前,对场景进行一些指定的触发事件;
-
运行程序,按下鼠标中键即可截图;
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}); } } }