Skip to content

Instantly share code, notes, and snippets.

@gamemachine
Last active June 24, 2021 18:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gamemachine/6e1b8f58ccdf4072a42d0baba4b57174 to your computer and use it in GitHub Desktop.
Save gamemachine/6e1b8f58ccdf4072a42d0baba4b57174 to your computer and use it in GitHub Desktop.
using Sirenix.OdinInspector;
using System.Collections.Generic;
using Unity.Entities;
using UnityEngine;
namespace AiGame
{
public class PrefabConvertToEntity : MonoBehaviour
{
private const string AssetPath = @"Assets/AiGame/GameData/Resources/EcsPrefabData";
public const string ResourcePath = @"EcsPrefabData/PrefabDb";
private static bool Loaded;
public List<GameObject> Prefabs = new List<GameObject>();
[SerializeField]
private Unity.Scenes.ReferencedUnityObjects ObjectRefs;
private BlobAssetStore ConversionStore;
private World ConversionWorld;
private GameObjectConversionSettings ConversionSettings;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
static void Initialize()
{
Loaded = false;
}
public static void LoadAllPrefabs()
{
if (Loaded)
{
return;
}
Loaded = true;
var prefabDb = Resources.Load(ResourcePath, typeof(Unity.Scenes.ReferencedUnityObjects)) as Unity.Scenes.ReferencedUnityObjects;
foreach (var obj in prefabDb.Array)
{
var prefabConvert = (PrefabConvertToEntity)obj;
prefabConvert.Load();
}
}
#if UNITY_EDITOR
public static void ConvertAll()
{
var prefabDb = Resources.Load(ResourcePath, typeof(Unity.Scenes.ReferencedUnityObjects)) as Unity.Scenes.ReferencedUnityObjects;
foreach (var obj in prefabDb.Array)
{
var prefabConvert = (PrefabConvertToEntity)obj;
prefabConvert.Convert();
}
}
#endif
protected virtual void OnEntityConverted(Entity entity, GameObject gameObject, EntityManager manager)
{
}
protected virtual void OnBeforeConversion(EntityManager manager)
{
}
protected virtual void OnAfterConversion()
{
}
[Button("Load")]
public void Load()
{
DefaultWorldInitialization.DefaultLazyEditModeInitialize();
World targetWorld = World.DefaultGameObjectInjectionWorld;
targetWorld.EntityManager.CompleteAllJobs();
World sourceWorld = new World(name);
EntitySerializer.Deserialize(sourceWorld.EntityManager, name, ObjectRefs);
targetWorld.EntityManager.MoveEntitiesFrom(sourceWorld.EntityManager);
sourceWorld.Dispose();
}
#if UNITY_EDITOR
public World StartConversion()
{
EnsurePrefabDb();
ResetObjectRefs();
DefaultWorldInitialization.DefaultLazyEditModeInitialize();
ConversionWorld = new World(name);
ConversionStore = new BlobAssetStore();
ConversionStore.ResetCache(true);
ConversionSettings = new GameObjectConversionSettings(ConversionWorld, GameObjectConversionUtility.ConversionFlags.AssignName, ConversionStore);
OnBeforeConversion(ConversionWorld.EntityManager);
foreach (var prefab in Prefabs)
{
Entity entity = GameObjectConversionUtility.ConvertGameObjectHierarchy(prefab, ConversionSettings);
ConversionWorld.EntityManager.SetName(entity, prefab.name);
OnEntityConverted(entity, prefab, ConversionWorld.EntityManager);
}
return ConversionWorld;
}
public void EndConversion()
{
EntitySerializer.Serialize(ConversionWorld.EntityManager, name, out Unity.Scenes.ReferencedUnityObjects refs);
if (refs != null && refs.Array.Length > 0)
{
ObjectRefs.Array = new Object[refs.Array.Length];
for (int i = 0; i < refs.Array.Length; i++)
{
ObjectRefs.Array[i] = refs.Array[i];
}
}
ConversionWorld.Dispose();
ConversionStore.Dispose();
OnAfterConversion();
}
[Button("Convert")]
public void Convert()
{
StartConversion();
EndConversion();
Debug.LogFormat("Converted {0}", name);
}
[Button("Unload")]
private void Unload()
{
World world = World.DefaultGameObjectInjectionWorld;
if (world == null) return;
world.EntityManager.CompleteAllJobs();
var entities = world.EntityManager.GetAllEntities();
world.EntityManager.DestroyEntity(entities);
}
private void EnsurePrefabDb()
{
string path = string.Format("{0}/PrefabDb.asset", AssetPath);
var prefabs = UnityEditor.AssetDatabase.LoadAssetAtPath<Unity.Scenes.ReferencedUnityObjects>(path);
if (prefabs == null)
{
prefabs = ScriptableObject.CreateInstance<Unity.Scenes.ReferencedUnityObjects>();
UnityEditor.AssetDatabase.CreateAsset(prefabs, path);
UnityEditor.AssetDatabase.SaveAssets();
UnityEditor.EditorUtility.SetDirty(prefabs);
}
List<Object> converters = new List<Object>();
if (prefabs.Array != null)
{
converters.AddRange(prefabs.Array);
}
foreach(var prefab in converters)
{
if (prefab == this)
{
return;
}
}
converters.Add(this);
prefabs.Array = converters.ToArray();
UnityEditor.AssetDatabase.SaveAssets();
UnityEditor.EditorUtility.SetDirty(prefabs);
}
private void ResetObjectRefs()
{
if (ObjectRefs != null)
{
ObjectRefs.Array = null;
}
ObjectRefs = ScriptableObject.CreateInstance<Unity.Scenes.ReferencedUnityObjects>();
string path = string.Format("{0}/{1}.asset", AssetPath, name);
UnityEditor.AssetDatabase.CreateAsset(ObjectRefs, path);
UnityEditor.AssetDatabase.SaveAssets();
UnityEditor.EditorUtility.SetDirty(ObjectRefs);
}
#endif
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment