Changing a texture as a float or int drops
Hi
For my first game, i decided to make a game based on my first pc game, Colobot.
Colobot has these batteries:
They have limited energy of course, and as the energy drops, they start to turn from green to red (like the image above).
This is my model's uv(if helps in some way):
My question is, how can i make this effect in c#?
sorry for english mistakes.
Answer by Eno-Khaon · Jan 19, 2016 at 01:43 AM
Most of what would be implemented for this visual effect will be inherited from a shader. Therefore, I'll start by using Unity's Surface Shader Example page as a baseline.
Now, there are multiple ways this effect can be applied. Based on the screenshot, it appears there are two different textures being blended between (rather, there appear to be rings around the green batteries, whereas the red one appears to be mainly a single color). With this in mind, I'll work on the assumption that there are two textures. I'll also work on the assumption that the transition between colors will be based on a gauge, rather than on a color fade.
If the battery textures aren't currently utilizing their alpha channel, then this becomes particularly simple to handle.
By aligning a gradient with the sides of the batteries in the alpha channel of the battery's texture (either one), you'll have a reusable control available to display the current state of the battery.
Here's an example of a quick modification to one of the example surface shaders, assuming the "Full Battery" texture has a gradient in its alpha channel:
Shader "Battery Level Example"
{
Properties
{
_EmptyTex ("Texture", 2D) = "black" {}
_FullTex ("Texture", 2D) = "white" {}
_BatteryLevel ("Battery Level", Range(0.0, 1.0)) = 1.0
}
SubShader
{
Tags { "RenderType" = "Opaque" }
CGPROGRAM
#pragma surface surf Lambert
struct Input
{
float2 uv_EmptyTex;
float2 uv_FullTex;
};
sampler2D _EmptyTex;
sampler2D _FullTex;
float _BatteryLevel;
void surf (Input IN, inout SurfaceOutput o)
{
float4 emptyColor = tex2D(_EmptyTex, IN.uv_EmptyTex);
float4 fullColor = tex2D(_FullTex, IN.uv_FullTex);
float blend = saturate(ceil(_BatteryLevel - fullColor.a));
float4 combinedColor = lerp(emptyColor, fullColor, blend);
o.Albedo = combinedColor;
}
ENDCG
}
Fallback "Diffuse"
}
Then, you can change the value of _BatteryLevel rather simply in a C#/JS script to reflect the current battery level.
// C#
using UnityEngine;
using System.Collections;
public class SetBatteryLevel : MonoBehaviour
{
public Renderer rend;
void Start()
{
rend = GetComponent<Renderer>();
}
void Update()
{
float level = Mathf.PingPong(Time.time, 1.0F);
rend.material.SetFloat("_BatteryLevel", level);
}
}
If this doesn't work directly for how you're hoping for it, I hope it at least gets you started in the right direction!