Hello, I’m just starting my dive into DOTS and am about 6 days deep. I’ve made it to the point where I understand most of the ECS concepts (I think), but am still rather fuzzy on the Jobs and Burst pillars. To get started, I completed most of the tutorials I could find and have started to try to do something on my own.
I followed this Pong tutorial and decided to try to handle the collisions programmatically like how I’d do it in OOP. I’ve made it to the point where my triggers are actually working (specifically the goal triggers on the far sides of the paddles), thanks to this helpful physics tutorial.
I’m able to detect a trigger event, identify the entities involved and despawn my ball. The issue I’ve run into is, I cannot trigger my new ball to be spawned and record the point scored for the player. Below is my current GoalSystem code and I’m sure it’s horrendous so brace yourselves:
using UnityEngine;
using Unity.Entities;
using Unity.Jobs;
using Unity.Physics;
using Unity.Physics.Systems;
using Unity.Collections;
[AlwaysSynchronizeSystem]
public class GoalSystem : JobComponentSystem
{
private BuildPhysicsWorld buildPhysicsWorld;
private StepPhysicsWorld stepPhysicsWorld;
private EndSimulationEntityCommandBufferSystem ecBufferSystem;
// private EntityQuery spawnDataGroup;
// private EntityQuery textDataGroup;
private struct TriggerJob : ITriggerEventsJob
{
public ComponentDataFromEntity<BallTag> ballTag;
public ComponentDataFromEntity<WallTag> wallTag;
public ComponentDataFromEntity<PaddleTag> paddleTag;
public ComponentDataFromEntity<LeftGoalTag> leftGoalTag;
public ComponentDataFromEntity<RightGoalTag> rightGoalTag;
// public Entity spawnEntity;
// public Entity textEntity;
// public ComponentDataFromEntity<SpawnComponent> spawnDataFromEntity;
// public ComponentDataFromEntity<TextChangeComponent> textDataFromEntity;
public EntityCommandBuffer.ParallelWriter ecb;
public void Execute( TriggerEvent evt )
{
// SpawnComponent spawnData = spawnDataFromEntity[spawnEntity];
// TextChangeComponent textData = textDataFromEntity[textEntity];
if( ballTag.HasComponent( evt.EntityA ) && ( leftGoalTag.HasComponent( evt.EntityB ) ) )
{
Debug.Log( "1" );
// textData.p2Score++;
ecb.DestroyEntity( 1, evt.EntityA );
// spawnData.doSpawn = true;
}
else if( ballTag.HasComponent( evt.EntityB ) && ( leftGoalTag.HasComponent( evt.EntityA ) ) )
{
Debug.Log( "2" );
// textData.p2Score++;
ecb.DestroyEntity( 1, evt.EntityA );
// spawnData.doSpawn = true;
}
else if( ballTag.HasComponent( evt.EntityA ) && ( rightGoalTag.HasComponent( evt.EntityB ) ) )
{
Debug.Log( "3" );
// textData.p1Score++;
ecb.DestroyEntity( 1, evt.EntityA );
// spawnData.doSpawn = true;
}
else if( ballTag.HasComponent( evt.EntityB ) && ( rightGoalTag.HasComponent( evt.EntityA ) ) )
{
Debug.Log( "4" );
// textData.p1Score++;
ecb.DestroyEntity( 1, evt.EntityA );
// spawnData.doSpawn = true;
}
}
}
protected override void OnCreate()
{
base.OnCreate();
buildPhysicsWorld = World.GetOrCreateSystem<BuildPhysicsWorld>();
stepPhysicsWorld = World.GetOrCreateSystem<StepPhysicsWorld>();
ecBufferSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
// spawnDataGroup = GetEntityQuery( typeof( SpawnComponent ) );
// textDataGroup = GetEntityQuery( typeof( TextChangeComponent ) );
}
protected override JobHandle OnUpdate( JobHandle inputDeps )
{
// NativeArray<Entity> s = spawnDataGroup.ToEntityArray( Allocator.TempJob );
// NativeArray<Entity> t = textDataGroup.ToEntityArray( Allocator.TempJob );
TriggerJob triggerJob = new TriggerJob()
{
ballTag = GetComponentDataFromEntity<BallTag>(),
wallTag = GetComponentDataFromEntity<WallTag>(),
paddleTag = GetComponentDataFromEntity<PaddleTag>(),
leftGoalTag = GetComponentDataFromEntity<LeftGoalTag>(),
rightGoalTag = GetComponentDataFromEntity<RightGoalTag>(),
// spawnEntity = s[0],
// textEntity = t[0],
// spawnDataFromEntity = GetComponentDataFromEntity<SpawnComponent>(),
// textDataFromEntity = GetComponentDataFromEntity<TextChangeComponent>(),
ecb = ecBufferSystem.CreateCommandBuffer().AsParallelWriter()
};
// s.Dispose();
// t.Dispose();
return triggerJob.Schedule( stepPhysicsWorld.Simulation, ref buildPhysicsWorld.PhysicsWorld, inputDeps );
}
}
I’ve commented out all the code for how I was getting the entities with the spawn and text components as it did work and I could successfully read my textData.p1Score and the current state of spawnData.doSpawn, etc… but I writing to it didn’t actually change any data on the corresponding entities.
I’m sure there’s a better way to do this, so please highlight all my flaws.