120 lines
7.0 KiB
C#
120 lines
7.0 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using HotUpdate.UI;
|
|
using Newtonsoft.Json;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using Object = UnityEngine.Object;
|
|
|
|
public static class VerifyPreviewDeployment
|
|
{
|
|
static string Output => Path.GetFullPath(Path.Combine(Application.dataPath, "../../Tools/output/server_release"));
|
|
const string MaterialPath = "Assets/Bundles/UI/Material/HomeExplorerCutout.mat";
|
|
|
|
public static string PackedMaterial()
|
|
{
|
|
string art = Path.GetFullPath(Path.Combine(Application.dataPath, "../../Tools/cdn_root/wechat/1.0.0/Art"));
|
|
var shaders = AssetBundle.LoadFromFile(Directory.GetFiles(art, "unityshaders_*.bundle").Single());
|
|
var bundle = AssetBundle.LoadFromFile(Directory.GetFiles(art, "share_assets_bundles_ui_material_*.bundle").Single());
|
|
Check(bundle != null, "Material bundle unavailable");
|
|
try
|
|
{
|
|
var material = bundle.LoadAllAssets<Material>().Single(m => m.name == "HomeExplorerCutout");
|
|
var saved = new SerializedObject(material).FindProperty("m_SavedProperties.m_Colors");
|
|
var key = Color.clear;
|
|
for (int i = 0; i < saved.arraySize; i++)
|
|
{
|
|
var pair = saved.GetArrayElementAtIndex(i);
|
|
if (pair.FindPropertyRelative("first").stringValue == "_Key") key = pair.FindPropertyRelative("second").colorValue;
|
|
}
|
|
Directory.CreateDirectory(Output);
|
|
string json = JsonConvert.SerializeObject(new { shippedKey = new[] { key.r, key.g, key.b },
|
|
sourceKey = AssetDatabase.LoadAssetAtPath<Material>(MaterialPath).GetColor("_Key").ToString(),
|
|
hardcodedMagentaMismatch = Vector4.Distance(key, Color.magenta) > .5f });
|
|
File.WriteAllText(Path.Combine(Output, "packed_preview.json"), json);
|
|
return json;
|
|
}
|
|
finally { bundle.Unload(true); if (shaders != null) shaders.Unload(true); }
|
|
}
|
|
|
|
public static string StartLegacyPreview()
|
|
{
|
|
Check(EditorApplication.isPlaying, "Play isolated scene first");
|
|
var holder = new GameObject("LegacyPreviewHolder"); holder.SetActive(false);
|
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Bundles/UI/Prefab/UI_MainHUD.prefab");
|
|
var hud = Object.Instantiate(prefab, holder.transform, false); hud.name = "LegacyPreviewHUD";
|
|
var raw = hud.transform.Find("ExplorerStage").GetComponent<RawImage>();
|
|
var material = new Material(AssetDatabase.LoadAssetAtPath<Material>(MaterialPath));
|
|
material.SetColor("_Key", new Color(.07f,.02f,.09f,1)); raw.material = material;
|
|
holder.SetActive(true);
|
|
var camera = new GameObject("LegacyPreviewCamera", typeof(Camera)).GetComponent<Camera>();
|
|
camera.clearFlags = CameraClearFlags.SolidColor; camera.backgroundColor = Color.gray; camera.cullingMask = 0;
|
|
return "Started authored HUD with shipped legacy material key";
|
|
}
|
|
|
|
public static string RuntimeStatus() => JsonConvert.SerializeObject(new {
|
|
roots = Object.FindObjectsOfType<HomeExplorerPresenter>(true).Select(p => new { p.name,p.enabled,
|
|
active=p.gameObject.activeInHierarchy,p.Ready,material=p.GetComponent<RawImage>()?.material?.name,
|
|
shader=p.GetComponent<RawImage>()?.material?.shader?.name,
|
|
supported=p.GetComponent<RawImage>()?.material?.shader?.isSupported }).ToArray(),
|
|
cameras=Object.FindObjectsOfType<Camera>().Select(c=>c.name).ToArray()
|
|
});
|
|
|
|
public static string CheckAndCapture()
|
|
{
|
|
var hud = GameObject.Find("LegacyPreviewHUD"); var raw = hud.transform.Find("ExplorerStage").GetComponent<RawImage>();
|
|
var presenter = raw.GetComponent<HomeExplorerPresenter>();
|
|
Check(presenter != null && presenter.Ready, "Preview not ready");
|
|
var previewCamera = (Camera)typeof(HomeExplorerPresenter).GetField("_camera", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(presenter);
|
|
Check(Vector4.Distance(previewCamera.backgroundColor, raw.material.GetColor("_Key")) < .001f, "Camera clear differs from shipped material");
|
|
VerifyDiscard(raw.material);
|
|
var canvas = hud.GetComponent<Canvas>(); var oldMode = canvas.renderMode; var oldCamera = canvas.worldCamera;
|
|
var camera = GameObject.Find("LegacyPreviewCamera").GetComponent<Camera>();
|
|
var target = new RenderTexture(540, 960, 24); var pixels = new Texture2D(540, 960, TextureFormat.RGB24, false);
|
|
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,540,960),0,0); pixels.Apply(); Directory.CreateDirectory(Output);
|
|
File.WriteAllBytes(Path.Combine(Output,"legacy_preview.png"),pixels.EncodeToPNG());
|
|
}
|
|
finally
|
|
{
|
|
RenderTexture.active = previous; camera.targetTexture = null; canvas.renderMode = oldMode; canvas.worldCamera = oldCamera;
|
|
target.Release(); Object.Destroy(target); Object.Destroy(pixels);
|
|
}
|
|
return "PASS: legacy shipped material and camera match; GPU removes the key, foreground retained; screenshot captured";
|
|
}
|
|
|
|
static void VerifyDiscard(Material material)
|
|
{
|
|
var input = new Texture2D(2,2,TextureFormat.RGBA32,false,true);
|
|
var output = new RenderTexture(8,8,0,RenderTextureFormat.ARGB32,RenderTextureReadWrite.Linear);
|
|
var read = new Texture2D(8,8,TextureFormat.RGBA32,false,true); var previous = RenderTexture.active;
|
|
try
|
|
{
|
|
foreach (var key in new[] { new Color(.07f,.02f,.09f,1), Color.magenta })
|
|
{
|
|
var test = new Material(material); test.SetColor("_Key",key);
|
|
try
|
|
{
|
|
input.SetPixels(Enumerable.Repeat(key,4).ToArray()); input.Apply(); output.Create();
|
|
RenderTexture.active = output; GL.Clear(true,true,Color.cyan); Graphics.Blit(input,output,test);
|
|
RenderTexture.active = output; read.ReadPixels(new Rect(0,0,8,8),0,0);read.Apply();
|
|
var color = read.GetPixel(4,4); Check(color.r < .05f && color.g > .95f && color.b > .95f,"GPU did not discard background");
|
|
Graphics.Blit(Texture2D.whiteTexture,output,test); RenderTexture.active = output;
|
|
read.ReadPixels(new Rect(0,0,8,8),0,0);read.Apply(); Check(read.GetPixel(4,4).r > .95f,"GPU discarded foreground");
|
|
}
|
|
finally { Object.Destroy(test); }
|
|
}
|
|
}
|
|
finally { RenderTexture.active = previous; output.Release(); Object.Destroy(input); Object.Destroy(output); Object.Destroy(read); }
|
|
}
|
|
static void Check(bool pass,string message) { if (!pass) throw new Exception(message); }
|
|
}
|