Advice wanted - healthbars

I really want health bars for my mobs, previously ive only used sliders because well, they are so good at it…

I looked into the AddHybridComponent and, it doesnt seem to like UI… so, how is a girl to achieve a simple health bar that can follow the entity and not be really overly complicated?

Well I solved it by system which collects objects positions (in screen space float2) and bar parameters (blobs) per different parameters. And sends them to post processing shader. And wrote post processing effect for drawing them.
Here is example how it looks (old videos)
(on Alt press I’m showing them. Also I using them for building upgrades)

6 Likes

Well, @eizenhorn , as always hats off to you, you do have l33t skills there. I couldnt make a shader if you set me on fire. However, you are the only one I know whos made decent health bars.

The post-processing effect is a good solution (I think). But if you don’t want to hack into the rendering pipeline, there’s a couple of things you can do.

Probably the easiest approach is to generate a quad the shape of the full health bar whose origin is set to the left-hand side. Run a system that makes all these quads align with the camera direction and the camera’s up direction. Then apply a NonUniformScale to represent the different health values. Lastly, you can also calculate an additional scale factor to compensate for perspective if desired.

3 Likes

thanks - you set me down a path and it looks like I might make it…

For a smaller number of units, its quite easy to just attach a quad with a shader graph material that takes a parameter for how full the health bar should be. All the quads will be batched together.

Inspiration for you here :slight_smile:

1 Like

Here is my shader graph from when I last did this in ECS.

1 Like

Yup. ShaderGraph instead of scaling can get you a more colorful bars. I’m not sure how good the support is for URP for Hybrid Renderer V1. But for HDRP and V2 this would probably be my goto solution if I needed to do this.

this is where Im at I followed his thing, got a working shader (having downloaded it from github) - however, Im running into an issue where the quad isnt on the entity with the health… so how to update that…

My solution is:

  1. Create a shader to render a healthbar, should accept health value 0-1 or something. Reddit - Dive into anything
  2. Each entity that needs healthbar to be displayed creates another entity with healthbar material and material block property to update health value. First entity should have reference to this entity in component.
  3. Create a system to iterate all entities with healthbar, access its healthbar entity and update position & health value in material block property component.

Basically what wg-siggig said.

You need a system that updates the position and rotation of the quads to follow those entities and align correctly to the camera.

It’s really easiest to just have this on a gameobject in your prefab and use the conversion flow.

I dont need the quads to rotate or move, as they will move with the entity,

My entity goes

empty

  • many sub gameobjects that make up the tank (see unity tanks)
  • healthbar

the empty has the health and all that jaz, the healthbar is on top (as its kinda top down) so it can rotate all it likes with the object, for now, but, what i cant work out is how to get that meshrender details from the empty part

OK - this is clearly wrong on a lot of levels but

       NativeArray<doit> mobs = new NativeArray<doit>(GamaDataManager.Instance.manager.CreateEntityQuery(ComponentType.ReadOnly<MobData>()).CalculateEntityCount(), Allocator.TempJob);
        var i = 0;
        Entities.ForEach((in MobData m) =>
        {
            mobs[i] =
            new doit {health = (float)m.health/(float)m.Maxhealth };
            i++;
        }).Run();
        i = 0;
        Entities.WithoutBurst().ForEach((RenderMesh mr, in HealthBar h) =>
        {
            var mr2 = mr;
            /*
            mr2.GetPropertyBlock(matBlock);
            matBlock.SetFloat("_Fill", mobs[i].health);
            mr2.SetPropertyBlock(matBlock);*/
            mr2.material.SetFloat("_Fill", mobs[i].health);
            mr = mr2;
            i++;
        }).Run();
        mobs.Dispose();

So, I got the material but unlike the meshrenderer, you cant get the block, and so none of them change because I guess its changing the fill value for the original material not its instance??

https://docs.unity3d.com/Packages/com.unity.rendering.hybrid@0.4/manual/index.html#custom-shadergraph-material-property-overrides

I wish that made more sense to me.
I havent used shader graph because I dont know how - I used the shader which I found earlier which wg-siggig listed, I feel like Im close, I have no errors, but its not changing.

You need to expose parameters on your shader graph and then set values on them via code.

Believe me I tried - however _Fill is the shader not the material…

[MaterialProperty("_Fill", MaterialPropertyFormat.Float)]
public struct HealthBar : IComponentData{ public float Value; }

with a system doing

        var i = 0;
        Entities.ForEach((Entity e, in MobData m) =>
        {
            var h = (float)m.health / (float)m.Maxhealth;
            mobs[i] =
            new doit {e = e, health = h };
            i++;
        }).Run();
        Entities.ForEach((ref HealthBar h, in Parent p) =>
        {
            var localh = h;
            for (int j = 0; j < mobs.Length; j++)
            {
                if (p.Value == mobs[j].e)
                {
                    localh.Value = mobs[j].health;
                    h = localh;
                    break;
                }
            }
        }).Run();

what happens? the health bar never changes but I know health is going down, and maxhealth is staying the same. PS I checked, mobs[j].health is definitely the right value.

Ok. So let’s back up a little bit. Which version of Unity are you using? Which render pipeline are you using and which version?

Shader graph is really easy for basic effects like this. Learning it will let you easily drive some pretty cool effects directly from DOTS.

Im on 2020.1b6, and using the hybrid renderer 0.4.2 - and as mentioned before, i seriously dont understand shaders!

Which Render Pipeline? Legacy? URP? HDRP? And if URP or HDRP, which version?

You don’t need to understand shaders to understand Shader Graph.