Happy_Forest/Assets/Scripts/PilleCollisionSystem.cs

89 lines
2.9 KiB
C#
Raw Normal View History

2026-08-03 00:56:52 +02:00
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;
}
}
}
}
}
}