I'm a amateur programmer having used code mainly for artistic purposes, I"m a VJ musician, etc. etc. I know the basics of programming having used java in Processing and Eclipse.
I'm loving the possibilities of unity for live performance.
I have created my first script - just to change a materials colour using the mouse, but presumably the material glitches because I am attempting to change the material to quickly. Any suggestions how I should guard against this. How can I ensure the the mesh's material will change smoothly and whithout artifacting.
I have attached the script below to a mesh.
function Update () {
var x = Input.GetAxis("Mouse X");
print(x);
var color = Color (0.2, x, 0.9);
renderer.material.SetColor ("_Color", color);
}
Hey there. First off, I think it's a very interesting idea!
The glitch that you're seeing isn't actually to do with changing the material too quickly. There are a few reasons:
The value of GetAxis is updating
every frame, which is ~0.0166
seconds at 60FPS. If your mouse
input rate fluctuates even SLIGHTLY
in that time, you'll get fairly
drastic colour changes, which is why
some frames it flickers white, and
then back to strong blue.
GetAxis returns a value from -1 to
1, so when the mouse is still, or
moving slightly to the left, the
object will be full blue. You can
add 1 and halve the result to get it
as a value between 0 and 1. Also, on
frames that you aren't moving the
mouse, the GetAxis movement will be 0.
Even with the '(value+1)/2' workaround
I suggested, you'll need
to ifcheck for the input being 0.
I can think of a few ways you might try to fix this.
Limit the amount that the color can change per frame (in my opinion, best result so far):
var maxChange : float = 0.05; // maximum amount the color can change by per frame
function Update ()
{
var inputX : float = Input.GetAxis("Mouse X");
if ( inputX != 0 )
{
inputX = (inputX+1)/2;
var currGValue : float = renderer.material.color.g;
var colorX : float = Mathf.Clamp(inputX, currGValue-maxChange, currGValue+maxChange);
renderer.material.color = Color(0.2, colorX, 0.9);
}
}
Average the input and only change the color once every few updates:
var updateFrequency : float = 0.15; // seconds between update
private var inputX : float = 0.0; // the accumulative x input per frame
private var updateTime : float = 0.0; // the accumulated update delta time
private var updates : int = 0; // actual number of updates
function Update ()
{
inputX += (Input.GetAxis("Mouse X")+1)/2;
updateTime += Time.deltaTime;
updates++;
if ( updateTime >= updateFrequency )
{
var colorX = Color (0.2, inputX/updates, 0.9);
updateTime = inputX = updates = 0;
renderer.material.SetColor ("_Color", colorX);
}
}
Lerp between the colors with a clamped change of rate.
I'm still working through some ideas myself. I have noticed that very small input values can still make the color appear to flicker.