简单重构拆分 SimulationWorld
This commit is contained in:
+99
@@ -0,0 +1,99 @@
|
||||
using Unity.Burst;
|
||||
using Unity.Collections;
|
||||
using Unity.Jobs;
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace SepCore.Simulation
|
||||
{
|
||||
internal static class PickupMovementSystem
|
||||
{
|
||||
// 读写集:R/W PickupTransform / PickupState; R PickupIdentity / PickupRadius
|
||||
// W CollectedPickups
|
||||
public static JobHandle Schedule(PickupStore pickups, NativeList<int> collectedPickups,
|
||||
float deltaTime, float3 playerPosition, float absorbRange, float absorbSpeed, float collectDistance,
|
||||
JobHandle dependency)
|
||||
{
|
||||
int pickupCount = pickups.Count;
|
||||
if (pickupCount == 0)
|
||||
{
|
||||
return dependency;
|
||||
}
|
||||
|
||||
PickupMovementJob job = new PickupMovementJob
|
||||
{
|
||||
Transforms = pickups.Transform.Data.AsArray(),
|
||||
States = pickups.State.Data.AsArray(),
|
||||
Identities = pickups.Identity.Data.AsArray(),
|
||||
Radii = pickups.Radius.Data.AsArray(),
|
||||
CollectedPickups = collectedPickups.AsParallelWriter(),
|
||||
PlayerPosition = playerPosition,
|
||||
AbsorbRange = math.max(0f, absorbRange),
|
||||
AbsorbSpeed = math.max(0f, absorbSpeed),
|
||||
CollectDistance = math.max(0f, collectDistance),
|
||||
DeltaTime = deltaTime
|
||||
};
|
||||
return job.Schedule(pickupCount, 64, dependency);
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
internal struct PickupMovementJob : IJobParallelFor
|
||||
{
|
||||
public NativeArray<PickupTransformSim> Transforms;
|
||||
public NativeArray<PickupStateSim> States;
|
||||
[ReadOnly] public NativeArray<PickupIdentitySim> Identities;
|
||||
[ReadOnly] public NativeArray<PickupRadiusSim> Radii;
|
||||
public NativeList<int>.ParallelWriter CollectedPickups;
|
||||
public float3 PlayerPosition;
|
||||
public float AbsorbRange;
|
||||
public float AbsorbSpeed;
|
||||
public float CollectDistance;
|
||||
public float DeltaTime;
|
||||
|
||||
public void Execute(int index)
|
||||
{
|
||||
PickupTransformSim transform = Transforms[index];
|
||||
PickupStateSim state = States[index];
|
||||
PickupIdentitySim identity = Identities[index];
|
||||
PickupRadiusSim radius = Radii[index];
|
||||
|
||||
float3 currentPosition = transform.Position;
|
||||
float3 horizontalPosition = new float3(currentPosition.x, 0f, currentPosition.z);
|
||||
float3 toPlayer = PlayerPosition - horizontalPosition;
|
||||
float sqrDistance = math.lengthsq(toPlayer);
|
||||
|
||||
float effectiveCollectDistance = math.max(CollectDistance, radius.Radius);
|
||||
float sqrCollectDistance = effectiveCollectDistance * effectiveCollectDistance;
|
||||
|
||||
if (sqrDistance <= sqrCollectDistance)
|
||||
{
|
||||
CollectedPickups.AddNoResize(identity.EntityId);
|
||||
return;
|
||||
}
|
||||
|
||||
bool isAbsorbing = state.State == PickupStateSim.StateAbsorbing;
|
||||
bool shouldAbsorb = isAbsorbing || (AbsorbRange > 0f && sqrDistance <= AbsorbRange * AbsorbRange);
|
||||
|
||||
if (shouldAbsorb && AbsorbSpeed > 0f && sqrDistance > float.Epsilon)
|
||||
{
|
||||
state.State = PickupStateSim.StateAbsorbing;
|
||||
float distance = math.sqrt(sqrDistance);
|
||||
float step = AbsorbSpeed * DeltaTime;
|
||||
|
||||
if (step >= distance)
|
||||
{
|
||||
transform.Position = new float3(PlayerPosition.x, currentPosition.y, PlayerPosition.z);
|
||||
CollectedPickups.AddNoResize(identity.EntityId);
|
||||
}
|
||||
else
|
||||
{
|
||||
float3 direction = toPlayer / distance;
|
||||
transform.Position = currentPosition + direction * step;
|
||||
}
|
||||
|
||||
Transforms[index] = transform;
|
||||
States[index] = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user