Files

112 lines
5.3 KiB
C#

using System.Linq;
using System.Text;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
/// <summary>
/// Nests the authored A-scheme battlefield under the live battle prefab.
/// Gameplay actors stay on PrototypeArena; the primitive ground is turned off.
/// </summary>
public static class AttachGreenfield
{
const string Arena = "Assets/Bundles/Scenes/Prototype/PrototypeArena.prefab";
const string Battlefield = "Assets/Bundles/Scenes/Prototype/Battlefield/Battlefield_Greenfield.prefab";
public static string Build()
{
if (EditorApplication.isPlaying) throw new System.Exception("Attach the battlefield in Edit Mode.");
var battlefield = AssetDatabase.LoadAssetAtPath<GameObject>(Battlefield);
if (battlefield == null) throw new System.Exception("Missing " + Battlefield);
var root = PrefabUtility.LoadPrefabContents(Arena);
try
{
var previous = root.transform.Find("Greenfield");
if (previous != null) Object.DestroyImmediate(previous.gameObject);
var instance = (GameObject)PrefabUtility.InstantiatePrefab(battlefield, root.transform);
instance.name = "Greenfield";
instance.transform.SetSiblingIndex(0);
foreach (var transform in instance.GetComponentsInChildren<Transform>(true)) transform.gameObject.layer = 30;
foreach (Transform child in root.transform)
{
if (child == instance.transform) continue;
if (child.name == "Ground" || child.name == "Lane" || child.name == "LeftBorder" || child.name == "RightBorder" || child.name == "BattleLight")
child.gameObject.SetActive(false);
}
PrefabUtility.SaveAsPrefabAsset(root, Arena);
}
finally { PrefabUtility.UnloadPrefabContents(root); }
AssetDatabase.SaveAssets();
return Verify();
}
public static string Verify()
{
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(Arena);
if (prefab == null) throw new System.Exception("Missing arena prefab.");
var scene = EditorSceneManager.NewPreviewScene();
var instance = (GameObject)PrefabUtility.InstantiatePrefab(prefab, scene);
try
{
var report = new StringBuilder();
var greenfield = instance.transform.Find("Greenfield");
if (greenfield == null || !greenfield.gameObject.activeSelf) throw new System.Exception("Greenfield is missing.");
Require(greenfield, "Ground/GroundMesh");
Require(greenfield, "Routes/Lane0");
Require(greenfield, "Routes/Lane1");
Require(greenfield, "Routes/Lane2");
Require(greenfield, "Lighting/Sun");
if (greenfield.Find("Decorations/bridge") != null || greenfield.Find("Decorations/bridgeLeft") != null || greenfield.Find("Decorations/bridgeRight") != null)
throw new System.Exception("Bridge is still placed in the battle arena.");
var badLayer = greenfield.GetComponentsInChildren<Renderer>(true).FirstOrDefault(r => r.gameObject.layer != 30);
if (badLayer != null) throw new System.Exception("Greenfield renderer not on layer 30: " + badLayer.name);
foreach (string name in new[] { "Heroes", "Enemies", "Projectiles", "DeploymentMarkers", "SkillEffects", "BattleCamera", "DefenceLine" })
{
var node = instance.transform.Find(name);
if (node == null || !node.gameObject.activeSelf) throw new System.Exception(name + " must stay active.");
}
foreach (Transform child in instance.transform)
{
if (child.name == "Ground" || child.name == "Lane" || child.name == "LeftBorder" || child.name == "RightBorder" || child.name == "BattleLight")
{
if (child.gameObject.activeSelf) throw new System.Exception(child.name + " primitive is still active.");
}
}
var mesh = greenfield.Find("Ground/GroundMesh").GetComponentInChildren<MeshRenderer>();
if (mesh == null || mesh.sharedMaterial == null || mesh.sharedMaterial.shader.name != "Test/XPbr")
throw new System.Exception("Greenfield ground shader is not Test/XPbr.");
report.Append("PASS nested Greenfield; primitives hidden; gameplay nodes kept.");
return report.ToString();
}
finally
{
Object.DestroyImmediate(instance);
EditorSceneManager.ClosePreviewScene(scene);
}
}
static void Require(Transform root, string path)
{
var node = root.Find(path);
if (node == null) throw new System.Exception("Missing " + path);
}
public static string FramePrefabStage()
{
var stage = PrefabStageUtility.OpenPrefab(Arena);
var view = SceneView.lastActiveSceneView;
if (view == null) throw new System.Exception("No Scene View.");
view.LookAt(new Vector3(0, 0, 3.5f), Quaternion.Euler(38, -35, 0), 22f);
view.orthographic = false;
view.Repaint();
return stage.assetPath;
}
public static string ClosePrefabStage()
{
StageUtility.GoToMainStage();
return "Closed prefab stage";
}
}