using System; using System.Collections.Generic; using System.IO; using System.Reflection; using UnityEditor; using UnityEngine; using UnityEngine.Profiling; using UnityEngine.Rendering; namespace Ironspore.Editor { public static class LightingSmoke { static int step, initialChassis; static double nextAt; static Result result; const string Output = "Docs/QA/Lighting/TestResults/WorldCycles.json"; public static string Begin() { if (!EditorApplication.isPlaying || !GameSession.Active || result != null) throw new InvalidOperationException("A playing, idle GameSession is required."); initialChassis = GameSession.Active.SelectedChassis; if (GameSession.Active.InField) GameSession.Active.EndSortie(true); result = new Result(); step = 0; nextAt = EditorApplication.timeSinceStartup + 1; EditorApplication.update += Tick; return "Three chassis and three field/hangar cycles scheduled; report in about 14 seconds."; } static void Tick() { if (EditorApplication.timeSinceStartup < nextAt) return; nextAt = EditorApplication.timeSinceStartup + 1; try { var game = GameSession.Active; if (step >= 12) { result.passed = result.rows.TrueForAll(row => row.passed); Finish(); return; } int phase = step % 4; if (phase == 0) { game.SelectedChassis = step / 4; game.StartTrial(); } if (phase == 1) { Snapshot("field", false); typeof(MechPilot).GetProperty("FirstPerson").SetValue(game.Pilot, true); } if (phase == 2) { Snapshot("first-person", true); game.EndSortie(true); } if (phase == 3) Snapshot("hangar", false); step++; } catch (Exception error) { result.error = error.ToString(); Finish(); } } static void Snapshot(string phase, bool requireShadowOnly) { var world = GameObject.Find("World"); int roots = 0, suns = 0, spots = 0, shadowOnly = 0; foreach (var candidate in UnityEngine.Object.FindObjectsByType()) if (candidate.gameObject.activeInHierarchy) roots++; foreach (var light in world.GetComponentsInChildren()) { if (light.type == LightType.Directional) suns++; if (light.type == LightType.Spot && light.enabled) spots++; } foreach (var renderer in world.GetComponentsInChildren()) if (renderer.enabled && renderer.shadowCastingMode == ShadowCastingMode.ShadowsOnly) shadowOnly++; int probes = world.GetComponentsInChildren().Length; int cameras = world.GetComponentsInChildren().Length; result.rows.Add(new Row { phase = phase, chassis = GameSession.Active.SelectedChassis, worlds = roots, suns = suns, enabledSpots = spots, probes = probes, cameras = cameras, shadowOnlyRenderers = shadowOnly, allocatedMiB = Profiler.GetTotalAllocatedMemoryLong() / 1048576.0, reflectionReady = world.GetComponent().ReflectionReady, passed = roots == 1 && suns == 1 && probes == 1 && cameras == 1 && spots <= 1 && (!requireShadowOnly || shadowOnly > 0) }); } static void Finish() { EditorApplication.update -= Tick; if (GameSession.Active) GameSession.Active.SelectedChassis = initialChassis; Directory.CreateDirectory(Path.GetDirectoryName(Output)); File.WriteAllText(Output, JsonUtility.ToJson(result, true)); result = null; } [Serializable] sealed class Result { public bool passed; public string error; public List rows = new List(); } [Serializable] sealed class Row { public string phase; public int chassis, worlds, suns, enabledSpots, probes, cameras, shadowOnlyRenderers; public double allocatedMiB; public bool passed, reflectionReady; } } }