#if UNITY_EDITOR using System; using System.IO; using System.Linq; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.SceneManagement; using Object=UnityEngine.Object; /// Isolated static or sampled-pose views; preserves all open scene contents. public static class AuditCharacterVisual { public static string Capture(string prefabPath,string outputDirectory,float height=.55f,string clipPath="",float phase=0) { string dir=Path.GetFullPath(Path.Combine(Application.dataPath,"../..",outputDirectory));Directory.CreateDirectory(dir); var scene=EditorSceneManager.NewPreviewScene(); try { var prefab=AssetDatabase.LoadAssetAtPath(prefabPath); if(prefab==null)throw new Exception("Missing visual prefab: "+prefabPath); var unit=(GameObject)PrefabUtility.InstantiatePrefab(prefab,scene); var animator=unit.GetComponentInChildren();if(animator!=null)animator.enabled=false; if(animator==null) { var filters=unit.GetComponentsInChildren(); var points=filters.SelectMany(m=>m.sharedMesh.vertices.Select(v=>m.transform.TransformPoint(v))).ToArray(); if(points.Length==0)throw new Exception("No static geometry"); float minY=points.Min(v=>v.y),actualHeight=points.Max(v=>v.y)-minY; int triangles=filters.Sum(m=>m.sharedMesh.triangles.Length/3); if(Mathf.Abs(minY)>.002f || Mathf.Abs(actualHeight-height)>.002f)throw new Exception("Static height/bottom invalid"); if(unit.GetComponentsInChildren().Any(r=>r.sharedMaterial==null || r.sharedMaterial.shader.name!="Test/XPbr"))throw new Exception("Static XPbr material missing"); File.WriteAllText(Path.Combine(dir,"static_verification.txt"),$"height={actualHeight:F6} bottom={minY:F6} triangles={triangles} XPbr=True; facing verified in front/side/back views"); } if(!string.IsNullOrEmpty(clipPath)) { var clip=AssetDatabase.LoadAssetAtPath(clipPath); if(clip==null || animator==null)throw new Exception("Missing clip/animator"); clip.SampleAnimation(animator.gameObject,clip.length*phase); } var light=new GameObject("AuditLight").AddComponent();SceneManager.MoveGameObjectToScene(light.gameObject,scene); light.type=LightType.Directional;light.intensity=1.4f;light.transform.rotation=Quaternion.Euler(40,-30,0); var camera=new GameObject("AuditCamera").AddComponent();SceneManager.MoveGameObjectToScene(camera.gameObject,scene);camera.scene=scene; camera.clearFlags=CameraClearFlags.SolidColor;camera.backgroundColor=new Color(.56f,.64f,.7f); camera.orthographic=true;camera.orthographicSize=height*.68f;camera.nearClipPlane=.01f;camera.farClipPlane=10; var rt=new RenderTexture(640,640,24);var tex=new Texture2D(640,640,TextureFormat.RGB24,false);var previous=RenderTexture.active; try { var directions=new[]{new Vector3(0,.22f,-1),new Vector3(1,.22f,0),new Vector3(0,.22f,1),new Vector3(.7f,.3f,-1)}; string[] names={"front","side","back","perspective"}; for(int i=0;i