Mark Quinn
Mark Quinn

Reputation: 79

Changing a shader blend on pointer click over time

I have a shader in Unity that is set up to blend between two textures. This is set up and works fine.

Blend has a range from 0-1 and works well on offline mode.

    _Blend1("Blend between _MainTex and Texture2", Range(0, 1)) = 0

I have set up an OnClick pointer that works fine. It essentially toggles a value to true and activates it in the Update. I have had some success on toggling the values between 0 (The first texture and 1 (The second texture).

    public void OnColorChangeClick()
{
    if (newSwitchOne)
    {
        switchOn = true;         
    }
    else if (newSwitchTwo)
    {
        switchOff = true; 
    }
}

In the update when switchOn is true I have a while loop that runs and increments a count for the blend.

 void Update()
{
    rend.material.SetFloat("_Blend1", up);
    while (switchOn == true) {
        for (int i = 0; i < 10; i++)
        {
           //StartCoroutine(Wait());
            up = Time.deltaTime * (up + 0.1f);
        }
        switchOn = false;
        print(switchOn);
    }
}

The trouble I am having is that the value increments are not working alongside time.deltaTime. I am seeing that Time.deltatime may not work in a while loop. So I have also tried a CoRoutine with a WaitForSeconds. None of this is giving me the incrementation that I desire.

I have looked into Lerping this - but I'm not aware how to Lerp such a value - I have been looking, perhaps in the wrong places.

Can someone point me in the right direction?

Upvotes: 0

Views: 409

Answers (2)

Update() already runs "over time." You don't need a for loop or a coroutine. You just need to track a variable that changes inside the Update() method body.

up = Time.deltaTime * (up + 0.1f);

Oh wait, you already do.

void Update()
{
    rend.material.SetFloat("_Blend1", up);
    if(switchOn == true) {
        up = Time.deltaTime * (up + 0.1f);
        if(up >= 1) {
            switchOn = false;
        }
        print(switchOn);
    }
}

Ta da.

However, you still need code to bring the value back down again (either animating it back to 0 or just setting it to 0) but your original code didn't have it either, so I'm not including it.

Upvotes: 2

ryeMoss
ryeMoss

Reputation: 4343

Time.deltaTime returns the time it took to complete the last frame so it will be roughly constant as you loop through (and a very small value) - which is keeping your up value to remain tiny. You should be able to lerp the value like so.

float t = 0;

void Update()
{
    if (switchOn == true)
    {
        t += Time.deltaTime;
        rend.material.SetFloat("_Blend1", Mathf.Lerp(0, 1f, t/3f)); //3 is time to complete lerp
    }
    if (t > 3) // lerp has completed. reset function and timer.
    {
        t = 0;
        switchOn = false;
    }
}

Upvotes: 2

Related Questions