Yay … Shaders (a breakthrough)

While I didn’t exactly create this shader from scratch, I did have to try and work out how it was working.  It was originally set up to work from a UV, which is to say that it had a range of 0 – 1.  I, however wanted to fork of a texture that was not a UV and had to “reverse engineer” this solution.  The original tutorial was from https://www.youtube.com/watch?v=fjJacIFxEM8 and created by user prime[31].

My first problem came from the _HealthBarMix being a “fixed” variable, which was fine when it was tracking information for a UV (0 – 1) as the fixed has a range of +-2. Through trial and error, I found that this range was not enough to get the entire coverage for my textures.

I had to go up to the next variable which was a “half” which has a range of +- 60k.  I discovered that the range of -5 to 5 covered the entire texture ( from full health to no health).  The tutorial also showed that they way they personally set up shaders, was to use VertexInput and FragmentInput.  On relfection, FragmentInput was not really different to VertexOutput.  As our tutor seems to prefer using the two Vertex Structs, I changed it around to make sure that was the case with my shader.

 

The full shader code :

 

Shader “Custom/HealthTextureMix” {
Properties {
_MainTex (“Main Texture”, 2D) = “white” {}
_SecondTex (“Second Texture”, 2D) = “white” {}
_HealthBarMix (“Health Bar Wipe”, Range (-5,5)) = 0
}
SubShader {
Tags { “RenderType”=”Geometry” }

Pass
{

CGPROGRAM
#pragma exclude_renderers ps3 xbox360 flash
#pragma vertex vert
#pragma fragment frag

#include “UnityCG.cginc”

uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform sampler2D _SecondTex;
uniform float4 _SecondTex_ST;
uniform half _HealthBarMix;

struct VertexInput {
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
};
struct VertexOutput {
float4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
half2 uv2 : TEXCOORD1;
fixed2 localPos : TEXCOORD2;

};

VertexOutput vert(VertexInput i)
{
VertexOutput o;
o.localPos = i.vertex.xy; // + fixed2 (0.5, 0.5);
o.pos = mul(UNITY_MATRIX_MVP, i.vertex);
o.uv = TRANSFORM_TEX (i.texcoord, _MainTex);
o.uv2 = TRANSFORM_TEX (i.texcoord, _SecondTex);

return o;
}

float4 frag(VertexOutput i) : COLOR {

fixed4 mainTexColour = tex2D (_MainTex, i.uv);
fixed4 secondTexColour = tex2D (_SecondTex, i.uv2);

if(i.localPos.x < _HealthBarMix)
{
return mainTexColour;
}
else
{
return secondTexColour;
}
}
ENDCG
}
}

}

 

Now the challenge was to try and get access to the _HealthBarMix through my scripts and alter it through the GameDirector, who was looking after any damage that the player was going through.

The following script was attached to the HealthBar :

using UnityEngine;
using System.Collections;

public class HealthBar : MonoBehaviour {

private Material _mat;
private float health;

void Start () {
//sets the material to the HealthBar material
_mat = this.renderer.material;
//        _mat = renderer.material.shader;
//

//        health = 0f;

}

void Update () {
//health in the GameDirector is always positive, so I need to -5 to get it into the range of the shader (-5 to +5)
health = GameDirector.inst.currentHealth – 5f;
//sets health to the HealthBarMix and effectively displays the current health
_mat.SetFloat(“_HealthBarMix”, health );
}
}

.. along with the following code in the Update of GameDirector:

void Update ()
{
//deal with the player if he dies.
if(currentHealth <= 0 && !didPlayerBlowUp)
{
currentHealth = totHealth;
RestartAtLastCheckpoint();
}

//slow depletion of players health
currentHealth -= (Time.deltaTime / depletionRate);
//CHEAT CODE to get more health
if (Input.GetKey (KeyCode.RightControl))
currentHealth = totHealth;
}

HealthBar material.

HealthBar material.

Game test screen shot.

Game test screen shot.

This gives me an effective floating health bar (created with another short script that gives it a position above the y position of the player) that utilises a shader and doesn’t have to rely on the GUI.

Advertisements

One thought on “Yay … Shaders (a breakthrough)

  1. Pingback: Postmortem on “Valour” .. my latest group project. | richarddanielstein

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s