Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Monobehaviour and ECS

Discussion in 'Entity Component System' started by Galimski, Jan 18, 2020.

  1. Galimski

    Galimski

    Joined:
    Apr 11, 2019
    Posts:
    25
    Hi! Sorry, if my question is stupid. But how should connect old style and new? I have a progress bar with a filler, and I can control the filler with float value. I created
    [GenerateAuthoringComponent]
    public struct ProgressBarComponent : IComponentData
    {
    public float progress;
    }

    and a very simple system to increase value. But how can I can link progress with Image component filler amount?
     
  2. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    You can write a bridge MonoBehaviour that acts handles updating the image component fill amount with public methods, then create a System that reads the ProgressBarComponent and accesses that bridge component's methods to handle the update.

    You won't be able to jobifiy the bridge component access, but it's fine to use MonoBehaviour's as ECS components if you Convert and Inject instead of Convert and Destroy.
     
  3. Galimski

    Galimski

    Joined:
    Apr 11, 2019
    Posts:
    25
    Please, give me an example of bridge. This part of ECS is totally unclear for me.
    I have MonoBehaviour like this
    public class ProgressView : MonoBehaviour
    {
    private const string LEVEL_PATTERN = "Level {0}";

    [SerializeField]
    private Image _progressBar;

    public void UpdateProgressBar(float progress)
    {
    _progressBar.fillAmount = progress;
    }
    }
     
    Last edited: Jan 19, 2020
  4. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,580
    You can simply create reference to GameObject bar, and use that on ECS main thread, in o Update.
     
  5. Galimski

    Galimski

    Joined:
    Apr 11, 2019
    Posts:
    25
    Sorry, still don't understand. On ECS I have only entity, and my component
    [GenerateAuthoringComponent]
    public struct ProgressBarComponent : IComponentData
    {
    public float progress;
    }

    How link it?
     
  6. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,580
    You just reference GameObject in similar manner, like any other class.
    You can do that on main thread (not in Job).
     
  7. Galimski

    Galimski

    Joined:
    Apr 11, 2019
    Posts:
    25
    ArgumentException: ProgressBarComponent contains a field of UnityEngine.UI.Image, which is neither primitive nor blittable.
     
  8. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,580
    Show us the code please.
    Also, please read
    Using code tags properly
    and edit your posts accordingly.
     
  9. Galimski

    Galimski

    Joined:
    Apr 11, 2019
    Posts:
    25
    Oh, sorry

    I have old-fashion game object and monobehaviour
    Code (CSharp):
    1. public class ProgressBar : MonoBehaviour
    2. {
    3.     [SerializeField]
    4.     private Image _progressBar;
    5.  
    6.     public void UpdateProgressBar(float progress)
    7.     {
    8.         _progressBar.fillAmount = progress;
    9.     }
    10. }

    Now I start use ECS. I create component
    Code (CSharp):
    1. [GenerateAuthoringComponent]
    2. public struct ProgressBarComponent : IComponentData
    3. {
    4.     public float progress;
    5. }

    And a very simple system:
    Code (CSharp):
    1.     public class ProgressBarSystem : ComponentSystem
    2.     {
    3.         protected override void OnCreate()
    4.         {
    5.             base.OnCreate();
    6.            
    7.             Entities.WithAll<ProgressBarComponent>().ForEach((ref ProgressBarComponent progressBarComponent) =>
    8.             {
    9.                 progressBarComponent.progress = 0f;
    10.             });
    11.         }
    12.  
    13.         protected override void OnUpdate()
    14.         {
    15.            
    16.         }
    17.     }
    How can I apply progressBarComponent.progress to Image?
     
  10. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,580
    Use ECS OnCreate, to define reference to ProgressBar.
    You can do that with tags, finding names, or by setting static values. Just some examples.
    But that should be clear, if you aiming to play with DOTS.
    Otherwise, I suggest go look into Getting Started forum, because you may have missing some critical principles.
    Then use that reference in OnUpdate

    Then you should be able use as normal inside OnUpdate,
    Code (CSharp):
    1. myProgressBar.UpdateProgressBar ( someValue ) ;
    But mind, as I said, you can not pass reference to the job. Like a GameObject for example.
    Or any other none blittable data types.
     
    Last edited: Jan 19, 2020
    oldhighscore likes this.
  11. gladieweb

    gladieweb

    Joined:
    Sep 7, 2012
    Posts:
    8
    where do you get the progressbar? you only recieve entities...
     
  12. JooleanLogic

    JooleanLogic

    Joined:
    Mar 1, 2018
    Posts:
    447
    I'm not up with 1.0 but afaik, hybrid conversion is going away so this example just hard codes entity creation.
    If you're just starting out with entities, I'm not sure I'd bother learning v0.5 mechanics.

    The method you're interested in below is AddComponentObject.
    In ProgressBar Monobehaviour, we create our entity and attach the ProgressBarComponent and Image to it.
    Then in the ProgressBarSystem, you can directly update the Image there.
    Code (CSharp):
    1. public class ProgressBar : MonoBehaviour
    2. {
    3.     [SerializeField]
    4.     public Image _progressBar;
    5.  
    6.     void Start()
    7.     {
    8.         var em = World.DefaultGameObjectInjectionWorld.EntityManager;
    9.         Entity entity = em.CreateEntity(typeof(ProgressBarComponent), typeof(Image));
    10.         em.AddComponentObject(entity, _progressBar);
    11.      
    12.         _progressBar.fillAmount = 0f;
    13.     }
    14. }
    15.  
    16. public struct ProgressBarComponent : IComponentData {
    17.     public float fillAmount;
    18. }
    19.  
    20. public partial class ProgressBarSystem : SystemBase
    21. {
    22.     protected override void OnUpdate() {
    23.         float dt = Time.DeltaTime;
    24.  
    25.         Entities
    26.         .ForEach( (Image image, ref ProgressBarComponent progressBar) => {
    27.             progressBar.fillAmount = math.min(1.0f, progressBar.fillAmount + (dt / 5.0f));   // 5 sec bar
    28.             image.fillAmount = progressBar.fillAmount;
    29.         })
    30.         .WithoutBurst()
    31.         .Run();
    32.     }
    33. }
     
    Egad_McDad, shotoutgames and bb8_1 like this.