测试修复安卓打包

This commit is contained in:
2026-03-17 11:28:33 +08:00
parent 224db4cd5c
commit 59f1d02a18
23 changed files with 583 additions and 258 deletions
@@ -95,20 +95,11 @@ namespace Simulation.Tests.PlayMode
private static readonly MethodInfo TryGetNearestEnemyEntityIdMethod =
SimulationWorldType?.GetMethod("TryGetNearestEnemyEntityId", PublicInstance);
private static readonly MethodInfo TryEnqueueAreaCollisionQueryMethod =
SimulationWorldType?.GetMethod("TryEnqueueAreaCollisionQuery", PublicInstance);
private static readonly MethodInfo TryRequestAreaCollisionMethod =
SimulationWorldType?.GetMethod("TryRequestAreaCollision", PublicInstance);
private static readonly MethodInfo SetUseSimulationMovementMethod =
SimulationWorldType?.GetMethod("SetUseSimulationMovement", PublicInstance);
private static readonly MethodInfo SetUseJobSimulationMethod =
SimulationWorldType?.GetMethod("SetUseJobSimulation", PublicInstance);
private static readonly MethodInfo SetUseBurstJobsMethod =
SimulationWorldType?.GetMethod("SetUseBurstJobs", PublicInstance);
private static readonly MethodInfo ClearMethod =
SimulationWorldType?.GetMethod("Clear", PublicInstance);
private static readonly MethodInfo ClearSimulationStateMethod =
SimulationWorldType?.GetMethod("ClearSimulationState", PublicInstance);
private static readonly MethodInfo UseGridBucketSolverMethod =
EnemySeparationSolverProviderType?.GetMethod("UseGridBucketSolver", PublicStatic);
@@ -116,8 +107,14 @@ namespace Simulation.Tests.PlayMode
private static readonly FieldInfo EntitySyncField =
SimulationWorldType?.GetField("_entitySync", NonPublicInstance);
private static readonly FieldInfo PresentationField =
SimulationWorldType?.GetField("_presentation", NonPublicInstance);
private static readonly FieldInfo TransformSyncField =
SimulationWorldType?.GetField("_transformSync", NonPublicInstance);
private static readonly FieldInfo HitPresentationField =
SimulationWorldType?.GetField("_hitPresentation", NonPublicInstance);
private static readonly FieldInfo UseSimulationMovementField =
SimulationWorldType?.GetField("_useSimulationMovement", NonPublicInstance);
private static readonly PropertyInfo EnemiesProperty =
SimulationWorldType?.GetProperty("Enemies", PublicInstance);
@@ -131,9 +128,6 @@ namespace Simulation.Tests.PlayMode
private static readonly PropertyInfo UseSimulationMovementProperty =
SimulationWorldType?.GetProperty("UseSimulationMovement", PublicInstance);
private static readonly PropertyInfo UseJobSimulationProperty =
SimulationWorldType?.GetProperty("UseJobSimulation", PublicInstance);
private static readonly PropertyInfo LastResolvedAreaHitCountProperty =
SimulationWorldType?.GetProperty("LastResolvedAreaHitCount", PublicInstance);
@@ -223,17 +217,14 @@ namespace Simulation.Tests.PlayMode
Assert.NotNull(TryGetEnemyDataMethod, "TryGetEnemyData reflection lookup failed.");
Assert.NotNull(TickMethod, "Tick reflection lookup failed.");
Assert.NotNull(TryGetNearestEnemyEntityIdMethod, "TryGetNearestEnemyEntityId reflection lookup failed.");
Assert.NotNull(TryEnqueueAreaCollisionQueryMethod, "TryEnqueueAreaCollisionQuery reflection lookup failed.");
Assert.NotNull(SetUseSimulationMovementMethod, "SetUseSimulationMovement reflection lookup failed.");
Assert.NotNull(SetUseJobSimulationMethod, "SetUseJobSimulation reflection lookup failed.");
Assert.NotNull(SetUseBurstJobsMethod, "SetUseBurstJobs reflection lookup failed.");
Assert.NotNull(ClearMethod, "Clear reflection lookup failed.");
Assert.NotNull(TryRequestAreaCollisionMethod, "TryRequestAreaCollision reflection lookup failed.");
Assert.NotNull(ClearSimulationStateMethod, "ClearSimulationState reflection lookup failed.");
Assert.NotNull(UseGridBucketSolverMethod, "UseGridBucketSolver reflection lookup failed.");
Assert.NotNull(EnemiesProperty, "Enemies property reflection lookup failed.");
Assert.NotNull(ProjectilesProperty, "Projectiles property reflection lookup failed.");
Assert.NotNull(CollisionCandidateCountProperty, "CollisionCandidateCount property reflection lookup failed.");
Assert.NotNull(UseSimulationMovementProperty, "UseSimulationMovement property reflection lookup failed.");
Assert.NotNull(UseJobSimulationProperty, "UseJobSimulation property reflection lookup failed.");
Assert.NotNull(UseSimulationMovementField, "_useSimulationMovement field reflection lookup failed.");
Assert.NotNull(LastResolvedAreaHitCountProperty, "LastResolvedAreaHitCount property reflection lookup failed.");
Assert.NotNull(CollisionQueryInputsField, "Collision query inputs field reflection lookup failed.");
Assert.NotNull(AreaCollisionRequestsField, "Area collision requests field reflection lookup failed.");
@@ -264,9 +255,10 @@ namespace Simulation.Tests.PlayMode
// Isolate PlayMode regression to simulation behavior only.
EntitySyncField?.SetValue(_worldComponent, null);
PresentationField?.SetValue(_worldComponent, null);
TransformSyncField?.SetValue(_worldComponent, null);
HitPresentationField?.SetValue(_worldComponent, null);
SetUseSimulationMovementMethod.Invoke(_worldComponent, new object[] { true });
SetUseSimulationMovement(true);
UseGridBucketSolverMethod.Invoke(null, new object[] { 1f });
yield return null;
}
@@ -277,7 +269,8 @@ namespace Simulation.Tests.PlayMode
if (_worldComponent != null)
{
EntitySyncField?.SetValue(_worldComponent, null);
PresentationField?.SetValue(_worldComponent, null);
TransformSyncField?.SetValue(_worldComponent, null);
HitPresentationField?.SetValue(_worldComponent, null);
}
if (_worldGameObject != null)
@@ -347,7 +340,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest]
public IEnumerator TickEnemies_ChasesPlayer_WhenJobSimulationChannelEnabled()
{
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 3201, position: Vector3.zero, speed: 2f, attackRange: 1f));
InvokeTick(deltaTime: 1f, realDeltaTime: 1f, playerPosition: new Vector3(10f, 0f, 0f));
@@ -363,10 +355,8 @@ namespace Simulation.Tests.PlayMode
}
[UnityTest]
public IEnumerator TickEnemies_MatchesOutput_WhenBurstJobsToggled()
public IEnumerator TickEnemies_MatchesOutput_AfterClearSimulationState()
{
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
SetUseBurstJobsMethod.Invoke(_worldComponent, new object[] { false });
UpsertEnemy(CreateEnemy(entityId: 3251, position: Vector3.zero, speed: 2f, attackRange: 1f));
InvokeTick(deltaTime: 1f, realDeltaTime: 1f, playerPosition: new Vector3(10f, 0f, 0f));
@@ -375,11 +365,9 @@ namespace Simulation.Tests.PlayMode
Vector3 nonBurstPosition = (Vector3)GetField(nonBurstEnemy, "Position");
Vector3 nonBurstForward = (Vector3)GetField(nonBurstEnemy, "Forward");
ClearMethod.Invoke(_worldComponent, null);
ClearSimulationStateMethod.Invoke(_worldComponent, null);
SetUseSimulationMovementMethod.Invoke(_worldComponent, new object[] { true });
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
SetUseBurstJobsMethod.Invoke(_worldComponent, new object[] { true });
SetUseSimulationMovement(true);
UpsertEnemy(CreateEnemy(entityId: 3251, position: Vector3.zero, speed: 2f, attackRange: 1f));
InvokeTick(deltaTime: 1f, realDeltaTime: 1f, playerPosition: new Vector3(10f, 0f, 0f));
@@ -397,7 +385,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest]
public IEnumerator TryGetNearestEnemyEntityId_SelectsNearestBucketCandidate_WhenJobSimulationEnabled()
{
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 3301, position: new Vector3(1f, 0f, 0f), speed: 0f, attackRange: 1f));
UpsertEnemy(CreateEnemy(entityId: 3302, position: new Vector3(6f, 0f, 0f), speed: 0f, attackRange: 1f));
@@ -415,7 +402,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest]
public IEnumerator TickEnemies_SeparatesOverlappedEnemies_WhenJobSimulationEnabled()
{
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 3401, position: new Vector3(0f, 0f, 0f), speed: 1f, attackRange: 0.1f,
avoidEnemyOverlap: true, enemyBodyRadius: 0.45f, separationIterations: 2));
UpsertEnemy(CreateEnemy(entityId: 3402, position: new Vector3(0.1f, 0f, 0f), speed: 1f, attackRange: 0.1f,
@@ -437,7 +423,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest]
public IEnumerator TickEnemies_SeparatesOverlappedEnemies_WhenPlayerIsStaticAndInRange()
{
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 3411, position: new Vector3(0f, 0f, 0f), speed: 1f, attackRange: 10f,
avoidEnemyOverlap: true, enemyBodyRadius: 0.45f, separationIterations: 3));
UpsertEnemy(CreateEnemy(entityId: 3412, position: new Vector3(0.05f, 0f, 0f), speed: 1f, attackRange: 10f,
@@ -462,7 +447,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest]
public IEnumerator TickProjectiles_MovesAndUpdatesLifetime_WhenJobSimulationEnabled()
{
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertProjectile(CreateProjectile(entityId: 5401, position: Vector3.zero, forward: Vector3.right,
velocity: new Vector3(2f, 0f, 0f), speed: 0f, lifeTime: 2f, age: 0f, active: true,
remainingLifetime: 2f, state: 0));
@@ -484,9 +468,8 @@ namespace Simulation.Tests.PlayMode
}
[UnityTest]
public IEnumerator TickProjectiles_ResumesFromLatestState_AfterTogglingJobSimulation()
public IEnumerator TickProjectiles_ContinuesFromLatestState_AcrossConsecutiveTicks()
{
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertProjectile(CreateProjectile(entityId: 5410, position: Vector3.zero, forward: Vector3.right,
velocity: new Vector3(2f, 0f, 0f), speed: 0f, lifeTime: 5f, age: 0f, active: true,
remainingLifetime: 5f, state: 0));
@@ -498,33 +481,24 @@ namespace Simulation.Tests.PlayMode
Assert.That(positionAfterJobEnabled.x, Is.EqualTo(1f).Within(0.0001f));
Assert.That(ageAfterJobEnabled, Is.EqualTo(0.5f).Within(0.0001f));
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { false });
InvokeTick(deltaTime: 0.5f, realDeltaTime: 0.5f, playerPosition: Vector3.zero);
object afterJobDisabled = GetProjectileAt(0);
Vector3 positionAfterJobDisabled = (Vector3)GetField(afterJobDisabled, "Position");
float ageAfterJobDisabled = (float)GetField(afterJobDisabled, "Age");
Assert.That(positionAfterJobDisabled.x, Is.EqualTo(1f).Within(0.0001f));
Assert.That(ageAfterJobDisabled, Is.EqualTo(0.5f).Within(0.0001f));
object afterSecondTick = GetProjectileAt(0);
Vector3 positionAfterSecondTick = (Vector3)GetField(afterSecondTick, "Position");
float ageAfterSecondTick = (float)GetField(afterSecondTick, "Age");
float remainingLifetimeAfterSecondTick = (float)GetField(afterSecondTick, "RemainingLifetime");
bool activeAfterSecondTick = (bool)GetField(afterSecondTick, "Active");
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
InvokeTick(deltaTime: 0.5f, realDeltaTime: 0.5f, playerPosition: Vector3.zero);
object afterJobReEnabled = GetProjectileAt(0);
Vector3 positionAfterJobReEnabled = (Vector3)GetField(afterJobReEnabled, "Position");
float ageAfterJobReEnabled = (float)GetField(afterJobReEnabled, "Age");
float remainingLifetimeAfterJobReEnabled = (float)GetField(afterJobReEnabled, "RemainingLifetime");
bool activeAfterJobReEnabled = (bool)GetField(afterJobReEnabled, "Active");
Assert.That(positionAfterJobReEnabled.x, Is.EqualTo(2f).Within(0.0001f));
Assert.That(ageAfterJobReEnabled, Is.EqualTo(1f).Within(0.0001f));
Assert.That(remainingLifetimeAfterJobReEnabled, Is.EqualTo(4f).Within(0.0001f));
Assert.IsTrue(activeAfterJobReEnabled);
Assert.That(positionAfterSecondTick.x, Is.EqualTo(2f).Within(0.0001f));
Assert.That(ageAfterSecondTick, Is.EqualTo(1f).Within(0.0001f));
Assert.That(remainingLifetimeAfterSecondTick, Is.EqualTo(4f).Within(0.0001f));
Assert.IsTrue(activeAfterSecondTick);
yield break;
}
[UnityTest]
public IEnumerator EnemyProjectile_TogglesCollider_WhenJobSimulationSwitchesAtRuntime()
public IEnumerator EnemyProjectile_TogglesCollider_WhenSimulationMovementSwitchesAtRuntime()
{
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { false });
SetUseSimulationMovement(false);
GameObject projectileObject = new GameObject("EnemyProjectileColliderTogglePlayMode");
Component projectileComponent = null;
@@ -553,11 +527,11 @@ namespace Simulation.Tests.PlayMode
InvokeEnemyProjectileUpdate(projectileComponent, 0.016f, 0.016f);
Assert.IsTrue(projectileCollider.enabled);
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
SetUseSimulationMovement(true);
InvokeEnemyProjectileUpdate(projectileComponent, 0.016f, 0.016f);
Assert.IsFalse(projectileCollider.enabled);
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { false });
SetUseSimulationMovement(false);
InvokeEnemyProjectileUpdate(projectileComponent, 0.016f, 0.016f);
Assert.IsTrue(projectileCollider.enabled);
}
@@ -603,7 +577,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest]
public IEnumerator TickProjectiles_RecyclesWhenExceedingPlayerDistance_WhenJobSimulationEnabled()
{
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
ProjectileMaxDistanceFromPlayerField.SetValue(_worldComponent, 5f);
ProjectileMaxVerticalOffsetFromPlayerField.SetValue(_worldComponent, 1000f);
UpsertProjectile(CreateProjectile(entityId: 5408, position: new Vector3(6f, 0f, 0f),
@@ -619,7 +592,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest]
public IEnumerator TickProjectiles_RecyclesWhenExceedingVerticalOffset_WhenJobSimulationEnabled()
{
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
ProjectileMaxDistanceFromPlayerField.SetValue(_worldComponent, 0f);
ProjectileMaxVerticalOffsetFromPlayerField.SetValue(_worldComponent, 1f);
UpsertProjectile(CreateProjectile(entityId: 5409, position: new Vector3(0f, 2f, 0f),
@@ -635,7 +607,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest]
public IEnumerator TickProjectiles_RecyclesExpiredProjectile_WhenJobSimulationEnabled()
{
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertProjectile(CreateProjectile(entityId: 5402, position: Vector3.zero, forward: Vector3.forward,
velocity: Vector3.zero, speed: 0f, lifeTime: 1f, age: 0.95f, active: true, remainingLifetime: 0.05f,
state: 0));
@@ -649,7 +620,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest]
public IEnumerator TickProjectiles_BuildsCollisionCandidatesAgainstEnemies_WhenJobSimulationEnabled()
{
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 5501, position: Vector3.zero, speed: 0f, attackRange: 1f));
UpsertProjectile(CreateProjectile(entityId: 5502, position: Vector3.zero, forward: Vector3.forward,
velocity: Vector3.zero, speed: 0f, lifeTime: 2f, age: 0f, active: true, remainingLifetime: 2f,
@@ -664,7 +634,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest]
public IEnumerator TickProjectiles_BuildsCollisionCandidates_WithLatestEnemyMovement_WhenJobSimulationEnabled()
{
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 5511, position: new Vector3(2f, 0f, 0f), speed: 1f, attackRange: 0.1f));
UpsertProjectile(CreateProjectile(entityId: 5512, position: new Vector3(1f, 0f, 0f),
forward: Vector3.forward, velocity: Vector3.zero, speed: 0f, lifeTime: 2f, age: 0f, active: true,
@@ -679,7 +648,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest]
public IEnumerator TickProjectiles_ExpiresAfterCollisionCandidateConsumed_WhenJobSimulationEnabled()
{
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 5503, position: Vector3.zero, speed: 0f, attackRange: 1f));
UpsertProjectile(CreateProjectile(entityId: 5504, position: Vector3.zero, forward: Vector3.forward,
velocity: Vector3.zero, speed: 0f, lifeTime: 10f, age: 0f, active: true, remainingLifetime: 10f,
@@ -694,7 +662,6 @@ namespace Simulation.Tests.PlayMode
[UnityTest]
public IEnumerator TickProjectiles_LimitsCandidatesToMaxTargets_IncludingPlayerCandidate()
{
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
object previousEnemyManager = GetGameEntryEnemyManager();
GameObject enemyManagerObject = new GameObject("EnemyManagerMaxTargetsPlayMode");
GameObject playerObject = new GameObject("PlayerTargetMaxTargetsPlayMode");
@@ -736,51 +703,25 @@ namespace Simulation.Tests.PlayMode
}
[UnityTest]
public IEnumerator SetUseSimulationAndJob_AreIgnored_WhenBattleStateIsActive()
public IEnumerator TryRequestAreaCollision_ReturnsFalse_WhenSimulationMovementDisabled()
{
SetUseSimulationMovementMethod.Invoke(_worldComponent, new object[] { true });
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { false });
SetUseSimulationMovement(false);
object[] requestArgs = { 5530, 5530, Vector3.zero, 1f, 1 };
bool requestResult = (bool)TryRequestAreaCollisionMethod.Invoke(_worldComponent, requestArgs);
object previousProcedure = GetGameEntryProcedure();
GameObject procedureObject = new GameObject("ProcedureGuardPlayMode");
try
{
Component procedureComponent = procedureObject.AddComponent(ProcedureComponentType);
object procedureManager = Activator.CreateInstance(ProcedureManagerType);
Type fsmType = FsmOpenGenericType.MakeGenericType(ProcedureManagerInterfaceType);
object fsm = Activator.CreateInstance(fsmType);
object procedureGame = Activator.CreateInstance(ProcedureGameType);
object battleState = Enum.Parse(GameStateTypeType, "Battle");
Assert.IsFalse(requestResult);
Assert.IsFalse((bool)UseSimulationMovementProperty.GetValue(_worldComponent));
SetPrivateField(procedureGame, "_currentGameState", battleState);
SetPrivateField(fsm, "m_CurrentState", procedureGame);
SetPrivateField(procedureManager, "m_ProcedureFsm", fsm);
SetPrivateField(procedureComponent, "m_ProcedureManager", procedureManager);
SetGameEntryProcedure(procedureComponent);
SetUseSimulationMovementMethod.Invoke(_worldComponent, new object[] { false });
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
Assert.IsTrue((bool)UseSimulationMovementProperty.GetValue(_worldComponent));
Assert.IsFalse((bool)UseJobSimulationProperty.GetValue(_worldComponent));
}
finally
{
SetGameEntryProcedure(previousProcedure);
Object.Destroy(procedureObject);
}
yield return null;
yield break;
}
[UnityTest]
public IEnumerator EnqueueAreaQuery_CapturesInactiveSourceSnapshot_WhenSourceEntityUnavailable()
{
SetUseJobSimulationMethod.Invoke(_worldComponent, new object[] { true });
UpsertEnemy(CreateEnemy(entityId: 5531, position: Vector3.zero, speed: 0f, attackRange: 1f));
object[] enqueueArgs = { 99999, 99999, Vector3.zero, 1f, 1 };
bool enqueueResult = (bool)TryEnqueueAreaCollisionQueryMethod.Invoke(_worldComponent, enqueueArgs);
bool enqueueResult = (bool)TryRequestAreaCollisionMethod.Invoke(_worldComponent, enqueueArgs);
Assert.IsTrue(enqueueResult);
object areaCollisionRequests = AreaCollisionRequestsField.GetValue(_worldComponent);
@@ -850,6 +791,11 @@ namespace Simulation.Tests.PlayMode
TickMethod.Invoke(_worldComponent, new[] { tickContext });
}
private void SetUseSimulationMovement(bool enabled)
{
UseSimulationMovementField.SetValue(_worldComponent, enabled);
}
private void UpsertEnemy(object enemy)
{
UpsertEnemyMethod.Invoke(_worldComponent, new[] { enemy });