API

Section is progress.

Node HashMap System

Used to find the nearest pedestrian entity node.

How To Use

private void Awake()
{
        NodeHashMapSystem.Register();
}

public Entity GetClosestNode(Vector3 position, out Vector3 nodePosition)
{
        return NodeHashMapSystem.GetClosestNode(position, out nodePosition);
}

User Spawn

Spawn a pedestrian in a custom position using user code.

using Spirit604.DotsCity.Simulation.Pedestrian;
using Spirit604.Extensions;
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;

public class PedestrianSpawnExample : MonoBehaviour
{
private EntityQuery pedestrianSettingsQuery;
private EntityQuery prefabContainerQuery;

private EntityManager EntityManager => World.DefaultGameObjectInjectionWorld.EntityManager;

private void Start()
{
        pedestrianSettingsQuery = EntityManager.CreateEntityQuery(ComponentType.ReadOnly<PedestrianSettingsReference>());
        prefabContainerQuery = EntityManager.CreateEntityQuery(ComponentType.ReadOnly<PedestrianEntityPrefabContainer>());
        NodeHashMapSystem.Register();
}

public void Spawn(Vector3 spawnPosition, Quaternion spawnRotation, Vector3 destination, int skinIndex = -1)
{
        var commandBuffer = new EntityCommandBuffer(Unity.Collections.Allocator.Temp);
        uint seed = MathUtilMethods.GetRandomSeed();

        var pedestrianSettings = pedestrianSettingsQuery.GetSingleton<PedestrianSettingsReference>().Config;
        var prefabContainer = prefabContainerQuery.GetSingletonBuffer<PedestrianEntityPrefabContainer>();

        var rnd = new Unity.Mathematics.Random(seed);

        Entity entityPrefab;

        if (skinIndex == -1)
        {
                entityPrefab = prefabContainer.GetRandomPrefab(rnd, out skinIndex);
        }
        else
        {
                if (prefabContainer.HasPrefabVariants())
                        entityPrefab = prefabContainer[skinIndex].PrefabEntity;
                else
                        entityPrefab = prefabContainer[0].PrefabEntity;
        }

        Entity destinationNode = NodeHashMapSystem.GetClosestNode(destination, out var destinationNodePos);
        destination = destinationNodePos;

        Spawn(
                ref commandBuffer,
                in pedestrianSettings,
                seed,
                entityPrefab,
                skinIndex,
                spawnPosition,
                spawnRotation,
                destinationNode,
                destination);

        commandBuffer.Playback(EntityManager);
        commandBuffer.Dispose();
}

private static Entity Spawn(
                 ref EntityCommandBuffer commandBuffer,
                 in BlobAssetReference<PedestrianSettings> pedestrianSettings,
                 uint seed,
                 Entity entityPrefab,
                 int skinIndex,
                 Vector3 spawnPosition,
                 Quaternion spawnRotation,
                 Entity destinationEntity,
                 float3 destination)
{
        var pedestrianEntity = commandBuffer.Instantiate(entityPrefab);

        var destinationComponent = new DestinationComponent()
        {
                Value = destination,
                PreviousDestination = destination,
                DestinationNode = destinationEntity,
                PreviuosDestinationNode = destinationEntity,
        };

        var spawnParams = new SpawnParams()
        {
                DestinationComponent = destinationComponent,
                RigidTransform = new RigidTransform(spawnRotation, spawnPosition),
                Seed = seed,
                SkinIndex = skinIndex
        };

        PedestrianInitUtils.Initialize(ref commandBuffer, pedestrianEntity, in spawnParams, in pedestrianSettings);

        return pedestrianEntity;
}
}

Density

Change the density of pedestrians at runtime.

using Spirit604.Attributes;
using Spirit604.DotsCity.Simulation.Pedestrian.Authoring;
using Spirit604.Extensions;
using System;
using System.Linq;
using UnityEngine;

public class PedestrianDensityChanger : MonoBehaviour
{
        [SerializeField] private PedestrianSpawnerConfigHolder pedestrianSpawnerConfigHolder;
        [SerializeField] private PedestrianSpawnerConfigAuthoring pedestrianSpawnerConfigAuthoring;
        [SerializeField] private int count = 200;

        public void SetCountRuntime(int count)
        {
                if (count < 0)
                        throw new ArgumentException("Count should be greater than zero");

                pedestrianSpawnerConfigAuthoring.ChangeDensity(count);
        }

        public void SetCountEditor(int count)
        {
                if (count < 0)
                        throw new ArgumentException("Count should be greater than zero");

                pedestrianSpawnerConfigHolder.PedestrianSpawnerConfig.MinPedestrianCount = count;
                EditorSaver.SetObjectDirty(pedestrianSpawnerConfigHolder.PedestrianSpawnerConfig);
        }

        [Button]
        private void SetCountFromInspector()
        {
                SetCountRuntime(count);
        }

#if UNITY_EDITOR
        private void Reset()
        {
                pedestrianSpawnerConfigHolder = ObjectUtils.FindObjectsOfType<PedestrianSpawnerConfigHolder>().Where(a => !a.gameObject.scene.isSubScene).FirstOrDefault();
                pedestrianSpawnerConfigAuthoring = ObjectUtils.FindObjectsOfType<PedestrianSpawnerConfigAuthoring>().Where(a => !a.gameObject.scene.isSubScene).FirstOrDefault();
                EditorSaver.SetObjectDirty(this);
        }
#endif
}