how can i make the division of the health bar like a lol health bar ?

i want know how to make the division like this picture 110657-3zl6hhs.jpg

& another thing how to make that effect of damage on health bar like this ?110658-untitled-2.jpg

1 Like

Here is a little shader I made for you:

  1. Create a new shader and name it “HealthBar”
  2. Open it using MonoDevelop / Visual Studio and copy-paste the code
  3. In Unity, create a new material and select the “Sprites/HealthBar” shader
  4. Create a new UI Image in your scene, and apply the material you have created step 3.
  5. You can put an image in the Image component, but the image type must be set to “Simple”, and “Preserve aspect” must be unchecked

Here is an example image I’ve used:

Healthbar

Thanks to the shader, you will be able to:

  1. Set the main color of the bar if you have an enemy / friend
  2. Indicate the number of “steps” (black bars). If the character has 100 max HP and each little square represents 25HP, then, steps must be equals to 100/25 = 4
  3. Indicate the remaining life (using percentage)
  4. Define the color of the bar when your character takes damages using the inspector
  5. Indicate the damages taken by the character (using percentage)
  6. Define the color of the border using the inspector
  7. Define the width of the border using the inspector

#Result

#Shader code

 Shader "Sprites/HealthBar"
 {
     Properties
     {
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
         [Header(Life)]_Color ("Main Color", Color) = (0.2,1,0.2,1)
         _Steps ("Steps", Float) = 1
         _Percent ("Percent", Float) = 1
     
         [Header(Damages)]_DamagesColor ("Damages color", Color) = (1,1,0,1)
         _DamagesPercent ("Damages Percent", Float) = 0
     
     
         [Header(Border)]_BorderColor ("Border color", Color) = (0.1,0.1,0.1,1)
         _BorderWidth ("Border width", Float) = 1
         [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
     
     
         _ImageSize ("Image Size", Vector) = (100, 100, 0, 0)
     }
 
     SubShader
     {
         Tags
         { 
             "Queue"="Transparent" 
             "IgnoreProjector"="True" 
             "RenderType"="Transparent" 
             "PreviewType"="Plane"
             "CanUseSpriteAtlas"="True"
         }
 
         Cull Off
         Lighting Off
         ZWrite Off
         Blend One OneMinusSrcAlpha
 
         Pass
         {
         CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             #pragma multi_compile _ PIXELSNAP_ON
             #include "UnityCG.cginc"
             
             struct appdata_t
             {
                 float4 vertex   : POSITION;
                 float4 color    : COLOR;
                 float2 texcoord : TEXCOORD0;
             };
 
             struct v2f
             {
                 float4 vertex   : SV_POSITION;
                 fixed4 color    : COLOR;
                 half2 texcoord  : TEXCOORD0;
             };
             
             fixed4 _Color;
             half _Steps;
             half _Percent;
             
             fixed4 _DamagesColor;
             half _DamagesPercent;
             
             fixed4 _BorderColor;
             half _BorderWidth;
 
             v2f vert(appdata_t IN)
             {
                 v2f OUT;
                 OUT.vertex = UnityObjectToClipPos(IN.vertex);
                 OUT.texcoord = IN.texcoord;
                 #ifdef PIXELSNAP_ON
                 OUT.vertex = UnityPixelSnap (OUT.vertex);
                 #endif
 
                 return OUT;
             }
 
             sampler2D _MainTex;
             float4 _ImageSize;
 
             fixed4 frag(v2f IN) : SV_Target
             {
                 fixed4 c = tex2D(_MainTex, IN.texcoord);
                 
                 if ( IN.texcoord.x > _Percent + _DamagesPercent )
                 {
                    c.a = 0 ;
                 }
                 else
                 {
                     if ( IN.texcoord.x > _Percent )
                        c *= _DamagesColor ;
                     else
                     {
                        if( (IN.texcoord.x * _ImageSize.x ) % (_ImageSize.x / _Steps) < _BorderWidth )
                            c *= _BorderColor;
                        else if ( IN.texcoord.y * _ImageSize.y < _BorderWidth )
                            c *= _BorderColor;
                        else
                            c *= _Color;
                     }
                 }
                     
                 
                 c.rgb *= c.a;
                 return c;
             }
         ENDCG
         }
     }
 }

C# code

Here is a C# script to manipulate the HealthBar:

using UnityEngine;
using UnityEngine.UI;

public class HealthBar : MonoBehaviour
{
    [SerializeField]
    private Image image ;
    
    [SerializeField]
    private float maxHealthPoints = 100;
    
    [SerializeField]
    private float healthBarStepsLength = 10;
    
    [SerializeField]
    private float damagesDecreaseRate = 10;
    
    private float currentHealthPoints ;
    
    private RectTransform imageRectTransform ;
    
    private float damages;

    public float Health
    {
        get { return currentHealthPoints; }
        set
        {
            currentHealthPoints = Mathf.Clamp(value, 0, MaxHealthPoints);
            image.material.SetFloat("_Percent", currentHealthPoints / MaxHealthPoints);

            if (currentHealthPoints < Mathf.Epsilon)
                Damages = 0;
        }
    }

    public float Damages
    {
        get { return damages; }
        set
        {
            damages = Mathf.Clamp(value, 0, MaxHealthPoints);
            image.material.SetFloat("_DamagesPercent", damages / MaxHealthPoints);
        }
    }

    public float MaxHealthPoints
    {
        get { return maxHealthPoints; }
        set
        {
            maxHealthPoints = value;
            image.material.SetFloat("_Steps", MaxHealthPoints / healthBarStepsLength);
        }
    }

    protected void Awake()
    {
        imageRectTransform = image.GetComponent<RectTransform>();
        image.material = Instantiate(image.material); // Clone material

        image.material.SetVector( "_ImageSize", new Vector4( imageRectTransform.rect.size.x, imageRectTransform.rect.size.y, 0, 0) );

        MaxHealthPoints = MaxHealthPoints; // Force the call to the setter in order to update the material
        currentHealthPoints = MaxHealthPoints; // Force the call to the setter in order to update the material
    }
    
    protected void Update()
    {
        if( Damages > 0 )
        {
            Damages -= damagesDecreaseRate * Time.deltaTime;
        }
        
        // Dummy test, you can remove this
        if( Input.GetKeyDown(KeyCode.Space) )
        {
            Hurt( 20 );
        }
    }
    
    public void Hurt( float damagesPoints )
    {
        Damages = damagesPoints ;
        Health -= Damages;
    }
}