133 lines
9.1 KiB
C#
133 lines
9.1 KiB
C#
using System;
|
|
using System.IO;
|
|
using AIGame.EditorTools;
|
|
using AOT.Editor.YooAssetTools;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using UnityEngine.EventSystems;
|
|
using System.Collections.Generic;
|
|
|
|
public static class IntegrateHomeCamp
|
|
{
|
|
public static string Status() => "frame=" + Time.frameCount + " paused=" + EditorApplication.isPaused + " background=" + Application.runInBackground;
|
|
public static string ExplorerStatus()
|
|
{
|
|
var presenter = UnityEngine.Object.FindObjectOfType<HotUpdate.UI.HomeExplorerPresenter>();
|
|
var stage = GameObject.Find("HomeExplorerStage");
|
|
if (!stage) return "No explorer stage";
|
|
var animator = stage.GetComponentInChildren<Animator>(true);
|
|
return "ready=" + (presenter && presenter.Ready) + " animator=" + (animator != null) + " controller=" + (animator && animator.runtimeAnimatorController ? animator.runtimeAnimatorController.name : "null") + " avatar=" + (animator && animator.avatar ? animator.avatar.name : "null");
|
|
}
|
|
public static string EnablePreviewFrames() { Application.runInBackground = true; return Status(); }
|
|
public static async System.Threading.Tasks.Task<string> CheckArtManifest()
|
|
{
|
|
if (!EditorApplication.isPlaying) throw new InvalidOperationException("Play Mode required");
|
|
if (!YooAsset.YooAssets.IsInitialized) YooAsset.YooAssets.Initialize();
|
|
if (!YooAsset.YooAssets.TryGetPackage("Art", out var package)) package = YooAsset.YooAssets.CreatePackage("Art");
|
|
var build = YooAsset.EditorSimulateBuildInvoker.Build("Art", (int)YooAsset.EBundleType.VirtualAssetBundle);
|
|
var init = package.InitializePackageAsync(new YooAsset.EditorSimulateModeOptions {
|
|
EditorFileSystemParameters = YooAsset.FileSystemParameters.CreateDefaultEditorFileSystemParameters(build.PackageRootDirectory)
|
|
});
|
|
await init;
|
|
if (init.Status != YooAsset.EOperationStatus.Succeeded) throw new InvalidOperationException(init.Error);
|
|
var version = package.RequestPackageVersionAsync(); await version;
|
|
if (version.Status != YooAsset.EOperationStatus.Succeeded) throw new InvalidOperationException(version.Error);
|
|
var manifest = package.LoadPackageManifestAsync(new YooAsset.LoadPackageManifestOptions(version.PackageVersion, 60)); await manifest;
|
|
if (manifest.Status != YooAsset.EOperationStatus.Succeeded) throw new InvalidOperationException(manifest.Error);
|
|
if (!package.IsLocationValid("HomeCamp")) throw new InvalidOperationException("HomeCamp missing from Art manifest");
|
|
return "PASS simulated Art manifest resolves HomeCamp";
|
|
}
|
|
public static async System.Threading.Tasks.Task<string> CheckArtSceneLoad()
|
|
{
|
|
var manager = HotUpdate.UI.UiManager.Instance;
|
|
var oldHud = manager.Get("UI_MainHUD");
|
|
manager.Close("UI_MainHUD", true);
|
|
for (int i = 0; i < 100 && UnityEngine.SceneManagement.SceneManager.GetSceneByPath("Assets/Bundles/Scenes/Town/HomeCamp/HomeCamp.unity").isLoaded; i++)
|
|
await System.Threading.Tasks.Task.Delay(50);
|
|
GameObject hud = null;
|
|
manager.StartCoroutine(manager.OpenAsync("UI_MainHUD", loaded => hud = loaded));
|
|
for (int i = 0; i < 200 && !hud; i++) await System.Threading.Tasks.Task.Delay(50);
|
|
if (!hud) throw new InvalidOperationException("HUD reload failed");
|
|
var view = hud.GetComponent<HotUpdate.UI.MainHudView>() ?? hud.AddComponent<HotUpdate.UI.MainHudView>();
|
|
view.Bind();
|
|
for (int i = 0; i < 200 && (!hud || !hud.GetComponentInChildren<HotUpdate.UI.HomeCampPresenter>(true) || !hud.GetComponentInChildren<HotUpdate.UI.HomeCampPresenter>(true).Ready); i++)
|
|
await System.Threading.Tasks.Task.Delay(50);
|
|
var presenter = hud.GetComponentInChildren<HotUpdate.UI.HomeCampPresenter>(true);
|
|
var field = typeof(HotUpdate.UI.HomeCampPresenter).GetField("_handle", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
|
|
if (presenter == null || !presenter.Ready || !(field.GetValue(presenter) is YooAsset.SceneHandle handle) || handle.Status != YooAsset.EOperationStatus.Succeeded)
|
|
throw new InvalidOperationException("YooAsset scene handle did not load HomeCamp");
|
|
return "PASS YooAsset additive scene load and HUD render";
|
|
}
|
|
public static string CheckPreview()
|
|
{
|
|
var hud = HotUpdate.UI.UiManager.Instance?.Get("UI_MainHUD");
|
|
if (!hud) throw new InvalidOperationException("HUD not ready");
|
|
var camp = hud.GetComponentInChildren<HotUpdate.UI.HomeCampPresenter>(true);
|
|
if (!camp || !camp.Ready) throw new InvalidOperationException("Camp preview not ready");
|
|
var image = camp.GetComponent<RawImage>();
|
|
if (!image.enabled || image.raycastTarget || !(image.texture is RenderTexture rt))
|
|
throw new InvalidOperationException("Camp render target or hit testing invalid");
|
|
var camera = GameObject.Find("HomeCampCamera")?.GetComponent<Camera>();
|
|
if (!camera || camera.targetTexture != rt || !camera.enabled)
|
|
throw new InvalidOperationException("Camp camera is not rendering into HUD");
|
|
var explorer = hud.transform.Find("ExplorerStage");
|
|
if (!explorer || explorer.gameObject.activeSelf || hud.transform.Find("Btn_Explorer").gameObject.activeSelf)
|
|
throw new InvalidOperationException("Legacy explorer overlay should be hidden over the 3D camp");
|
|
hud.SetActive(false);
|
|
if (camera.enabled && camera.gameObject.activeInHierarchy) throw new InvalidOperationException("Hidden HUD still renders camp");
|
|
hud.SetActive(true);
|
|
if (!camera.enabled || !camera.gameObject.activeInHierarchy) throw new InvalidOperationException("Camp did not resume");
|
|
return "PASS camp render " + rt.width + "x" + rt.height + "; FOV=" + camera.fieldOfView + "; legacy overlay hidden; hide/resume passed";
|
|
}
|
|
public static string Capture()
|
|
{
|
|
var hud = HotUpdate.UI.UiManager.Instance.Get("UI_MainHUD");
|
|
var camera = GameObject.Find("HomeMobileTestCamera").GetComponent<Camera>();
|
|
var canvas = hud.GetComponent<Canvas>();
|
|
Canvas.ForceUpdateCanvases();
|
|
foreach (var button in hud.transform.Find("Layout_Top").GetComponentsInChildren<Button>())
|
|
{
|
|
var rect = (RectTransform)button.transform;
|
|
var hits = new List<RaycastResult>();
|
|
EventSystem.current.RaycastAll(new PointerEventData(EventSystem.current) { position = rect.TransformPoint(rect.rect.center) }, hits);
|
|
if (hits.Count == 0 || ExecuteEvents.GetEventHandler<IPointerClickHandler>(hits[0].gameObject) != button.gameObject)
|
|
throw new InvalidOperationException("Header hit blocked: " + button.name);
|
|
}
|
|
var target = new RenderTexture(Screen.width, Screen.height, 24);
|
|
var pixels = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
|
|
var mode = canvas.renderMode; var canvasCamera = canvas.worldCamera; var mask = camera.cullingMask;
|
|
var previous = RenderTexture.active;
|
|
try
|
|
{
|
|
camera.targetTexture = target; camera.cullingMask = 1 << LayerMask.NameToLayer("UI");
|
|
canvas.renderMode = RenderMode.ScreenSpaceCamera; canvas.worldCamera = camera; canvas.planeDistance = 1;
|
|
Canvas.ForceUpdateCanvases(); camera.Render(); RenderTexture.active = target;
|
|
pixels.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0); pixels.Apply();
|
|
var dir = Path.GetFullPath(Path.Combine(Application.dataPath, "../../Tools/output/homecamp_integration"));
|
|
Directory.CreateDirectory(dir); var path = Path.Combine(dir, "home_" + Screen.width + "x" + Screen.height + ".png");
|
|
File.WriteAllBytes(path, pixels.EncodeToPNG()); return "PASS header hit targets; " + path;
|
|
}
|
|
finally
|
|
{
|
|
RenderTexture.active = previous; camera.targetTexture = null; camera.cullingMask = mask;
|
|
canvas.renderMode = mode; canvas.worldCamera = canvasCamera;
|
|
target.Release(); UnityEngine.Object.Destroy(target); UnityEngine.Object.Destroy(pixels);
|
|
}
|
|
}
|
|
public static string Build()
|
|
{
|
|
if (EditorApplication.isPlaying) throw new InvalidOperationException("Stop Play Mode before building the HUD.");
|
|
var json = Path.GetFullPath(Path.Combine(Application.dataPath, "../../Doc/UIPrefabCreater/UI_MainHUD.json"));
|
|
var validation = JsonUIPrefabBuilder.Validate(json);
|
|
if (!validation.Ok) throw new InvalidOperationException(string.Join("\n", validation.Errors));
|
|
var path = JsonUIPrefabBuilder.BuildFromJsonFile(json);
|
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
|
|
if (prefab == null || prefab.transform.Find("CampWorld")?.GetComponent<RawImage>() == null)
|
|
throw new InvalidOperationException("HUD CampWorld missing");
|
|
if (prefab.transform.Find("CampWorld").GetComponent<RawImage>().raycastTarget)
|
|
throw new InvalidOperationException("Camp image must not intercept buttons");
|
|
return "HUD: " + path + "; " + BuildAndStageArt.EnsureLoadableScenePrefabs();
|
|
}
|
|
}
|