88 lines
2.9 KiB
C#
88 lines
2.9 KiB
C#
using Unity.Burst;
|
|
using Unity.Collections;
|
|
using Unity.Entities;
|
|
using Unity.Jobs;
|
|
using Unity.Mathematics;
|
|
using Unity.Transforms;
|
|
|
|
namespace HappyForest.Prototypen
|
|
{
|
|
// Pille-gegen-Pille Kollision. Bewusst als einfacher O(n^2) Burst-Job gebaut,
|
|
// damit man per "K"-Taste sauber A/B vergleichen kann, was die Kollisionsprüfung
|
|
// an Performance kostet. Läuft nur, wenn PilleCollisionEnabled = true ist.
|
|
// (Für sehr große Mengen, z.B. >10.000, wäre ein Spatial-Grid der nächste Schritt.)
|
|
public partial struct PilleCollisionSystem : ISystem
|
|
{
|
|
public void OnCreate(ref SystemState state)
|
|
{
|
|
state.RequireForUpdate<PilleSimulationConfig>();
|
|
}
|
|
|
|
public void OnUpdate(ref SystemState state)
|
|
{
|
|
var config = SystemAPI.GetSingleton<PilleSimulationConfig>();
|
|
if (!config.PilleCollisionEnabled)
|
|
return;
|
|
|
|
var query = SystemAPI.QueryBuilder().WithAll<PilleComponent, LocalTransform>().Build();
|
|
int count = query.CalculateEntityCount();
|
|
if (count < 2)
|
|
return;
|
|
|
|
var transforms = query.ToComponentDataArray<LocalTransform>(Allocator.TempJob);
|
|
var pilles = query.ToComponentDataArray<PilleComponent>(Allocator.TempJob);
|
|
|
|
float radiusSum = config.PilleRadius * 2f;
|
|
|
|
var job = new ResolvePairCollisionsJob
|
|
{
|
|
Transforms = transforms,
|
|
Pilles = pilles,
|
|
RadiusSq = radiusSum * radiusSum
|
|
};
|
|
|
|
state.Dependency = job.Schedule(state.Dependency);
|
|
state.Dependency.Complete();
|
|
|
|
query.CopyFromComponentDataArray(pilles);
|
|
|
|
transforms.Dispose();
|
|
pilles.Dispose();
|
|
}
|
|
}
|
|
|
|
[BurstCompile]
|
|
public struct ResolvePairCollisionsJob : IJob
|
|
{
|
|
[ReadOnly] public NativeArray<LocalTransform> Transforms;
|
|
public NativeArray<PilleComponent> Pilles;
|
|
public float RadiusSq;
|
|
|
|
public void Execute()
|
|
{
|
|
int count = Transforms.Length;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
for (int j = i + 1; j < count; j++)
|
|
{
|
|
float3 delta = Transforms[i].Position - Transforms[j].Position;
|
|
float distSq = math.lengthsq(delta);
|
|
|
|
if (distSq < RadiusSq && distSq > 0.0001f)
|
|
{
|
|
float3 normal = math.normalize(delta);
|
|
|
|
var pi = Pilles[i];
|
|
var pj = Pilles[j];
|
|
|
|
pi.Velocity = math.reflect(pi.Velocity, normal);
|
|
pj.Velocity = math.reflect(pj.Velocity, -normal);
|
|
|
|
Pilles[i] = pi;
|
|
Pilles[j] = pj;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|