Hi, I’m currently working on a City builder with DOTS.
But I have an issue with my prefab converted to entity.
Here the script I have made:
// ==================================================================
// ■ DotsPrefabs.cs
// ------------------------------------------------------------------
//
// ==================================================================
using System.Collections.Generic;
using Unity.Entities;
using UnityEngine;
using UnityEngine.Assertions;
using Object = UnityEngine.Object;
// ------------------------------------------------------------------
// ♦
// ------------------------------------------------------------------
[RequiresEntityConversion]
public class DotsPrefabs : MonoBehaviour, IDeclareReferencedPrefabs, IConvertGameObjectToEntity {
public List<Content> Contents;
public static readonly Dictionary<int, Entity> ConversionTable = new Dictionary<int, Entity>();
public static Entity GetEntityOf(GameObject prefab) => ConversionTable.ContainsKey(prefab.GetInstanceID()) ? ConversionTable[prefab.GetInstanceID()] : Global.NullEntity;
// --------------------------------------------------------------
// ○
// --------------------------------------------------------------
public static Entity CreateInstanceOf(GameObject prefab) {
int id = prefab.GetInstanceID();
if (!ConversionTable.ContainsKey(id)) return Global.NullEntity;
Entity entity = ConversionTable[id];
//
if (!Global.ECS.EntityManager.Exists(entity))
Debug.LogError($"Entity doesn't exist for {prefab.name} -> {entity}");
//
entity = Global.ECS.EntityManager.Instantiate(entity);
return entity;
}
// --------------------------------------------------------------
// ○
// --------------------------------------------------------------
public void DeclareReferencedPrefabs(List<GameObject> referencedPrefabs) {
foreach (Content content in this.Contents) {
foreach (Object obj in content.List) {
if (obj is BuildingInfo buildingInfo) {
Assert.IsNotNull(buildingInfo.Prefab);
referencedPrefabs.Add(buildingInfo.Prefab);
} else if (obj is VehicleInfo vehicleInfo) {
Assert.IsNotNull(vehicleInfo.Prefab);
referencedPrefabs.Add(vehicleInfo.Prefab);
}
}
}
}
// --------------------------------------------------------------
// ○
// --------------------------------------------------------------
public void Convert(Entity bank, EntityManager dstManager, GameObjectConversionSystem conversionSystem) {
List<Entity> citizenCars = new List<Entity>();
//
foreach (Content content in this.Contents) {
foreach (Object obj in content.List) {
if (obj is BuildingInfo buildingInfo) {
Entity entity = conversionSystem.GetPrimaryEntity(buildingInfo.Prefab);
ConversionTable.Add(buildingInfo.Prefab.GetInstanceID(), entity);
} else if (obj is VehicleInfo vehicleInfo) {
Entity entity = conversionSystem.GetPrimaryEntity(vehicleInfo.Prefab);
ConversionTable.Add(vehicleInfo.Prefab.GetInstanceID(), entity);
citizenCars.Add(entity);
}
}
}
//
Global.CitizenCars = citizenCars;
}
// -- END --
}
Content (line 18) is a ScriptableObject that contain a list of UnityEngine.Object, I sort all my ScriptableObject like that.
BuildingInfo (line 41) is a ScriptableObject that contain all sort of stuff related to a building. (price, id, prefab…)
VehicleInfo (line 44) same but for Vehicles.
In short: I have a ScriptableObject of type Content that contain all my buildings and another one with all my vehicles.
There are a Gameobject in my scene with this script “DotsPrefabs” on it and a list of Content.
This gameObject also have the script ConvertToEntity given by unity.
What I want is when I start the scene all the prefab accessible through the BuildingInfo/VehicleInfo/Content get converted in entity and get referenced in the var ConversionTable.
ConversionTable is a static Dictionary<int, Entity>, int is Prefab.GetInstanceID() and the Entity is the converted prefab.
Like that I can call GetEntityOf() (line 24) to get a new entity instance of a certain prefab.
All works good until unity 2019.2, so I guess something is not OK in my approach.
(same issue in 2019.3 Alpha10)
My problem is that at some point certain referenced entities in the ConversionTable are destroyed or moved… their Index/Version don’t correspond to the prefab anymore and EntityManager.Exists return false on them (line 29).
I did not touch these entities, I always access them through CreateInstanceOf, I’m sure only their instances is use in the game and not the prefab itself.
How am I supposed to keep track of all the entity prefab ?
Feel free to ask if you need more information.
Thanks for reading and sorry for possible grammar mistake English is not my first language.


