Files
tiny_tackle_heroes/Assets/_Project/Tests/PlayMode/Defense25DComparisonHudLayoutPlayModeTests.cs
T
2026-09-27 21:08:05 +09:00

100 lines
4.8 KiB
C#

using System.Collections;
using System.Linq;
using BumpCombat.Constants;
using BumpCombat.Defense;
using BumpCombat.Defense.Comparison;
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
using UnityEngine.TestTools;
using Object = UnityEngine.Object;
namespace BumpCombat.Tests
{
public sealed class Defense25DComparisonHudLayoutPlayModeTests
{
private Defense25DComparison world;
private Defense25DComparisonSettings settings;
private Camera projectionCamera;
private const string SettingsPath = "Assets/_Project/Constants/Defense25DComparison/ComparisonSettings.asset";
[UnitySetUp]
public IEnumerator SetUp()
{
settings = Object.Instantiate(AssetDatabase.LoadAssetAtPath<Defense25DComparisonSettings>(SettingsPath));
Assert.That(settings, Is.Not.Null);
settings.Enemy = AssetDatabase.LoadAssetAtPath<BumpCombat.Enemies.EnemyDefinition>(
"Assets/_Project/Constants/Enemies/Slime.asset");
world = new GameObject("HUD geometry world").AddComponent<Defense25DComparison>();
world.Initialize(settings);
GameObject cameraObject = new("HUD pad projection camera");
projectionCamera = cameraObject.AddComponent<Camera>();
projectionCamera.orthographic = true;
projectionCamera.orthographicSize = settings.CameraSize;
projectionCamera.aspect = (float)Defense25DView.Width / Defense25DView.Height;
Rect viewport = Defense25DView.GetViewport(Screen.width, Screen.height);
projectionCamera.rect = new Rect(viewport.x / Screen.width, viewport.y / Screen.height,
viewport.width / Screen.width, viewport.height / Screen.height);
projectionCamera.transform.SetPositionAndRotation(
new Vector3(0f, 13f, -11f), Quaternion.Euler(settings.CameraPitch, 0f, 0f));
yield return null;
}
[UnityTearDown]
public IEnumerator TearDown()
{
if (world != null) Object.Destroy(world.gameObject);
if (projectionCamera != null) Object.Destroy(projectionCamera.gameObject);
if (settings != null) Object.Destroy(settings);
yield return null;
}
[UnityTest]
public IEnumerator PersistentHudControlsLeaveAllSixProjectedPadsClearAndConsumeOnlyTheirDrawnRegions()
{
Rect viewport = Defense25DView.GetViewport(Screen.width, Screen.height);
float scale = viewport.width / Defense25DView.Width;
Rect[] controls = world.GetPersistentDefenseUiHitRects();
Assert.That(controls, Is.Not.Empty);
for (int pad = 0; pad < 6; pad++)
{
Vector2 ground = GameplayConstants.Current.Defense.GetBuildPadPosition(pad);
Vector3 screen = projectionCamera.WorldToScreenPoint(
new Vector3(ground.x, settings.GroundY, ground.y));
Vector2 gui = new((screen.x - viewport.x) / scale,
(Screen.height - screen.y - viewport.y) / scale);
Rect padFootprint = new(gui.x - 14f, gui.y - 14f, 28f, 28f);
Assert.That(controls.Any(control => control.Overlaps(padFootprint)), Is.False,
$"Persistent HUD control covers projected pad {pad + 1} at {gui}.");
Assert.That(world.IsPointerOverDefenseUI(ScreenPoint(viewport, scale, gui)), Is.False,
$"A click on projected pad {pad + 1} is incorrectly captured by the HUD.");
}
foreach (Rect control in controls)
{
Vector2 center = control.center;
Assert.That(world.IsPointerOverDefenseUI(ScreenPoint(viewport, scale, center)), Is.True,
$"Drawn HUD control at {center} is not protected from combat input.");
}
Rect noDetails = world.GetSelectedPadDetailsRect();
Assert.That(noDetails.width <= 0f || noDetails.height <= 0f, Is.True,
"Detailed construction controls should not occupy arena space before a pad is selected.");
Assert.That(world.SelectBuildPad(0), Is.True);
Rect details = world.GetSelectedPadDetailsRect();
Assert.That(details.width, Is.GreaterThan(0f));
Assert.That(details.height, Is.GreaterThan(0f));
Assert.That(world.IsPointerOverDefenseUI(ScreenPoint(viewport, scale, details.center)), Is.True,
"The contextual detail panel's click area must match its drawn panel.");
yield return null;
}
private static Vector2 ScreenPoint(Rect viewport, float scale, Vector2 gui) =>
new(viewport.x + gui.x * scale,
Screen.height - (viewport.y + gui.y * scale));
}
}