Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

reference to another entity

Discussion in 'Project Tiny' started by marval, Mar 16, 2020.

  1. marval

    marval

    Joined:
    Jul 10, 2013
    Posts:
    46
    hi,
    before I could have a reference to another object that could be controlled in the same script:

    public class enemy : MonoBehaviour {
    public GameObject currentTarget;

    how to do the same with entities?
     
  2. Maras

    Maras

    Joined:
    Dec 11, 2012
    Posts:
    131
    You can for example:
    - make an entity query via GetEntityQuery
    - or get it from singleton via GetSingletonEntity
    - or directly link it from authoring component (Create monobehaviour with IConvertGameObjectToEntity, get the primary entity from the currentTarget and put it into Component on the main entity)
     
  3. marval

    marval

    Joined:
    Jul 10, 2013
    Posts:
    46
    hi,
    i don't have a minimum idea of how to do this.
    do any of the TinySamples demonstrate how to do this?
     
  4. AbdulAlgharbi

    AbdulAlgharbi

    Unity Technologies

    Joined:
    Jul 27, 2018
    Posts:
    319
    the easiest fix is to create a component that is called Enemy with currentTarget as an entity

    Code (CSharp):
    1.  
    2. using Unity.Entities;
    3.  
    4. [GenerateAuthoringComponent]
    5. public struct Enemy : IComponentData
    6. {
    7.     public Entity currentTarget;
    8. }
    from the editor, attach that component to your game object
    and add the target game object to the currentTarget field from the inspector
     
    JuanuMusic likes this.
  5. marval

    marval

    Joined:
    Jul 10, 2013
    Posts:
    46
    I had already tried that
    the problem is that when i try to access this entity from the system i can't do anything with it.
    I don't know if I'm doing it right:

    Entities.ForEach((ref Enemy enemy) =>
    {
    Entity ent = enemy.currentTarget;
    ent.???
    });
     
  6. Ted_Wikman

    Ted_Wikman

    Unity Technologies

    Joined:
    Oct 7, 2019
    Posts:
    916
    @marval could you share a bit more code on how your structure looks like currently?
     
  7. SINePrime

    SINePrime

    Joined:
    Jan 24, 2019
    Posts:
    54
    At that point you'd want to use the EntityManager class to perform some operations on the entity's components. Eg, GetComponentData.
     
    kevinmv likes this.
  8. marval

    marval

    Joined:
    Jul 10, 2013
    Posts:
    46
    Code (CSharp):
    1. using UnityEngine;
    2. using Unity.Entities;
    3.  
    4. namespace Tiny3D
    5. {
    6.     [GenerateAuthoringComponent]
    7.     public struct Enemy : IComponentData
    8.     {
    9.       public Entity curretTarget;
    10.     }
    11. }
    Code (CSharp):
    1. using System;//Unity.Physics
    2. //using Unity.Burst;
    3. //using Unity.Jobs
    4. using Unity.Entities;
    5. using Unity.Mathematics;
    6. using Unity.Transforms;
    7. using Unity.Tiny;
    8. using UnityEngine;
    9.  
    10. namespace Tiny3D
    11. {
    12.     public class EnemySystem : ComponentSystem
    13.     {
    14.         protected override void OnUpdate()
    15.         {
    16.             Entities.ForEach((ref Enemy enemy) =>
    17.             {
    18.                 Entity ent = enemy.currentTarget;
    19.                 //ent.???
    20.             });
    21.         }
    22.     }
    23. }
     
  9. AbdulAlgharbi

    AbdulAlgharbi

    Unity Technologies

    Joined:
    Jul 27, 2018
    Posts:
    319
    So your target entity should have a Target component with something like (Just an example)

    Code (CSharp):
    1. using Unity.Entities;
    2.  
    3. [GenerateAuthoringComponent]
    4. public struct Target: IComponentData
    5. {
    6.     public float health;
    7.     public float speed;
    8. }
    in the editor, attach Target component to the target game object
    and from the inspector, you can change the health and speed values

    and in your EnemySystem, you can do something like

    Code (CSharp):
    1. public class EnemySystem : ComponentSystem
    2. {
    3.     protected override void OnUpdate()
    4.     {
    5.         Entities.ForEach((ref Enemy enemy) =>
    6.         {
    7.             Entity ent = enemy.currentTarget;
    8.             var targetComponent = EntityManager.GetComponentData<Target>(ent);
    9.             targetComponent.health -=0.1f;
    10.             speed = 0.0f;
    11.             EntityManager.SetComponentData(ent, targetComponent);
    12.         });
    13.     }
    14. }
     
    Radivarig likes this.
  10. marval

    marval

    Joined:
    Jul 10, 2013
    Posts:
    46
    hi,
    I need to change the position of the entity,
    how to access the Transform Component and change the value?
    and
    using ( targetComponent.health -=0.1f; ) the component value does not change in the inspector ( DOTS Subscene -> edit )
     
  11. Maras

    Maras

    Joined:
    Dec 11, 2012
    Posts:
    131
    Checkout this tutorial:


    It goes through some ECS basics including Translation component
     
    Discipol likes this.
  12. marval

    marval

    Joined:
    Jul 10, 2013
    Posts:
    46
    this tutorial does not cover EntityManager.GetComponentData
    I need to access the Transform component of another entity to change the position.
     
  13. AbdulAlgharbi

    AbdulAlgharbi

    Unity Technologies

    Joined:
    Jul 27, 2018
    Posts:
    319
    you can use Entities.ForEach as @Maras mentioned or you can do

    Code (CSharp):
    1.  
    2.  var pos = EntityManager.GetComponentData<Translation>(entity);
    3. pos.Value.x = <do whatever you want  here>
    4. EntityManager.SetComponenetData(entity, pos);
    5.  
    Check how we are moving the camera in Tiny Racing here
     
  14. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    This works great, but unfortunately, if there is a custom converter, the strategy falls apart.

    Code (CSharp):
    1. [System.Serialize]
    2. public struct Enemy : IComponentData {
    3.     public float health;
    4.     public Entity someEntity;
    5. }
    If you do that, and then look at the inspector, the "health" field will show up fine, but the "someEntity" field will not appear. I know it can be done using a game-object and some extra IDeclareReferencedPrefabs voodoo, but I wish it was as simple as the [GenerateAuthoringComponent] scenario.