Files
AIGame/AIClient/AgentScripts/VerifyEnemyStudioBatch.cs
T

77 lines
7.3 KiB
C#

using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
using Object=UnityEngine.Object;
/// <summary>One Play session exercises all four original controllers on their new Studio meshes.</summary>
public static class VerifyEnemyStudioBatch
{
static readonly string[] Actors={"Hornlet","Dashlet","Shellhorn","HornCaptain"};
static string Repo=>Path.GetFullPath(Path.Combine(Application.dataPath,"../.."));
static void Check(bool v,string message){if(!v)throw new Exception(message);}
public static async Task<string> PlayAll()
{
Check(EditorApplication.isPlaying,"Use Play Mode");
var objects=new List<GameObject>();var animators=new List<Animator>();var bones=new List<Transform>();var seen=Actors.Select(a=>new HashSet<string>()).ToArray();var tilt=new float[4];
try
{
for(int i=0;i<Actors.Length;i++)
{
string actor=Actors[i];var prefab=AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Bundles/Characters/Enemy/"+actor+"Studio/"+actor+"Studio_Enemy.prefab");Check(prefab!=null,"Missing "+actor);
var go=Object.Instantiate(prefab);objects.Add(go);go.transform.position=new Vector3(400+i*3,0,0);var anim=go.GetComponentInChildren<Animator>();animators.Add(anim);bones.Add(go.GetComponentsInChildren<Transform>().Single(t=>t.name=="bone_0"));
var original=AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Bundles/Characters/Enemy/"+actor+"/"+actor+"_Enemy.prefab").GetComponentInChildren<Animator>();Check(anim.avatar==original.avatar&&anim.runtimeAnimatorController==original.runtimeAnimatorController,"Original avatar/controller changed "+actor);
}
for(int phase=0;phase<3;phase++)
{
foreach(var anim in animators){anim.SetInteger("Motion",phase==1?1:0);if(phase==2)anim.SetTrigger("Attack");}
var until=DateTime.UtcNow.AddSeconds(2);
while(DateTime.UtcNow<until)
{
Check(EditorApplication.isPlaying,"Editor left Play during verification");
for(int i=0;i<Actors.Length;i++){var s=animators[i].GetCurrentAnimatorStateInfo(0);foreach(string name in new[]{"Idle","Walk","Attack"})if(s.IsName(name))seen[i].Add(name);tilt[i]=Mathf.Max(tilt[i],Vector3.Angle(bones[i].up,Vector3.up));Check(Vector3.Distance(objects[i].transform.position,new Vector3(400+i*3,0,0))<.001f,"Root moved "+Actors[i]);}
await Task.Delay(40);
}
}
for(int i=0;i<Actors.Length;i++)
{
Check(seen[i].Count==3&&tilt[i]<25,"Missing state or bad tilt "+Actors[i]);string dir=Path.Combine(Repo,"Tools/output/studio_trial",Actors[i]);
File.WriteAllText(Path.Combine(dir,"play_verification.json"),JsonConvert.SerializeObject(new{status="pass",seen=seen[i],maxTilt=tilt[i],originalController=AssetDatabase.GetAssetPath(animators[i].runtimeAnimatorController),originalAvatar=true,rootPinned=true,batch="four_enemies"},Formatting.Indented));
}
return "PASS four Studio enemies: original Avatar/controller, Idle/Walk/Attack, orientation and pinned actor roots";
}
finally{foreach(var go in objects)if(go!=null)Object.Destroy(go);}
}
public static async Task<string> Overview()
{
Check(!EditorApplication.isPlaying,"Build overview in Edit Mode");
var actors=Actors.Concat(new[]{"GreatHorn"}).ToArray();var heights=new[]{.5f,.5f,.5f,.6f,.8f};
var previous=SceneManager.GetActiveScene();var scene=EditorSceneManager.NewScene(NewSceneSetup.EmptyScene,NewSceneMode.Additive);var old=RenderTexture.active;var rt=new RenderTexture(1800,900,24);var texture=new Texture2D(1800,900,TextureFormat.RGB24,false);
try
{
SceneManager.SetActiveScene(scene);var root=new GameObject("FiveEnemyStudioOverview");root.transform.position=new Vector3(440,0,0);
for(int row=0;row<2;row++)for(int i=0;i<actors.Length;i++)
{
string name=actors[i]+(row==0?"":"Studio");var prefab=AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Bundles/Characters/Enemy/"+name+"/"+name+"_Enemy.prefab");Check(prefab!=null,"Missing "+name);
var go=(GameObject)PrefabUtility.InstantiatePrefab(prefab,scene);go.transform.SetParent(root.transform,false);go.transform.localPosition=new Vector3((i-2)*1.8f,0,row==0?1.35f:-1.35f);go.transform.localScale=Vector3.one*(.8f/heights[i]);
var animator=go.GetComponentInChildren<Animator>();animator.enabled=false;var clip=AssetDatabase.LoadAssetAtPath<AnimationClip>("Assets/Bundles/Characters/Enemy/"+actors[i]+"/Clips/Idle.anim");clip.SampleAnimation(animator.gameObject,clip.length*.5f);
var label=new GameObject("Label_"+name).AddComponent<TextMesh>();label.transform.SetParent(root.transform,false);label.transform.localPosition=go.transform.localPosition+new Vector3(0,-.22f,-.1f);label.transform.localRotation=Quaternion.Euler(12,0,0);label.text=(row==0?"Original":"Studio")+" / "+actors[i];label.fontSize=50;label.characterSize=.022f;label.anchor=TextAnchor.MiddleCenter;label.color=new Color(.95f,.98f,1);
}
var floor=GameObject.CreatePrimitive(PrimitiveType.Plane);floor.name="Ground_Y0";floor.transform.SetParent(root.transform,false);floor.transform.localPosition=new Vector3(0,-.002f,0);floor.transform.localScale=new Vector3(1.05f,1,.57f);floor.GetComponent<Renderer>().sharedMaterial=AssetDatabase.LoadAssetAtPath<Material>("Assets/Bundles/Scenes/Review/EnemyReviewFloor.mat");Object.DestroyImmediate(floor.GetComponent<Collider>());
var camera=new GameObject("EnemyStudioOverviewCamera").AddComponent<Camera>();camera.transform.SetParent(root.transform,false);camera.transform.localPosition=new Vector3(0,7,-10);camera.transform.LookAt(root.transform.position+Vector3.up*.45f);camera.orthographic=true;camera.orthographicSize=2.3f;camera.aspect=2;camera.nearClipPlane=.1f;camera.farClipPlane=100;camera.clearFlags=CameraClearFlags.SolidColor;camera.backgroundColor=new Color(.075f,.105f,.14f);camera.cullingMask=1<<26;camera.enabled=false;
var light=new GameObject("OverviewLight").AddComponent<Light>();light.transform.SetParent(root.transform,false);light.type=LightType.Directional;light.intensity=1.1f;light.transform.localRotation=Quaternion.Euler(40,-35,0);light.cullingMask=1<<26;
foreach(var t in root.GetComponentsInChildren<Transform>(true))t.gameObject.layer=26;
EditorSceneManager.SaveScene(scene,"Assets/Bundles/Scenes/Review/Studio_Enemies_Overview.unity");await Task.Delay(100);
camera.targetTexture=rt;camera.Render();RenderTexture.active=rt;texture.ReadPixels(new Rect(0,0,1800,900),0,0);texture.Apply();camera.targetTexture=null;
const string path="Assets/Screenshots/enemy_studio_batch_overview.png";File.WriteAllBytes(Path.Combine(Application.dataPath,"../",path),texture.EncodeToPNG());AssetDatabase.ImportAsset(path);return path;
}
finally{RenderTexture.active=old;rt.Release();Object.DestroyImmediate(rt);Object.DestroyImmediate(texture);SceneManager.SetActiveScene(previous);EditorSceneManager.CloseScene(scene,true);}
}
}