Add fixed-camera tower effect preview scene
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.TestTools;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor.SceneManagement;
|
||||
#endif
|
||||
using BumpCombat.Defense;
|
||||
|
||||
namespace BumpCombat.PlayModeTests
|
||||
{
|
||||
public sealed class Defense25DPreviewTests
|
||||
{
|
||||
private float previousTimeScale;
|
||||
|
||||
[UnitySetUp]
|
||||
public IEnumerator SetNormalTimeScale()
|
||||
{
|
||||
previousTimeScale = Time.timeScale;
|
||||
Time.timeScale = 1f;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTearDown]
|
||||
public IEnumerator RestoreTimeScale()
|
||||
{
|
||||
Time.timeScale = previousTimeScale;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator FireTargetAuraAndMeteor_KeepGroundHeightLayersAndCaptureRuntimeFrames()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
EditorSceneManager.LoadSceneInPlayMode("Assets/_Project/Scenes/Defense25DPreview.unity", new LoadSceneParameters(LoadSceneMode.Single));
|
||||
#else
|
||||
SceneManager.LoadScene("Defense25DPreview");
|
||||
#endif
|
||||
yield return null;
|
||||
var preview = Object.FindFirstObjectByType<Defense25DPreview>();
|
||||
Assert.That(preview, Is.Not.Null);
|
||||
Assert.That(preview.AuraBackFrames.Length, Is.EqualTo(6));
|
||||
Assert.That(preview.AuraFrontFrames.Length, Is.EqualTo(6));
|
||||
Assert.That(preview.BodyFrames.Length, Is.EqualTo(6));
|
||||
Assert.That(preview.MeteorFlightFrames.Length, Is.EqualTo(4));
|
||||
Assert.That(preview.MeteorImpactFrames.Length, Is.EqualTo(8));
|
||||
Assert.That(preview.Body.sprite.name, Does.StartWith("T3-Idle_"));
|
||||
Assert.That(preview.Body.transform.parent.GetComponentsInChildren<SpriteRenderer>().Length, Is.EqualTo(1));
|
||||
Assert.That(preview.AuraBack.sortingOrder, Is.LessThan(preview.Body.sortingOrder));
|
||||
Assert.That(preview.Body.sortingOrder, Is.LessThan(preview.AuraFront.sortingOrder));
|
||||
Assert.That(preview.AuraBack.transform.position, Is.EqualTo(preview.AuraFront.transform.position));
|
||||
Assert.That(preview.AuraBackFrames[0].pivot / preview.AuraBackFrames[0].rect.size, Is.EqualTo(new Vector2(0.5f, 0.4f)));
|
||||
Assert.That(Camera.main.orthographicSize, Is.EqualTo(2.8125f));
|
||||
Assert.That(preview.AuraBack.transform.localScale, Is.EqualTo(preview.AuraFront.transform.localScale));
|
||||
Assert.That(preview.BodyVisual.localPosition.y, Is.EqualTo(9f / 32f).Within(0.0001f));
|
||||
Assert.That(Defense25DPreview.ProjectGroundAndHeight(new Vector2(3f, 4f), 2f), Is.EqualTo(new Vector3(1f, 6f, 0f)));
|
||||
|
||||
string output = FindOutputDirectory();
|
||||
float deadline = Time.realtimeSinceStartup + 5f;
|
||||
while (!preview.Meteor.enabled && Time.realtimeSinceStartup < deadline) yield return null;
|
||||
Assert.That(preview.Meteor.enabled, Is.True, "Meteor did not start within five realtime seconds.");
|
||||
Capture(Camera.main, Path.Combine(output, "runtime-01-meteor-early.png"));
|
||||
Vector3 earlyViewport = Camera.main.WorldToViewportPoint(preview.Meteor.transform.position);
|
||||
Assert.That(earlyViewport.y, Is.InRange(0f, 1f), "Early meteor must stay within the camera frame.");
|
||||
|
||||
float initialHeight = preview.CurrentMeteorHeight;
|
||||
deadline = Time.realtimeSinceStartup + 5f;
|
||||
while (!(preview.CurrentMeteorHeight > 0f && preview.CurrentMeteorHeight <= initialHeight * 0.6f) &&
|
||||
Time.realtimeSinceStartup < deadline) yield return null;
|
||||
Assert.That(preview.CurrentMeteorHeight, Is.GreaterThan(0f).And.LessThanOrEqualTo(initialHeight * 0.6f),
|
||||
"Midflight capture did not reach the height threshold within five realtime seconds.");
|
||||
Capture(Camera.main, Path.Combine(output, "runtime-02-meteor-midflight.png"));
|
||||
Assert.That(preview.Meteor.transform.position, Is.Not.EqualTo(preview.GroundAnchor.position));
|
||||
Assert.That(preview.CurrentMeteorGround, Is.Not.EqualTo((Vector2)preview.GroundAnchor.position));
|
||||
|
||||
deadline = Time.realtimeSinceStartup + 5f;
|
||||
while (!(preview.Meteor.enabled && preview.CurrentMeteorHeight <= 0f) &&
|
||||
Time.realtimeSinceStartup < deadline) yield return null;
|
||||
Assert.That(preview.Meteor.enabled && preview.CurrentMeteorHeight <= 0f, Is.True,
|
||||
"Meteor did not reach ground height within five realtime seconds.");
|
||||
Capture(Camera.main, Path.Combine(output, "runtime-03-meteor-impact.png"));
|
||||
deadline = Time.realtimeSinceStartup + 5f;
|
||||
while (preview.Meteor.enabled && Time.realtimeSinceStartup < deadline) yield return null;
|
||||
Assert.That(preview.Meteor.enabled, Is.False, "Meteor impact sequence did not finish within five realtime seconds.");
|
||||
Assert.That(preview.AuraBack.transform.position.x, Is.EqualTo(preview.GroundAnchor.position.x).Within(0.0001f));
|
||||
}
|
||||
|
||||
private static void Capture(Camera camera, string path)
|
||||
{
|
||||
const int width = 1280, height = 720;
|
||||
var texture = new RenderTexture(width, height, 24, RenderTextureFormat.ARGB32);
|
||||
var image = new Texture2D(width, height, TextureFormat.RGB24, false);
|
||||
camera.targetTexture = texture;
|
||||
camera.Render();
|
||||
RenderTexture previous = RenderTexture.active;
|
||||
RenderTexture.active = texture;
|
||||
image.ReadPixels(new Rect(0, 0, width, height), 0, 0);
|
||||
image.Apply();
|
||||
File.WriteAllBytes(path, image.EncodeToPNG());
|
||||
camera.targetTexture = null;
|
||||
RenderTexture.active = previous;
|
||||
Object.Destroy(texture);
|
||||
Object.Destroy(image);
|
||||
}
|
||||
|
||||
private static string FindOutputDirectory()
|
||||
{
|
||||
for (DirectoryInfo folder = new DirectoryInfo(Application.dataPath); folder != null; folder = folder.Parent)
|
||||
{
|
||||
string output = Path.Combine(folder.FullName, "output/tower-25d-v1");
|
||||
if (Directory.Exists(output)) return output;
|
||||
}
|
||||
|
||||
string projectOutput = Path.GetFullPath(Path.Combine(Application.dataPath, "../output/tower-25d-v1"));
|
||||
Directory.CreateDirectory(projectOutput);
|
||||
return projectOutput;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 417f0ae0e37f4cc38c234a7e89c06472
|
||||
Reference in New Issue
Block a user