Hey all,
Sorry to make a “help me fix my code” post, I’m sure I’m just missing something silly.
I’ve been trying to do a more up-to-date version of the ECS tutorial where you spawn a load of ships which fly from one end of the screen to the other and loop around. So far I’m just doing the spawning bit (I’m basing it on the Spawner_FromEntity sample from github here).
My component:
// Spawner.cs
using Unity.Entities;
public struct Spawner : IComponentData
{
public int initial_ship_count;
public int increment_ship_count;
public float ship_movement_speed;
public float top_bound;
public float bottom_bound;
public float left_bound;
public float right_bound;
public Entity ship_prefab;
}
The authoring monobehaviour:
using Unity.Entities;
using UnityEngine;
using System.Collections.Generic;
[RequiresEntityConversion]
public class SpawnerAuthoring : MonoBehaviour, IDeclareReferencedPrefabs, IConvertGameObjectToEntity
{
public int initial_ship_count;
public int increment_ship_count;
public float ship_movement_speed;
public float top_bound;
public float bottom_bound;
public float left_bound;
public float right_bound;
public GameObject ship_prefab;
public void DeclareReferencedPrefabs(List<GameObject> referenced_prefabs)
{
referenced_prefabs.Add(this.ship_prefab);
}
public void Convert(Entity entity, EntityManager manager, GameObjectConversionSystem conversion_system)
{
Spawner spawner = new Spawner
{
initial_ship_count = initial_ship_count,
increment_ship_count = increment_ship_count,
ship_movement_speed = ship_movement_speed,
top_bound = top_bound,
bottom_bound = bottom_bound,
left_bound = left_bound,
right_bound = right_bound,
ship_prefab = conversion_system.GetPrimaryEntity(ship_prefab)
};
manager.AddComponentData(entity, spawner);
}
}
The system:
using Unity.Entities;
using Unity.Jobs;
using Unity.Transforms;
using Unity.Mathematics;
using Random = Unity.Mathematics.Random;
using URandom = UnityEngine.Random;
using UnityEngine;
using Unity.Collections;
[UpdateInGroup(typeof(SimulationSystemGroup))]
public class SpawnerSystem : JobComponentSystem
{
private bool initial_spawn_done;
private BeginInitializationEntityCommandBufferSystem entity_command_buffer_system;
protected override void OnCreate()
{
this.initial_spawn_done = false;
this.entity_command_buffer_system = this.World.GetOrCreateSystem<BeginInitializationEntityCommandBufferSystem>();
}
struct SpawnJob : IJobForEachWithEntity<Spawner>
{
public EntityCommandBuffer.Concurrent command_buffer;
public bool is_initial;
public Random random;
public void Execute(Entity entity, int index, [ReadOnly] ref Spawner spawner)
{
int count = this.is_initial ? spawner.initial_ship_count : spawner.increment_ship_count;
for (int i = 0; i < count; ++i)
{
Entity instance = command_buffer.Instantiate(index, spawner.ship_prefab);
command_buffer.SetComponent(index, instance,
new Translation{ Value = new float3(
random.NextFloat(spawner.left_bound, spawner.right_bound), // x
0.0f, // y
random.NextFloat(spawner.bottom_bound - 5.0f, spawner.bottom_bound)) });// z
}
}
}
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
if (!this.initial_spawn_done)
{
this.initial_spawn_done = true;
JobHandle job = new SpawnJob
{
command_buffer = this.entity_command_buffer_system.CreateCommandBuffer().ToConcurrent(),
is_initial = true,
random = new Random((uint)URandom.Range(int.MinValue, int.MaxValue))
}.Schedule(this, inputDeps);
this.entity_command_buffer_system.AddJobHandleForProducer(job);
return job;
}
else if (Input.GetKeyDown(KeyCode.Space))
{
JobHandle job = new SpawnJob
{
command_buffer = this.entity_command_buffer_system.CreateCommandBuffer().ToConcurrent(),
is_initial = false,
random = new Random((uint)URandom.Range(int.MinValue, int.MaxValue))
}.Schedule(this, inputDeps);
this.entity_command_buffer_system.AddJobHandleForProducer(job);
return job;
}
return new JobHandle();
}
}
Here’s my scene hierarchy:
The Spawner GameObject:
And the prefab I’m using:
Any help much appreciated
Cheers