using System; using System.IO; using System.Linq; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; using DepthsOfGreed.HandbookUI; [InitializeOnLoad] public static class SupplyBasementValidation { static SupplyBasementValidation(){if(SessionState.GetBool("SupplyValidate",false))EditorApplication.playModeStateChanged+=Ready;} public static void Validate() { EditorSceneManager.OpenScene("Assets/Scenes/Tim_Test_UI.unity"); SessionState.SetBool("SupplyValidate",true);EditorApplication.playModeStateChanged+=Ready;EditorApplication.EnterPlaymode(); } static void Ready(PlayModeStateChange state) { if(state!=PlayModeStateChange.EnteredPlayMode)return; SessionState.SetBool("SupplyValidate",false);EditorApplication.playModeStateChanged-=Ready; double due=EditorApplication.timeSinceStartup+1;int stage=0;SupplyBasementController c=null;int count=0;long first=0;Vector3 bookScale=Vector3.one; EditorApplication.CallbackFunction run=null;run=()=> { if(EditorApplication.timeSinceStartup(); Assert(c && c.connectionButtons.Length==8 && c.priorityButtons.Length==3,"Authored references"); Assert(!c.basementView.activeSelf && c.handbookRoot.activeSelf,"Starts on tower floor"); count=Count(c);bookScale=c.handbook.transform.Find("OpenBook").localScale; var catalog=AssetDatabase.LoadAssetAtPath("Assets/HandbookData/TestTurmkatalog.asset"); var result=c.placement.Backend.ExecuteBuild(new BuildRequest(catalog.towers.First(t=>t.id=="ammo_0"),new Vector3(3.5f,0,0))); Assert(result.Allowed,"Test tower build");first=c.placement.Backend.BuiltObjects.Last().instanceId; c.UseLift();c.UseLift();stage=1;due=EditorApplication.timeSinceStartup+1.7; } else if(stage==1) { Assert(c.IsInBasement && !c.IsTravelling && c.basementView.activeSelf && c.handbookVisibility.alpha==0,"Lift arrival"); Assert(c.handbookRoot.activeSelf && c.placement.isActiveAndEnabled,"Backend keeps updating in basement"); Assert(c.connectionButtons[0].interactable && c.IsConnectionEnabled(first),"Automatic connection"); c.ToggleConnection(0);Assert(!c.IsConnectionEnabled(first),"Disconnect"); c.ToggleConnection(0);Assert(c.IsConnectionEnabled(first),"Reconnect"); c.SetPriority(1);Assert(c.Priority==1,"Set priority"); c.SetPriority(1);Assert(c.Priority==-1,"Return to automatic priority"); // Force both travel directions independently of the loading pause. var pause=typeof(SupplyBasementController).GetField("truckPauseUntil",System.Reflection.BindingFlags.Instance|System.Reflection.BindingFlags.NonPublic); var truckPosition=c.truck.anchoredPosition; pause.SetValue(c,0f);c.truck.anchoredPosition=new Vector2(10000,truckPosition.y);c.SendMessage("Update"); Assert(c.truck.localScale.x<0,"Truck faces left while driving left"); pause.SetValue(c,0f);c.truck.anchoredPosition=new Vector2(-10000,truckPosition.y);c.SendMessage("Update"); Assert(c.truck.localScale.x>0,"Truck faces right while driving right"); c.truck.anchoredPosition=truckPosition; Assert(c.placement.Backend.BuiltObjects.Count==1,"No duplicate towers"); if (SystemInfo.graphicsDeviceType != GraphicsDeviceType.Null && Environment.GetCommandLineArgs().Contains("-captureSupplyPreview")) Capture(c); Assert(Count(c)==count,"No generated room UI"); c.UseLift();stage=2;due=EditorApplication.timeSinceStartup+1.7; } else { Assert(!c.IsInBasement && !c.IsTravelling && c.handbookRoot.activeSelf && c.handbookVisibility.alpha==1,"Return to tower"); Assert(c.handbook.transform.Find("OpenBook").localScale==bookScale,"Book scale preserved"); Assert(c.placement.Backend.BuiltObjects.Count==1,"Tower retained across trip"); Assert(Count(c)==count,"No UI created on second trip"); Debug.Log("SUPPLY_BASEMENT_RUNTIME_OK: native hierarchy, auto connection, toggle, priority, two-way lift and preserved book layout."); EditorApplication.update-=run;EditorApplication.Exit(0); } } catch(Exception e){EditorApplication.update-=run;Debug.LogException(e);EditorApplication.Exit(1);} };EditorApplication.update+=run; } static int Count(SupplyBasementController c)=>c.GetComponentInParent().GetComponentsInChildren(true).Count(t=>!t.name.StartsWith("TMP")); static void Assert(bool condition,string message){if(!condition)throw new Exception(message);} static void Capture(SupplyBasementController c) { var camera=Camera.main;var canvas=c.GetComponentInParent(); var rt=new RenderTexture(1920,1080,24);rt.Create();camera.targetTexture=rt;camera.aspect=1920f/1080; canvas.renderMode=RenderMode.ScreenSpaceCamera;canvas.worldCamera=camera;canvas.planeDistance=1;canvas.sortingOrder=200; Canvas.ForceUpdateCanvases();RenderPipeline.SubmitRenderRequest(camera,new UniversalRenderPipeline.SingleCameraRequest{destination=rt}); var previous=RenderTexture.active;RenderTexture.active=rt;var tex=new Texture2D(1920,1080,TextureFormat.RGB24,false);tex.ReadPixels(new Rect(0,0,1920,1080),0,0);tex.Apply();RenderTexture.active=previous; var folder=Path.Combine(Path.GetDirectoryName(Application.dataPath),"Temp","HandbookValidation"); Directory.CreateDirectory(folder);File.WriteAllBytes(Path.Combine(folder,"basement-preview.png"),tex.EncodeToPNG()); UnityEngine.Object.DestroyImmediate(tex);camera.targetTexture=null;rt.Release();UnityEngine.Object.DestroyImmediate(rt);canvas.renderMode=RenderMode.ScreenSpaceOverlay; } }