Skip to content

Instantly share code, notes, and snippets.

@Zammy
Last active November 10, 2022 14:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Zammy/c8afbed44676bc2019a2abd091884da8 to your computer and use it in GitHub Desktop.
Save Zammy/c8afbed44676bc2019a2abd091884da8 to your computer and use it in GitHub Desktop.
Projectile collision system ECS
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Physics;
using Unity.Physics.Systems;
using Unity.Transforms;
[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
[UpdateBefore(typeof(PhysicsSystemGroup))]
[BurstCompile]
public partial struct ProjectileCollisionSystem : ISystem
{
[BurstCompile]
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate<SettingsComponent>();
}
[BurstCompile]
public void OnDestroy(ref SystemState state) { }
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
var settings = SystemAPI.GetSingleton<SettingsComponent>();
var ecb = SystemAPI.GetSingleton<EndSimulationEntityCommandBufferSystem.Singleton>()
.CreateCommandBuffer(state.WorldUnmanaged);
var simuilationSingleton = SystemAPI.GetSingleton<SimulationSingleton>();
state.Dependency = new DestroyProjectileIfCollision
{
ProjectileExplosionPrefab = settings.ProjectileExplosionPrefab,
ECB = ecb,
ProjectileLookup = SystemAPI.GetComponentLookup<ProjectileComponent>(isReadOnly: true),
LocalToWorldLookup = SystemAPI.GetComponentLookup<LocalToWorld>(isReadOnly: true),
LifeLookup = SystemAPI.GetComponentLookup<LifeComponent>(isReadOnly: false)
}
.Schedule(simuilationSingleton, state.Dependency);
}
[BurstCompile]
public partial struct DestroyProjectileIfCollision : ICollisionEventsJob
{
public EntityCommandBuffer ECB;
public Entity ProjectileExplosionPrefab;
[ReadOnly] internal ComponentLookup<ProjectileComponent> ProjectileLookup;
[ReadOnly] internal ComponentLookup<LocalToWorld> LocalToWorldLookup;
internal ComponentLookup<LifeComponent> LifeLookup;
[BurstCompile]
public void Execute(CollisionEvent collisionEvent)
{
bool foundProjectile = false;
bool foundLife = false;
Entity projectileEntity = default(Entity);
Entity lifeEntity = default(Entity);
ProjectileComponent projectile;
LifeComponent life;
if (ProjectileLookup.TryGetComponent(collisionEvent.EntityA, out projectile))
{
projectileEntity = collisionEvent.EntityA;
foundProjectile = true;
}
if (!foundProjectile && ProjectileLookup.TryGetComponent(collisionEvent.EntityB, out projectile))
{
projectileEntity = collisionEvent.EntityB;
foundProjectile = true;
}
if (LifeLookup.TryGetComponent(collisionEvent.EntityA, out life))
{
lifeEntity = collisionEvent.EntityA;
foundLife = true;
}
if (!foundLife && LifeLookup.TryGetComponent(collisionEvent.EntityB, out life))
{
lifeEntity = collisionEvent.EntityB;
foundLife = true;
}
float damage = 0f;
if (foundProjectile)
{
damage = projectile.Damage;
if (!LocalToWorldLookup.TryGetComponent(projectileEntity, out LocalToWorld collidedEntityT))
{
UnityEngine.Debug.LogError("Projectile has no LocalToWorld? This should not happen.");
return;
}
Entity fxEntity = ECB.Instantiate(ProjectileExplosionPrefab);
ECB.AddComponent(fxEntity, new Translation()
{
Value = collidedEntityT.Position
});
ECB.DestroyEntity(projectileEntity);
}
if (foundLife && foundProjectile)
{
UnityEngine.Debug.Log("LIFE!");
var x = LifeLookup.GetRefRWOptional(lifeEntity, false);
x.ValueRW.Value -= damage;
//ECB.SetComponent(lifeEntity, new LifeComponent()
//{
// Value = life.Value - damage
//});
//life.Value -= damage;
//ECB.SetComponent(lifeEntity, life);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment