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

181 lines
8.0 KiB
C#

using System.Collections;
using System.Linq;
using BumpCombat.Constants;
using BumpCombat.Defense.Comparison;
using BumpCombat.Player;
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
using UnityEngine.TestTools;
using Object = UnityEngine.Object;
namespace BumpCombat.Tests
{
public sealed class Defense25DPlayerArtPlayModeTests
{
private const string SettingsPath =
"Assets/_Project/Constants/Defense25DComparison/ComparisonSettings.asset";
private Defense25DComparison world;
private Defense25DComparisonSettings settings;
private Defense25DPlayerArt playerArt;
[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");
settings.PlayerArt = ReadCharacter("Swordsman", "Swordsman", "BumpAttack-v1");
settings.EnemyArt = ReadCharacter("Slime", "Slime", "Attack");
world = new GameObject("2.5D player art test world")
.AddComponent<Defense25DComparison>();
world.Initialize(settings);
world.AutoSpawn = false;
world.ReadInput = false;
playerArt = world.Player.gameObject.AddComponent<Defense25DPlayerArt>();
playerArt.Bind(world);
yield return null;
}
[UnityTearDown]
public IEnumerator TearDown()
{
if (world != null) Object.Destroy(world.gameObject);
if (settings != null) Object.Destroy(settings);
yield return null;
}
[UnityTest]
public IEnumerator EquipmentSprite_UsesMatchingExistingFramesForEachPaletteAndRestores()
{
ActiveArtifactEffect[] effects =
{
ActiveArtifactEffect.Dash,
ActiveArtifactEffect.Pulse,
ActiveArtifactEffect.ChainLightning,
};
SpriteRenderer body = world.Player.Visual.Renderer;
for (int i = 0; i < effects.Length; i++)
{
ActiveArtifactDefinition definition = world.Loadout.FindArtifact(effects[i]);
Assert.That(definition, Is.Not.Null, effects[i].ToString());
Assert.That(world.Loadout.TryAddArtifact(definition), Is.True);
Assert.That(world.Loadout.Select(i), Is.True);
yield return null;
Sprite tinted = body.sprite;
Assert.That(tinted, Is.Not.Null);
Assert.That(tinted.texture.name,
Is.EqualTo("Swordsman_Idle-" + definition.ArtifactColor + "-v1"));
Sprite original = settings.PlayerArt.Idle.FirstOrDefault(
frame => frame.rect == tinted.rect);
Assert.That(original, Is.Not.Null);
Assert.That(tinted.rect, Is.EqualTo(original.rect));
Assert.That(tinted.pivot, Is.EqualTo(original.pivot));
Assert.That(tinted.pixelsPerUnit, Is.EqualTo(original.pixelsPerUnit));
playerArt.ResetVisuals();
Assert.That(body.sprite.texture.name, Is.EqualTo("Swordsman_Idle"));
}
}
[UnityTest]
public IEnumerator PrecoloredSequenceFrame_IsResolvedToBaseForSelectedPalette()
{
Sprite[] blueFrames = Resources.LoadAll<Sprite>(
"Artifacts/ThreeColor-v1/Player/Swordsman_Idle-Blue-v1");
Sprite blueFrame = blueFrames.FirstOrDefault(frame =>
settings.PlayerArt.Idle.Any(original => original.rect == frame.rect));
Assert.That(blueFrame, Is.Not.Null);
ActiveArtifactDefinition red = world.Loadout.FindArtifact(ActiveArtifactEffect.Pulse);
Assert.That(red, Is.Not.Null);
Assert.That(world.Loadout.TryAddArtifact(red), Is.True);
Assert.That(world.Loadout.Select(0), Is.True);
world.Player.Visual.Renderer.sprite = blueFrame;
yield return null;
Sprite recolored = world.Player.Visual.Renderer.sprite;
Assert.That(recolored.texture.name, Is.EqualTo("Swordsman_Idle-Red-v1"));
Assert.That(recolored.rect, Is.EqualTo(blueFrame.rect));
Assert.That(recolored.rect, Is.EqualTo(settings.PlayerArt.Idle
.First(original => original.rect == blueFrame.rect).rect));
playerArt.ResetVisuals();
Assert.That(world.Player.Visual.Renderer.sprite.texture.name, Is.EqualTo("Swordsman_Idle"));
}
[UnityTest]
public IEnumerator PrecoloredArtifactUseFrame_UsesBasePaletteAndGuardMaskKeys()
{
ActiveArtifactDefinition red = world.Loadout.FindArtifact(ActiveArtifactEffect.Pulse);
Assert.That(red, Is.Not.Null);
Assert.That(world.Loadout.TryAddArtifact(red), Is.True);
Assert.That(world.Loadout.Select(0), Is.True);
Sprite sequenceFrame = Resources.LoadAll<Sprite>(
"Artifacts/ThreeColor-v1/Player/Swordsman_ArtifactUse-v1-Blue-v1").First();
SpriteRenderer body = world.Player.Visual.Renderer;
body.sprite = sequenceFrame;
world.Player.Visual.enabled = false;
Assert.That(world.Player.TryActivateGuard(), Is.True);
yield return null;
SpriteRenderer outline = body.transform.Find("Player Guard Outline")
.GetComponent<SpriteRenderer>();
Assert.That(outline.enabled, Is.True);
Assert.That(outline.sprite.texture.name,
Is.EqualTo("Swordsman_ArtifactUse-v1-outline"));
Assert.That(outline.sprite.rect, Is.EqualTo(sequenceFrame.rect));
Assert.That(body.sprite.texture.name,
Is.EqualTo("Swordsman_ArtifactUse-v1-Red-v1"));
Assert.That(body.sprite.rect, Is.EqualTo(sequenceFrame.rect));
}
[UnityTest]
public IEnumerator DisabledWorld_DoesNotReapplyPaletteVisuals()
{
ActiveArtifactDefinition red = world.Loadout.FindArtifact(ActiveArtifactEffect.Pulse);
Assert.That(world.Loadout.TryAddArtifact(red), Is.True);
Assert.That(world.Loadout.Select(0), Is.True);
SpriteRenderer body = world.Player.Visual.Renderer;
Sprite original = settings.PlayerArt.Idle[0];
body.sprite = original;
world.enabled = false;
yield return null;
Assert.That(body.sprite, Is.SameAs(original));
world.enabled = true;
}
[UnityTest]
public IEnumerator UnguardedPlayer_HasNoOutlineAndResetRestoresSourceSprite()
{
SpriteRenderer body = world.Player.Visual.Renderer;
Assert.That(body.transform.Find("Player Guard Outline"), Is.Null,
"The art component has no local guard-state substitute; it follows the actor state.");
yield return null;
playerArt.ResetVisuals();
Assert.That(body.sprite.texture.name, Is.EqualTo("Swordsman_Idle"));
playerArt.enabled = false;
Assert.That(body.sprite.texture.name, Is.EqualTo("Swordsman_Idle"));
}
private static ComparisonSpriteFrames ReadCharacter(string folder, string prefix, string attack)
{
Sprite[] Read(string suffix) => AssetDatabase.LoadAllAssetsAtPath(
$"Assets/_Project/Art/Characters/{folder}/{prefix}_{suffix}.png")
.OfType<Sprite>()
.OrderBy(sprite => int.TryParse(
sprite.name[(sprite.name.LastIndexOf('_') + 1)..], out int frame) ? frame : 0)
.ToArray();
return new ComparisonSpriteFrames
{
Idle = Read("Idle"), Walk = Read("Walk"), Attack = Read(attack),
Hurt = Read("Hurt"), Death = Read("Death"),
};
}
}
}