- Home /
in Hybrid ECS, how can i destroy an entity ?
I tried
PostUpdateCommands.DestroyEntity(entity)
but it tell me than my "Script.Group" isn't a "Unity.Entities.Entity" (which is true... but still... i need to destroy it !)
thanks
Answer by Cassiopee · Dec 18, 2018 at 10:27 PM
Thanks to your answer. However that part about Injection really confuse me. I dont use it at all in my scripts and i dont know what it is needed for. creating the struct is enough for a system to detect gameObject with requiered components on it in my test, and what i was talking about was not destroying the gameObject itself but rather the entity whom represent this gameObject.
for example a script i am using
when a player connect, this system get through all other players to disables components (such as Camera for example) then turn a bool true to avoid doing it again. it run in OnUpdate so nomatter how player connect/disconnect, components are disabled anyway.
using UnityEngine;
using Unity.Entities;
using Hybrid.Components;
using UnityEngine.Networking;
public class PlayerSetup : ComponentSystem
{
private struct Group
{
public NetworkIdentity networkIdentity;
public ComponentsToDisable componentsToDisable;
}
protected override void OnUpdate()
{
foreach (PlayerSetup.Group entity in GetEntities<Group>())
{
if (!entity.networkIdentity.isLocalPlayer && !entity.componentsToDisable.TaskCompleted)
DisableComponents(entity);
}
}
private void DisableComponents(PlayerSetup.Group entity)
{
foreach (Behaviour behaviour in entity.componentsToDisable.behaviours)
{
Debug.Log(behaviour.name + " is now disabled");
behaviour.enabled = false;
}
entity.componentsToDisable.TaskCompleted = true;
}
}
since it is working i guess i'm not totally wrong but i dont get what Injections stands for. Also i would like to know and do things when entitys cames and leaves a system but that's for another thread.
[Inject] is just an alternative to GetEntities(), pretty much does the same thing just differently
This line contains na$$anonymous$$g error and probably source of confusion:
private void DisableComponents ( PlayerSetup.Group entity )
PlayerSetup.Group is not an entity. It's (kind of) filter and data container at the same time.
Here is an entity:
Entity entity = monobehaviourWithEntityComponentAttached.GetComponent<GameObjectEntity>().Entity;
But very probably won't work at all, for synchronization reasons.
Here is a way of getting real valid entity I know:
struct Group
{
public ComponentArray<Some$$anonymous$$indOf$$anonymous$$onoBehaviour> mono;
[ReadOnly] public EntityArray entity;//<HERE THEY ARE
public readonly int Length;
}
I've tried getting associated entity using GetEntities() but no luck so far. If i understand correctly - logs warn that this is not an intended path ("entity can not be used in a component enumerator"). Entity validity may not be guaranteed this way for some reason, i don't know.
thanks for your answers. i miss so much knowledge to understand all that _
Answer by andrew-lukasik · Dec 18, 2018 at 09:55 PM
If you are starting with ECS then consider not using entities at all. It is not easy to switch to entities, especially when it's implementation is still superficial in engine itself (true for year 2018 and maybe even 2019). When you take a look at Unity's own github examples for hybrid ECS then you can see that ECS can be employed without even thinking about these confusing entities. Here is a example of how you can port a class to ComponenSystem (which is part of hybrid/transitional solution):
Vanilla MonoBehaviour:
using UnityEngine;
// Simple old script that destroys this gameObject after delay
public class DestroyDelayed : MonoBehaviour
{
public float timeLeft = 1f;
void Update ()
{
//update time left:
this.timeLeft -= Time.deltaTime;
//destroy gameobject when time is up:
if( this.timeLeft<0f )
{
UnityEngine.Object.Destroy( gameObject );
}
}
}
Transitional "hybrid" version of the same functionality:
using System.Collections.Generic;
using UnityEngine;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using Unity.Collections;
// This is just regular monobehaviour here (to contain data) (...)
public class DestroyDelayed : MonoBehaviour
{
public float timeLeft = 1f;
}
// (...) but it can now run updates slightly faster thanks to streamlined code execution:
public class DestroyDelayedSystem : ComponentSystem
{
struct Group
{
[ReadOnly] public ComponentArray<DestroyDelayed> component;
public readonly int Length;
}
[Inject] Group group;
protected override void OnUpdate ()
{
float deltaTime = Time.deltaTime;
for( int i=0 ; i<group.Length ; i++ )
{
//read next in group:
var component = group.component[ i ];
//update time left:
component.timeLeft -= deltaTime;
//destroy gameobject when time is up:
if( component.timeLeft<0f )
{
UnityEngine.Object.Destroy( component.gameObject );
}
}
}
}
Answer by andrew-lukasik · Dec 18, 2018 at 10:23 PM
Here is how to destroy an entity in ComponenSystem:
using System.Collections.Generic;
using UnityEngine;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using Unity.Collections;
[System.Serializable]
public struct DestroyEntityDelayed : IComponentData
{
public float timeLeft;
}
public class DestroyEntityDelayedComponent : ComponentDataWrapper<DestroyEntityDelayed> {}
public class DestroyEntityDelayedSystem : ComponentSystem
{
struct Group
{
public ComponentDataArray<DestroyEntityDelayed> destroyDelayed;
[ReadOnly] public EntityArray entity;
public readonly int Length;
}
[Inject] Group group;
protected override void OnUpdate ()
{
float deltaTime = Time.deltaTime;
for( int i=0 ; i<group.Length ; i++ )
{
//read next in group:
var destroyDelayed = group.destroyDelayed[ i ];
Entity entity = group.entity[ i ];
//update time left:
destroyDelayed.timeLeft -= deltaTime;
group.destroyDelayed[ i ] = destroyDelayed;
//destroy entity on time out:
if( destroyDelayed.timeLeft<0f )
{
PostUpdateCommands.DestroyEntity( entity );
Debug.Log( $"entity destroyed: { entity }" );
}
}
}
}
Answer by pastersteli · Oct 16, 2021 at 05:07 PM
When I looking for solution, I see your comment u r everywhere dude :D @andrew-lukasik I have a problem. When I destroy entity, There is 3 of them appears
I have solve the problem. Converter make the submeshes to child entities. there are four entity actually.
Glad to hear that! And well... I might be commenting too much on this topic indeed :T
Your answer
Follow this Question
Related Questions
how to cancel iTween Catmull-Rom path 1 Answer
2d controll rigidboy.velocity.y 1 Answer
Is updating from Gamemaker apk to Unity apk possible in the Play Store? 0 Answers
blend4web is better than unity WebGl ? 1 Answer
Unity 5 (All turns White) 0 Answers