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?
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.
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;
}
}
You can simply create reference to GameObject bar, and use that on ECS main thread, in o Update.
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?
You just reference GameObject in similar manner, like any other class.
You can do that on main thread (not in Job).
ArgumentException: ProgressBarComponent contains a field of UnityEngine.UI.Image, which is neither primitive nor blittable.
Show us the code please.
Also, please read
** Using code tags properly **
and edit your posts accordingly.
Oh, sorry
I have old-fashion game object and monobehaviour
public class ProgressBar : MonoBehaviour
{
[SerializeField]
private Image _progressBar;
public void UpdateProgressBar(float progress)
{
_progressBar.fillAmount = progress;
}
}
Now I start use ECS. I create component
[GenerateAuthoringComponent]
public struct ProgressBarComponent : IComponentData
{
public float progress;
}
And a very simple system:
public class ProgressBarSystem : ComponentSystem
{
protected override void OnCreate()
{
base.OnCreate();
Entities.WithAll<ProgressBarComponent>().ForEach((ref ProgressBarComponent progressBarComponent) =>
{
progressBarComponent.progress = 0f;
});
}
protected override void OnUpdate()
{
}
}
How can I apply progressBarComponent.progress to Image?
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,
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.
1 Like
where do you get the progressbar? you only recieve entities…
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.
public class ProgressBar : MonoBehaviour
{
[SerializeField]
public Image _progressBar;
void Start()
{
var em = World.DefaultGameObjectInjectionWorld.EntityManager;
Entity entity = em.CreateEntity(typeof(ProgressBarComponent), typeof(Image));
em.AddComponentObject(entity, _progressBar);
_progressBar.fillAmount = 0f;
}
}
public struct ProgressBarComponent : IComponentData {
public float fillAmount;
}
public partial class ProgressBarSystem : SystemBase
{
protected override void OnUpdate() {
float dt = Time.DeltaTime;
Entities
.ForEach( (Image image, ref ProgressBarComponent progressBar) => {
progressBar.fillAmount = math.min(1.0f, progressBar.fillAmount + (dt / 5.0f)); // 5 sec bar
image.fillAmount = progressBar.fillAmount;
})
.WithoutBurst()
.Run();
}
}
3 Likes