Files
tiny_tackle_heroes/Assets/_Project/Tests/PlayMode/GuardSystemPlayModeTests.cs
T

686 lines
28 KiB
C#

using System.Collections;
using System.Reflection;
using BumpCombat.Core;
using BumpCombat.Enemies;
using BumpCombat.Player;
using BumpCombat.Progression;
using BumpCombat.Spawning;
using BumpCombat.UI;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.LowLevel;
using UnityEngine.SceneManagement;
using UnityEngine.TestTools;
namespace BumpCombat.PlayModeTests
{
public sealed class GuardSystemPlayModeTests
{
private Keyboard virtualKeyboard;
private InputSettings.BackgroundBehavior previousBackgroundBehavior;
private InputSettings.EditorInputBehaviorInPlayMode previousEditorInputBehavior;
private bool previousRunInBackground;
private bool inputSettingsCaptured;
[SetUp]
public void SetUp()
{
ArtifactRewardController.GrantCatalogForTests = true;
RunManager.ForceProductionModeForTests = false;
Time.timeScale = 1f;
}
[TearDown]
public void TearDown()
{
if (virtualKeyboard != null && virtualKeyboard.added)
{
InputSystem.QueueStateEvent(virtualKeyboard, new KeyboardState());
InputSystem.RemoveDevice(virtualKeyboard);
}
virtualKeyboard = null;
if (inputSettingsCaptured)
{
InputSystem.settings.backgroundBehavior = previousBackgroundBehavior;
InputSystem.settings.editorInputBehaviorInPlayMode =
previousEditorInputBehavior;
Application.runInBackground = previousRunInBackground;
inputSettingsCaptured = false;
}
ArtifactRewardController.GrantCatalogForTests = false;
RunManager.ForceProductionModeForTests = false;
Time.timeScale = 1f;
}
[UnityTest]
public IEnumerator DInput_ActivatesGuardAndBlocksDamageWithoutHurtOrKnockback()
{
yield return LoadCombatPrototype();
DisableCombatActors();
EnsureRunStarted();
Keyboard keyboard = BeginVirtualKeyboardInput();
PlayerHealth health = FindHealth();
float startingHealth = health.CurrentHealth;
bool damageEventRaised = false;
health.OnDamageTaken += _ => damageEventRaised = true;
InputSystem.QueueStateEvent(keyboard, new KeyboardState(Key.D));
yield return null;
Assert.That(health.IsGuarding, Is.True);
Assert.That(health.GuardCooldownRemaining, Is.EqualTo(10f).Within(0.05f));
Assert.That(health.GuardCooldownNormalized, Is.EqualTo(1f).Within(0.01f));
Assert.That(health.GuardReadinessNormalized, Is.EqualTo(0f).Within(0.01f));
Assert.That(
health.TryTakeDamage(25f, Vector2.right, 1.1f),
Is.False);
Assert.That(health.CurrentHealth, Is.EqualTo(startingHealth));
Assert.That(health.IsHurtMovementLocked, Is.False);
Assert.That(health.GetComponent<PlayerController>().IsDamageKnockbackActive,
Is.False);
Assert.That(damageEventRaised, Is.False);
InputSystem.QueueStateEvent(keyboard, new KeyboardState());
yield return new WaitForSeconds(health.GuardDuration + 0.05f);
Assert.That(health.IsGuarding, Is.False);
Assert.That(health.TryTakeDamage(1f, Vector2.zero, 0f), Is.True);
Assert.That(health.CurrentHealth, Is.LessThan(startingHealth));
Assert.That(health.IsHurtMovementLocked, Is.True);
}
[UnityTest]
public IEnumerator Guard_DefaultDurationRemainsActiveAtPointSixSecondsThenExpires()
{
yield return LoadCombatPrototype();
DisableCombatActors();
EnsureRunStarted();
PlayerHealth health = FindHealth();
Assert.That(health.GuardDuration,
Is.EqualTo(PlayerHealth.DefaultGuardDuration));
Assert.That(health.GuardDuration, Is.EqualTo(1f));
Assert.That(health.TryActivateGuard(), Is.True);
yield return new WaitForSeconds(0.6f);
Assert.That(health.IsGuarding, Is.True,
"The default one-second guard must still be active after 0.6 seconds.");
yield return new WaitForSeconds(health.GuardDuration - 0.6f + 0.05f);
Assert.That(health.IsGuarding, Is.False,
"The default guard must expire after its one-second duration.");
}
[UnityTest]
public IEnumerator DInput_ActivatesBeforeDamageInTheSameInputUpdate()
{
yield return LoadCombatPrototype();
DisableCombatActors();
EnsureRunStarted();
Keyboard keyboard = BeginVirtualKeyboardInput();
PlayerHealth health = FindHealth();
float startingHealth = health.CurrentHealth;
InputSystem.QueueStateEvent(keyboard, new KeyboardState(Key.D));
InputSystem.Update();
Assert.That(
health.TryTakeDamage(25f, Vector2.right, 1.1f),
Is.False,
"A same-frame attack must see D's processed input edge before health.Update runs.");
Assert.That(health.CurrentHealth, Is.EqualTo(startingHealth));
Assert.That(health.IsGuarding, Is.True);
Assert.That(health.IsHurtMovementLocked, Is.False);
Assert.That(health.GetComponent<PlayerController>().IsDamageKnockbackActive,
Is.False);
}
[UnityTest]
public IEnumerator GuardImpactSignal_OnlyFiresForPositiveGuardBlockedDamage()
{
yield return LoadCombatPrototype();
DisableCombatActors();
EnsureRunStarted();
PlayerHealth health = FindHealth();
int guardBlockedCount = 0;
int guardImpactCount = 0;
Vector2 impactDirection = Vector2.zero;
float artifactGaugeBefore =
health.GetComponent<ActiveArtifactController>().CurrentGauge;
health.OnGuardAttackBlocked += _ => guardBlockedCount++;
health.OnGuardImpact += direction =>
{
guardImpactCount++;
impactDirection = direction;
};
Assert.That(health.TryActivateGuard(), Is.True);
Assert.That(
health.GuardSuccessCooldownRechargePercent,
Is.EqualTo(PlayerHealth.DefaultGuardSuccessCooldownRechargePercent));
Assert.That(health.TryTakeDamage(0f, Vector2.left, 1.1f), Is.False);
Assert.That(guardBlockedCount, Is.Zero);
Assert.That(guardImpactCount, Is.Zero);
Assert.That(health.GuardCooldownRemaining,
Is.EqualTo(health.GuardCooldownDuration).Within(0.05f));
Assert.That(
health.TryTakeDamage(25f, new Vector2(3f, 4f), 1.1f),
Is.False);
Assert.That(guardBlockedCount, Is.EqualTo(1));
Assert.That(guardImpactCount, Is.EqualTo(1));
Assert.That(impactDirection, Is.EqualTo(new Vector2(0.6f, 0.8f)));
float cooldownAfterFirstBlock = health.GuardCooldownRemaining;
Assert.That(cooldownAfterFirstBlock,
Is.EqualTo(health.GuardCooldownDuration * 0.3f).Within(0.05f));
Assert.That(health.GuardReadinessNormalized,
Is.EqualTo(0.7f).Within(0.01f));
Assert.That(health.TryTakeDamage(0f, Vector2.left, 1.1f), Is.False);
Assert.That(guardBlockedCount, Is.EqualTo(1));
Assert.That(guardImpactCount, Is.EqualTo(1));
Assert.That(health.TryTakeDamage(25f, Vector2.left, 1.1f), Is.False);
Assert.That(guardBlockedCount, Is.EqualTo(2));
Assert.That(guardImpactCount, Is.EqualTo(2));
Assert.That(health.GuardCooldownRemaining,
Is.EqualTo(cooldownAfterFirstBlock).Within(0.05f),
"Only the first positive-damage block in an activation recharges the guard.");
Assert.That(
health.GetComponent<ActiveArtifactController>().CurrentGauge,
Is.EqualTo(artifactGaugeBefore),
"Guard readiness is independent from the shared artifact gauge.");
health.GrantInvulnerability(health.GuardDuration + 0.5f);
yield return new WaitForSeconds(health.GuardDuration + 0.05f);
Assert.That(health.IsGuarding, Is.False);
Assert.That(health.IsInvulnerable, Is.True);
Assert.That(health.TryTakeDamage(25f, Vector2.left, 1.1f), Is.False);
Assert.That(guardBlockedCount, Is.EqualTo(2));
Assert.That(guardImpactCount, Is.EqualTo(2));
}
[UnityTest]
public IEnumerator GuardRecharge_UsesConfiguredPercentOncePerActivationAndClampsToReady()
{
yield return LoadCombatPrototype();
DisableCombatActors();
EnsureRunStarted();
PlayerHealth health = FindHealth();
SetPrivateField(health, "guardCooldownDuration", 0.4f);
SetPrivateField(health, "guardSuccessCooldownRechargePercent", 25f);
Assert.That(health.TryActivateGuard(), Is.True);
Assert.That(
health.TryTakeDamage(25f, Vector2.right, 1.1f),
Is.False);
Assert.That(health.GuardCooldownRemaining,
Is.EqualTo(0.3f).Within(0.05f));
Assert.That(health.TryTakeDamage(25f, Vector2.left, 1.1f), Is.False);
Assert.That(health.GuardCooldownRemaining,
Is.EqualTo(0.3f).Within(0.05f),
"Repeated blocks in one activation must not recharge again.");
yield return new WaitForSeconds(health.GuardDuration + 0.05f);
Assert.That(health.IsGuarding, Is.False);
Assert.That(health.TryActivateGuard(), Is.True,
"A new activation is available after its configured cooldown has elapsed.");
SetPrivateField(health, "guardSuccessCooldownRechargePercent", 0f);
Assert.That(
health.TryTakeDamage(25f, Vector2.right, 1.1f),
Is.False);
Assert.That(health.GuardCooldownRemaining,
Is.EqualTo(health.GuardCooldownDuration).Within(0.05f),
"A zero-percent setting must leave the cooldown unchanged.");
yield return new WaitForSeconds(health.GuardDuration + 0.05f);
Assert.That(health.TryActivateGuard(), Is.True);
SetPrivateField(health, "guardSuccessCooldownRechargePercent", 100f);
Assert.That(
health.TryTakeDamage(25f, Vector2.right, 1.1f),
Is.False);
Assert.That(health.GuardCooldownRemaining, Is.EqualTo(0f).Within(0.01f));
Assert.That(health.GuardReadinessNormalized, Is.EqualTo(1f).Within(0.01f));
Assert.That(health.IsGuarding, Is.True,
"Cooldown recharge must not end the current guard window.");
Assert.That(health.TryActivateGuard(), Is.False,
"A ready cooldown must not allow a second guard during the active window.");
}
[UnityTest]
public IEnumerator Guard_BlocksRealMeleeAndProjectileHitsDuringActiveWindow()
{
yield return LoadCombatPrototype();
EnsureRunStarted();
SpawnDirector director = Object.FindAnyObjectByType<SpawnDirector>();
PlayerHealth health = FindHealth();
Assert.That(director, Is.Not.Null);
director.enabled = false;
DisableCombatActors();
Rigidbody2D playerBody = health.GetComponent<Rigidbody2D>();
Assert.That(playerBody, Is.Not.Null);
playerBody.position = new Vector2(3f, 0f);
Physics2D.SyncTransforms();
EnemyController prefab = FindCatalogPrefab(director, EnemyKind.Skeleton);
Assert.That(prefab, Is.Not.Null);
GameObject instance = Object.Instantiate(
prefab.gameObject,
new Vector2(-2f, 0f),
Quaternion.identity);
EnemyController enemy = instance.GetComponent<EnemyController>();
EnemyAttack attack = instance.GetComponent<EnemyAttack>();
Assert.That(enemy, Is.Not.Null);
Assert.That(attack, Is.Not.Null);
yield return null;
enemy.enabled = false;
Assert.That(health.TryActivateGuard(), Is.True);
float startingHealth = health.CurrentHealth;
attack.BeginWarning(Vector2.right, health.transform.position, 0.7f);
attack.Activate();
playerBody.position = new Vector2(-1.5f, 0f);
Physics2D.SyncTransforms();
attack.TickActive(0.05f);
Assert.That(health.IsGuarding, Is.True);
Assert.That(health.CurrentHealth, Is.EqualTo(startingHealth));
Assert.That(health.IsHurtMovementLocked, Is.False);
Assert.That(health.GetComponent<PlayerController>().IsDamageKnockbackActive,
Is.False);
attack.EndAttack(cancelled: true);
enemy.enabled = true;
Collider2D playerCollider = health.GetComponent<Collider2D>();
Assert.That(playerCollider, Is.Not.Null);
Vector2 playerHitPoint = playerCollider.bounds.center;
EnemyProjectile projectile = EnemyProjectile.Launch(
enemy,
playerHitPoint - Vector2.right * 2f,
Vector2.right,
25f,
500f,
10f,
0.06f,
false);
int projectileFrames = 0;
while (projectile != null && projectileFrames++ < 10)
{
yield return null;
}
Assert.That(
projectile == null,
Is.True,
"The projectile should hit and resolve.");
Assert.That(health.IsGuarding, Is.True);
Assert.That(health.CurrentHealth, Is.EqualTo(startingHealth));
Assert.That(health.IsHurtMovementLocked, Is.False);
Assert.That(health.GetComponent<PlayerController>().IsDamageKnockbackActive,
Is.False);
enemy.enabled = false;
yield return new WaitForSeconds(health.GuardDuration + 0.05f);
Assert.That(health.IsGuarding, Is.False);
float healthBeforeUnguardedMelee = health.CurrentHealth;
attack.BeginWarning(Vector2.right, health.transform.position, 0.7f);
attack.Activate();
attack.TickActive(0.05f);
Assert.That(
health.CurrentHealth,
Is.LessThan(healthBeforeUnguardedMelee),
"The same melee setup must deal damage after guard expires.");
attack.EndAttack(cancelled: true);
Object.Destroy(instance);
}
[UnityTest]
public IEnumerator DamageInvulnerability_ProtectsHurtRecoveryAndExpiresAfterOneSecond()
{
yield return LoadCombatPrototype();
DisableCombatActors();
EnsureRunStarted();
PlayerHealth health = FindHealth();
float startingHealth = health.CurrentHealth;
Assert.That(health.TryTakeDamage(1f, Vector2.zero, 0f), Is.True);
float damageTime = Time.time;
while (Time.time < damageTime + 0.51f)
{
yield return null;
}
Assert.That(health.IsHurtMovementLocked, Is.False);
Assert.That(health.IsInvulnerable, Is.True);
Assert.That(health.TryTakeDamage(1f, Vector2.zero, 0f), Is.False);
Assert.That(health.CurrentHealth, Is.EqualTo(startingHealth - 1f));
while (Time.time < damageTime + health.InvulnerabilityDuration + 0.05f)
{
yield return null;
}
Assert.That(health.IsInvulnerable, Is.False);
Assert.That(health.TryTakeDamage(1f, Vector2.zero, 0f), Is.True);
Assert.That(health.CurrentHealth, Is.EqualTo(startingHealth - 2f));
}
[UnityTest]
public IEnumerator DamageInvulnerability_AllowsMovementAndArtifactAfterHurtUnlock()
{
yield return LoadCombatPrototype();
DisableCombatActors();
EnsureRunStarted();
Keyboard keyboard = BeginVirtualKeyboardInput();
PlayerController player = FindHealth().GetComponent<PlayerController>();
PlayerHealth health = player.GetComponent<PlayerHealth>();
ActiveArtifactController artifacts =
player.GetComponent<ActiveArtifactController>();
Rigidbody2D body = player.GetComponent<Rigidbody2D>();
Assert.That(health.TryTakeDamage(1f, Vector2.zero, 0f), Is.True);
while (health.IsHurtMovementLocked)
{
yield return null;
}
Vector2 positionBeforeMovement = body.position;
InputSystem.QueueStateEvent(keyboard, new KeyboardState(Key.RightArrow));
yield return new WaitForFixedUpdate();
yield return new WaitForFixedUpdate();
InputSystem.QueueStateEvent(keyboard, new KeyboardState());
Assert.That(body.position.x, Is.GreaterThan(positionBeforeMovement.x));
Assert.That(health.IsInvulnerable, Is.True);
Assert.That(artifacts.TryUseCurrent(false), Is.True);
}
[UnityTest]
public IEnumerator Guard_CooldownStartsOnActivationAndRejectsReactivation()
{
yield return LoadCombatPrototype();
DisableCombatActors();
EnsureRunStarted();
PlayerHealth health = FindHealth();
Assert.That(health.GuardCooldownRemaining, Is.EqualTo(0f));
Assert.That(health.TryActivateGuard(), Is.True);
Assert.That(health.TryActivateGuard(), Is.False);
Assert.That(health.GuardCooldownRemaining, Is.GreaterThan(9.9f));
yield return null;
Assert.That(health.GuardCooldownRemaining, Is.LessThan(10f));
Assert.That(health.GuardCooldownRemaining, Is.GreaterThan(9.8f));
}
[UnityTest]
public IEnumerator ProductionGuard_UnlocksWithRunManagerAndBecomesReadyImmediately()
{
ArtifactRewardController.GrantCatalogForTests = false;
yield return LoadCombatPrototype();
DisableCombatActors();
RunManager runManager = RunManager.Instance;
PlayerHealth health = FindHealth();
RunTutorialController tutorials =
Object.FindAnyObjectByType<RunTutorialController>();
Assert.That(runManager, Is.Not.Null);
Assert.That(tutorials, Is.Not.Null);
Assert.That(runManager.IsTitleScreen, Is.True);
Assert.That(runManager.BeginRun(RunMode.Production), Is.True);
Assert.That(runManager.IsProductionRun, Is.True);
Assert.That(runManager.IsGuardUnlocked, Is.False);
Assert.That(health.IsGuardAvailable, Is.False);
Assert.That(health.IsGuarding, Is.False);
Assert.That(health.GuardReadinessNormalized, Is.EqualTo(0f).Within(0.01f));
Assert.That(health.TryActivateGuard(), Is.False);
runManager.UnlockGuard();
Assert.That(runManager.IsGuardUnlocked, Is.True);
Assert.That(health.IsGuardAvailable, Is.True);
Assert.That(health.GuardReadinessNormalized, Is.EqualTo(1f));
Assert.That(tutorials.DebugIsVisible, Is.True);
Assert.That(tutorials.DebugCurrentTutorial,
Is.EqualTo(RunTutorialController.TutorialKind.Guard));
Assert.That(health.TryActivateGuard(), Is.False,
"The guard tutorial modal must keep gameplay input locked until continued.");
Assert.That(tutorials.DebugContinue(), Is.True);
Assert.That(health.TryActivateGuard(), Is.True);
Assert.That(health.GuardReadinessNormalized, Is.EqualTo(0f).Within(0.0001f));
}
[UnityTest]
public IEnumerator Guard_HeldInputDoesNotRepeatAfterCooldownAndRepressActivates()
{
yield return LoadCombatPrototype();
DisableCombatActors();
EnsureRunStarted();
Keyboard keyboard = BeginVirtualKeyboardInput();
PlayerHealth health = FindHealth();
InputSystem.QueueStateEvent(keyboard, new KeyboardState(Key.D));
yield return null;
Assert.That(health.IsGuarding, Is.True);
Time.timeScale = 10f;
float deadline = Time.realtimeSinceStartup + 2f;
while (health.GuardCooldownRemaining > 0.1f
&& Time.realtimeSinceStartup < deadline)
{
yield return null;
}
Assert.That(health.GuardCooldownRemaining, Is.LessThanOrEqualTo(0.1f));
Assert.That(health.IsGuarding, Is.False);
Time.timeScale = 1f;
while (health.GuardCooldownRemaining > 0f)
{
yield return null;
}
Assert.That(health.IsGuarding, Is.False);
InputSystem.QueueStateEvent(keyboard, new KeyboardState());
yield return null;
InputSystem.QueueStateEvent(keyboard, new KeyboardState(Key.D));
yield return null;
Assert.That(health.IsGuarding, Is.True);
}
[UnityTest]
public IEnumerator Guard_OverlapsIndependentGrantInvulnerabilityWithoutHurtLock()
{
yield return LoadCombatPrototype();
DisableCombatActors();
EnsureRunStarted();
PlayerHealth health = FindHealth();
Assert.That(health.TryActivateGuard(), Is.True);
health.GrantInvulnerability(health.GuardDuration + 0.5f);
Assert.That(health.IsHurtMovementLocked, Is.False);
yield return new WaitForSeconds(health.GuardDuration + 0.05f);
Assert.That(health.IsGuarding, Is.False);
Assert.That(health.IsInvulnerable, Is.True);
yield return new WaitForSeconds(0.5f);
Assert.That(health.IsInvulnerable, Is.False);
}
[UnityTest]
public IEnumerator Guard_IsUnavailableDuringHurtPauseAndAfterDeath()
{
yield return LoadCombatPrototype();
DisableCombatActors();
EnsureRunStarted();
Keyboard keyboard = BeginVirtualKeyboardInput();
PlayerHealth health = FindHealth();
Assert.That(health.TryTakeDamage(1f, Vector2.zero, 0f), Is.True);
Assert.That(health.IsHurtMovementLocked, Is.True);
Assert.That(health.TryActivateGuard(), Is.False);
yield return new WaitForSeconds(health.InvulnerabilityDuration + 0.05f);
Assert.That(health.IsHurtMovementLocked, Is.False);
Assert.That(RunManager.Instance.TryOpenPause(), Is.True);
InputSystem.QueueStateEvent(keyboard, new KeyboardState(Key.D));
yield return null;
Assert.That(health.IsGuarding, Is.False);
Assert.That(RunManager.Instance.ClosePause(), Is.True);
InputSystem.QueueStateEvent(keyboard, new KeyboardState());
yield return null;
Assert.That(
health.TryTakeDamage(health.CurrentHealth + 1f, Vector2.zero, 0f),
Is.True);
Assert.That(health.CurrentHealth, Is.Zero);
Assert.That(health.TryActivateGuard(), Is.False);
}
[UnityTest]
public IEnumerator Guard_TimersPauseWithScaledGameTime()
{
yield return LoadCombatPrototype();
DisableCombatActors();
EnsureRunStarted();
PlayerHealth health = FindHealth();
Assert.That(health.TryActivateGuard(), Is.True);
Assert.That(RunManager.Instance.TryOpenPause(), Is.True);
yield return new WaitForSecondsRealtime(0.7f);
Assert.That(health.IsGuarding, Is.True);
Assert.That(health.GuardCooldownRemaining, Is.GreaterThan(9.8f));
Assert.That(RunManager.Instance.ClosePause(), Is.True);
yield return new WaitForSeconds(health.GuardDuration + 0.05f);
Assert.That(health.IsGuarding, Is.False);
}
[UnityTest]
public IEnumerator Guard_DisablingClearsActiveGuardWithoutResettingCooldown()
{
yield return LoadCombatPrototype();
DisableCombatActors();
EnsureRunStarted();
PlayerHealth health = FindHealth();
Assert.That(health.TryActivateGuard(), Is.True);
health.enabled = false;
Assert.That(health.IsGuarding, Is.False);
float remainingCooldown = health.GuardCooldownRemaining;
Assert.That(remainingCooldown, Is.GreaterThan(9.8f));
health.enabled = true;
Assert.That(health.IsGuarding, Is.False);
Assert.That(health.TryActivateGuard(), Is.False);
yield return null;
}
private static PlayerHealth FindHealth()
{
PlayerHealth health = Object.FindAnyObjectByType<PlayerHealth>();
Assert.That(health, Is.Not.Null);
return health;
}
private static void SetPrivateField(object target, string fieldName, object value)
{
FieldInfo field = target.GetType().GetField(
fieldName,
BindingFlags.Instance | BindingFlags.NonPublic);
Assert.That(field, Is.Not.Null, $"Expected private field '{fieldName}'.");
field.SetValue(target, value);
}
private static EnemyController FindCatalogPrefab(
SpawnDirector director,
EnemyKind kind)
{
string[] fieldNames =
{
"enemyPrefabs",
"elitePrefabs",
"midBossPrefabs",
"finalBossPrefabs",
};
foreach (string fieldName in fieldNames)
{
FieldInfo field = typeof(SpawnDirector).GetField(
fieldName,
BindingFlags.Instance | BindingFlags.NonPublic);
EnemyController[] prefabs = field?.GetValue(director) as EnemyController[];
if (prefabs == null)
{
continue;
}
foreach (EnemyController prefab in prefabs)
{
if (prefab != null
&& prefab.Definition != null
&& prefab.Definition.Kind == kind)
{
return prefab;
}
}
}
return null;
}
private static void EnsureRunStarted()
{
RunManager runManager = RunManager.Instance;
Assert.That(runManager, Is.Not.Null);
if (runManager.IsTitleScreen)
{
Assert.That(runManager.BeginRun(), Is.True);
}
}
private Keyboard BeginVirtualKeyboardInput()
{
inputSettingsCaptured = true;
previousBackgroundBehavior = InputSystem.settings.backgroundBehavior;
previousEditorInputBehavior =
InputSystem.settings.editorInputBehaviorInPlayMode;
previousRunInBackground = Application.runInBackground;
InputSystem.settings.backgroundBehavior =
InputSettings.BackgroundBehavior.IgnoreFocus;
InputSystem.settings.editorInputBehaviorInPlayMode =
InputSettings.EditorInputBehaviorInPlayMode.AllDeviceInputAlwaysGoesToGameView;
Application.runInBackground = true;
virtualKeyboard = InputSystem.AddDevice<Keyboard>();
virtualKeyboard.MakeCurrent();
return virtualKeyboard;
}
private static void DisableCombatActors()
{
SpawnDirector director = Object.FindAnyObjectByType<SpawnDirector>();
if (director != null)
{
director.enabled = false;
}
foreach (EnemyController enemy in Object.FindObjectsByType<EnemyController>(
FindObjectsSortMode.None))
{
enemy.gameObject.SetActive(false);
}
}
private static IEnumerator LoadCombatPrototype()
{
AsyncOperation load = SceneManager.LoadSceneAsync("CombatPrototype");
while (!load.isDone)
{
yield return null;
}
yield return null;
yield return null;
}
}
}