Hey,
the thread title is pretty generic but i couldn’t find a better title.
I try to implement that one entity can damage another entity. My current thinking is the following flow:
public struct PhysicalDamage : IComponentData
{
public uint Value;
}
public struct Target : IComponentData
{
public Entity Entity;
}
public struct PhysicalDamageReceived : IComponentData
{
public uint Value;
}
Entity A has component PhysicalDamage. When it should damage another entity it gets added a Target component with Entity B as Value. Than a system should add all damage that Entity B takes on to component PhysicalDamageReceived. Entity B might have PhysicalDamageReceived already but that shouldn’t matter. It should work either way.
My current (not working) solution looks like this:
public class DealPhysicalDamageMain : ComponentSystem
{
private ComponentGroup _group;
protected override void OnCreateManager()
{
base.OnCreateManager();
_group = GetComponentGroup(
new ECSQueryBuilder2().RequireReadOnly<PhysicalDamage>()
.RequireReadOnly<Target>()
.Build()
);
}
protected override void OnUpdate()
{
var physicalDamageType = GetArchetypeChunkComponentType<PhysicalDamage>(true);
var targetType = GetArchetypeChunkComponentType<Target>(true);
var chunks = _group.CreateArchetypeChunkArray(Allocator.Temp);
for(var i = 0; i < chunks.Length; ++i)
{
var chunk = chunks[i];
var physicalDamages = chunk.GetNativeArray(physicalDamageType);
var targets = chunk.GetNativeArray(targetType);
for(var j = 0; j < chunk.Count; ++j)
{
var damage = physicalDamages[i].Value;
var target = targets[i].Entity;
if(EntityManager.HasComponent<PhysicalDamageReceived>(target))
{
var physicalDamageReceived = EntityManager.GetComponentData<PhysicalDamageReceived>(target);
physicalDamageReceived.Value += damage;
EntityManager.SetComponentData(target, physicalDamageReceived);
}
else
{
EntityManager.AddComponentData(target, new PhysicalDamageReceived { Value = damage });
}
}
}
}
}
I first started with a job version but that made thinks not either. I have no idea how i could collapse the NativeMultiHashMap<Entity, uint>.
public class DealPhysicalDamage : JobComponentSystem
{
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
var map = new NativeMultiHashMap<Entity, uint>();
var mapDamage = new MapPhysicalDamage
{
Map = map.ToConcurrent()
};
return mapDamage.Schedule(this, inputDeps);
}
private struct MapPhysicalDamage : IJobProcessComponentData<PhysicalDamage, Target>
{
public NativeMultiHashMap<Entity, uint>.Concurrent Map;
public void Execute(ref PhysicalDamage data0, ref Target data1)
{
Map.Add(data1.Entity, data0.Value);
}
}
}
I’m out of ideas. It might be that i’m stuck somewhere with my thinking and try to do it the wrong way.
If anyone has an idea how i can get to where i want to be that would be helpful.
Thanks and regards,
sgrueling