Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I want to have a GameObject that has a "hovering" effect when the mouse is over it.

What I'm having trouble with is actually having a color that gradually goes from one color to the next. I'm assuming Color.Lerp() is the best function for that, but I can't seem to get it working properly.

Here's my CubeBehavior.cs's Update() function:

private bool ReachedTop = false;
private float t = 0f;
private float final_t;
private bool MouseOver = false;

// Update is called once per frame
void Update () {
    if (MouseOver) {
        t = Time.time % 1f; // using Time.time to get a value between 0 and 1
        if (t >= 1f || t <= 0f) // If it reaches either 0 or 1...
            ReachedTop = ReachedTop ? false : true; 

        if (ReachedTop) final_t = 1f - t; // Make it count backwards
        else final_t = t;

        print (final_t); // for debugging purposes
        renderer.material.color = Color.Lerp(Color.red, Color.green, final_t);
    }
}

void OnMouseEnter() {
    MouseOver = true;
}

void OnMouseExit() {
    renderer.material.color = Color.white;
    MouseOver = false;
}

Now, I've tried several approaches to making it reach 1 then count backwards till 0 including a multiplier that alternates between 1 and -1, but I just can't seem to get that effect. The value goes to 1 then resets at 0.

Any ideas on how to do this?

share|improve this question
    
not exactly sure what kind of "hover" effect you want to achieve, could you be more specific? –  melak47 Jul 5 '12 at 11:07
    
@melak47 The code is self explanatory: hovering over the cube would make it change colors, slowly and gradually between (in this example) red and green; it starts red/green, slowly becomes a cross of both, and eventually becoming the other color. I don't care which starts. That's actually irrelevant anyways; the real question is how do I use Time.time (or any better replacement you can think of) to have a number that goes from 0 to 1 as a float, and when reaches 1, changes direction and counts backwards to 0, (0.9->0.8->0.7->...) and the repeats the other way around. –  Chen Asraf Jul 5 '12 at 11:14
1  
As a longer-view heads up, by the way: now that you have the basics of your color interpolation working, you'll probably want to replace your Color.Lerp call with a custom call to interpolate between two colors. The issue is that interpolation between colors in RGB space tends to give really ugly intermediate colors (e.g., red to green goes through brown). At the very least you should interpolate in something like HSV (Hue-Saturation-Value) coordinates; for an even more detailed approach, check out the blog post at stuartdenman.com/improved-color-blending . –  Steven Stadnicki Jul 5 '12 at 18:10
add comment

4 Answers

up vote 2 down vote accepted

Found the solution... Just used my own float instead of using Time.time.

private bool CountBack = false;
private float Speed = 0.01f;
private float t = 0f;
private float final_t;
private bool MouseOver = false;

// Update is called once per frame
void Update () {
    if (MouseOver) {
        if (!CountBack) {
            t += Speed;
            if (t >= 1f) CountBack = true;
        }
        else {
            t -= Speed;
            if (t <= Speed) CountBack = false;
        }
        final_t = t;
        print (CountBack + "("+final_t+")");
        renderer.material.color = Color.Lerp(Color.red, Color.green, final_t);
    }
}
share|improve this answer
1  
you can mark your own answer, it looks good –  dreta Jul 5 '12 at 12:39
    
@dreta Only lets me do it in 2 days so I'll come back to it –  Chen Asraf Jul 5 '12 at 12:59
add comment

I don't think if (t >= 1f || t <= 0f) is ever executed, have you tried stepping through it with a debugger?

For sure t >= 1f is never going to be true, because of how % works. t <= 0f is going to be true in extremely rare situations, it's definetly never going below 0 and i daubt it'll ever reach zero simply because you're dealing with finite precision.

If i was to suggest something, try using 0.9 instead of 1 and 0.1 instead of 0 or something, i've no idea how precise the timer you're using is. The rest of the logic should work fine.

EDIT: The author answered his own question, still i'm leaving a different solution to this in C++.

#include <iostream>

int main () {

    float i = 0.f, final_i;
    bool swap = false;

    for(unsigned int k = 0; k < 30; ++k){

        i += 0.1f;

        if ( i >= 1.f ) {
            i = 0.f;
            swap = swap ? false : true;
        }

        if ( swap ) {
            final_i = 1.f - i;
        }
        else{
            final_i = i;
        }

        std::cout<<final_i<<std::endl;
    }

    system("pause");

    return 0;
}
share|improve this answer
    
Debugging this did work and the variables did change, but I'm not sure if often enough, whatever the result though, it didn't ever do this properly, I'll try to change that, thanks. Can you think of better logic to work it? –  Chen Asraf Jul 5 '12 at 11:46
    
@OhMrBigshot but does the value of ReachedTop change when you step through the code? –  dreta Jul 5 '12 at 11:54
    
It does. RIght now I simply used return; after changing ReachedTop if it's true, and the effect is much smoother - but it still has jumps now and then (like every 3-4 seconds). I'm using 0.03 and 0.97 for the checks, and anything farther from the integers than that results in a million jumps. –  Chen Asraf Jul 5 '12 at 12:04
add comment

Alternately:

t = Time.time % 2f;
if (t > 1f)
    t = 2f - t;

This will also give you a 't' value which smoothly loops back and forth along the interval [0..1..0].

share|improve this answer
add comment

iTween has a ColorTo method that might work as well..

http://itween.pixelplacement.com/documentation.php

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.