DOTS - avoiding hardcoding numbers

How do we get the info for (0, 500) from the setupspawner’s gridsize * spread ?

1 Like

Hey,

That question got me thinking and I found a solution (although I’m not sure if it’s the best one tbh.)

The way I did is I created another component called GridInfo for each person entity. And inside SetupSpawner, I set the component data for the grid info in accordance to gridsize * spread. This way SetupSpawner sends it to component and then we can get the component into system(via in, since we only need to read it, we don’t need to change it).

Here is the code itself(I also changed it a bit to have speed randomized each time entity chooses a new destination)

SetupSpawner:

using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;

public class SetupSpawner : MonoBehaviour
{
    [SerializeField] private GameObject personPrefab;

    [Header("Grid")]

    [SerializeField] private int gridSize;
    [SerializeField] private float spread;

    [Header("Movement")]
    [SerializeField] private Vector2 movementSpeedRange = new Vector2(4f, 7f);
    [SerializeField] private float defaultSpeed = 1f;

    private BlobAssetStore blob;

    private void Start()
    {
        blob = new BlobAssetStore();

        var settings = GameObjectConversionSettings.FromWorld(World.DefaultGameObjectInjectionWorld, blob);
        var entity = GameObjectConversionUtility.ConvertGameObjectHierarchy(personPrefab, settings);

        var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;

        for (int x = 0; x < gridSize; ++x)
        {
            for (int z = 0; z < gridSize; z++)
            {
                var instance = entityManager.Instantiate(entity);

                float3 postion = new float3(x*spread, 0, z*spread);

                entityManager.SetComponentData(instance, new Translation { Value = postion});
                entityManager.SetComponentData(instance, new MovementSpeed {Value = defaultSpeed, Range = new float2(movementSpeedRange.x, movementSpeedRange.y)});
                entityManager.SetComponentData(instance, new Destination { Value = postion});
                entityManager.SetComponentData(instance, new GridInfo { Range = new float2(0f, gridSize * spread)});
            }
        }
    }

    private void OnDestroy()
    {
        blob.Dispose();
    }
}

GridInfo:

using Unity.Entities;
using Unity.Mathematics;

[GenerateAuthoringComponent]
public struct GridInfo : IComponentData
{
    public float2 Range;
}

NewDestinationSystem:

using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Transforms;

public class NewDestinationSystem : SystemBase
{
    private RandomSystem randomSystem;

    private const float epsilon = 0.001f;

    protected override void OnCreate()
    {
        randomSystem = World.GetExistingSystem<RandomSystem>();
    }

    protected override void OnUpdate()
    {
        var randomArray = randomSystem.RandomArray;

        Entities
            .WithNativeDisableParallelForRestriction(randomArray)
            .ForEach((int nativeThreadIndex, ref Destination destination, ref MovementSpeed movementSpeed, in Translation translation, in GridInfo gridInfo) => {

                float distance = math.abs(math.length(destination.Value - translation.Value));

                if(distance < epsilon)
                {
                    var random = randomArray[nativeThreadIndex];

                    destination.Value.x = random.NextFloat(gridInfo.Range.x, gridInfo.Range.y);
                    destination.Value.z = random.NextFloat(gridInfo.Range.x, gridInfo.Range.y);

                    movementSpeed.Value = random.NextFloat(movementSpeed.Range.x, movementSpeed.Range.y); 

                    randomArray[nativeThreadIndex] = random;
                }

        }).ScheduleParallel();
    }
}

In GridInfo I have it called Range and use float2, calling it Value should be fine and even just using float instead of float2, if you are fine with having a 0 as constant in the system.

Certainly a solution and should work but that’s a lot of repeated info and space taken for it especially if you have 100,000s of people…

Hopefully there is a simpler solution & @Nathan_Farrer will come back with one

Privacy & Terms