Last active
April 20, 2022 04:46
-
-
Save tsubaki/00469aeae95757dc225dd3e7deca9afc to your computer and use it in GitHub Desktop.
GameObjectを破棄するとEntityも破棄される。もしくはその逆
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Unity.Entities; | |
using Unity.Transforms; | |
using UnityEngine; | |
/// <summary> | |
/// GameObjectを破棄する時、紐付いているEntityを破棄する。 | |
/// </summary> | |
[RequireComponent(typeof(ConvertToEntity))] | |
[DisallowMultipleComponent] | |
[RequiresEntityConversion] | |
public class SyncGameObjectWithEntity : MonoBehaviour, IConvertGameObjectToEntity | |
{ | |
Entity _cachedEntity; | |
void Reset() | |
{ | |
GetComponent<ConvertToEntity>().ConversionMode = ConvertToEntity.Mode.ConvertAndInjectGameObject; | |
} | |
/// <summary> | |
/// 座標を同期する方法 | |
/// </summary> | |
[SerializeField] SyncType syncType = SyncType.EntityToGameObject; | |
void IConvertGameObjectToEntity.Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) | |
{ | |
_cachedEntity = entity; | |
// Entityを破棄した事を認識するために ReferenceGameObjectFromEntityState を登録 | |
dstManager.AddComponentData(entity, new ReferenceGameObjectFromEntityState { Value = gameObject }); | |
dstManager.AddComponentData(entity, new ReferenceGameObjectFromEntityTag()); | |
// 座標を同期する方法を設定 | |
switch (syncType) | |
{ | |
case SyncType.EntityToGameObject: | |
dstManager.AddComponentData(entity, new CopyTransformToGameObject()); | |
break; | |
case SyncType.GameObjectToEntity: | |
dstManager.AddComponentData(entity, new CopyTransformFromGameObject()); | |
break; | |
} | |
} | |
void OnDestroy() | |
{ | |
if (World.DefaultGameObjectInjectionWorld == null) | |
return; | |
// 紐付いているEntityを破棄する | |
var em = World.DefaultGameObjectInjectionWorld.EntityManager; | |
if (em.Exists(_cachedEntity)) | |
{ | |
em.RemoveComponent<ReferenceGameObjectFromEntityState>(_cachedEntity); | |
em.DestroyEntity(_cachedEntity); | |
} | |
} | |
/// <summary> | |
/// 座標の同期方法 | |
/// </summary> | |
enum SyncType | |
{ | |
/// <summary> Entityの座標をGameObjectに設定 </summary> | |
EntityToGameObject, | |
/// <summary> GameObjectの座標をEntityに設定 </summary> | |
GameObjectToEntity, | |
/// <summary> 何もしない </summary> | |
None | |
} | |
} | |
/// <summary> | |
/// Entityに紐付いているGameObjectを破棄する。 | |
/// Update前に実行 | |
/// </summary> | |
[UpdateInGroup(typeof(PresentationSystemGroup))] | |
public class GameObjectEntityCleanUpSystem : ComponentSystem | |
{ | |
private EntityQuery query; | |
protected override void OnCreate() | |
{ | |
// 破棄された、ReferenceGameObjectFromEntityStateを持つEntityを収集する。 | |
query = GetEntityQuery( | |
ComponentType.ReadOnly<ReferenceGameObjectFromEntityState>(), | |
ComponentType.Exclude<ReferenceGameObjectFromEntityTag>()); | |
} | |
protected override void OnUpdate() | |
{ | |
// Entityに紐付いているGameObjectとReferenceGameObjectFromEntityStateを破棄する。 | |
Entities | |
.With(query) | |
.ForEach((ReferenceGameObjectFromEntityState data) => | |
{ | |
Object.Destroy(data.Value); | |
}); | |
EntityManager.RemoveComponent<ReferenceGameObjectFromEntityState>(query); | |
} | |
} | |
/// <summary> | |
/// 自身のEntityが破棄された時、紐付いているGameObjectを破棄する。 | |
/// ReferenceGameObjectFromEntityTagとセットで運用。 | |
/// </summary> | |
public class ReferenceGameObjectFromEntityState : ISystemStateComponentData | |
{ | |
public GameObject Value; | |
} | |
/// <summary> | |
/// ReferenceGameObjectFromEntityStateが紐付いているEntityが破棄されたかを確認するためのタグ。 | |
/// ReferenceGameObjectFromEntityStateとセットで運用。 | |
/// </summary> | |
public struct ReferenceGameObjectFromEntityTag : IComponentData { } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment