- Home /
GameObjects color changes on initial load, just not afterwards.
Hello, I've been trying to figure this out on my own through script reference, google, etc, but I can't seem to do it, so I've turned to the community. I've got a main menu for my game, it's pretty simple, just 4 cubes with a text engraving in each that highlight their functions (play, settings, about, quit). When the user mouses over them, they are supposed to move back a bit along the z-axis and turn red, signaling that it is highlighted. So far so good. When the user hits play, the game loads the first level, then if they decide to head back to the main menu, they just pause and select main menu. But now when Unity loads the main menu, the blocks don't change color! They still move and all, but they stay dull and gray. Here is my code for the menu blocks (they all run the same script):
using UnityEngine;
using System.Collections;
public class MenuButtonScript : MonoBehaviour {
public Color initColor = new Color(0,0,0,0);
public Vector3 initPos = new Vector3(0,0,0);
void Start () {
initColor = gameObject.renderer.material.color;
initPos = gameObject.transform.position;
}
void Update () {
}
void OnMouseOver(){
renderer.material.color -= new Color(0,2f,2f) * Time.deltaTime * 2f;
if(Input.GetMouseButtonDown(0)){
if(gameObject.name == "PlayButton"){
Debug.Log ("play");
Application.LoadLevel(1);
}
else if(gameObject.name == "SettingsButton"){
Debug.Log("settings");
}
else if(gameObject.name == "AboutButton"){
Debug.Log ("about");
}
else if(gameObject.name == "QuitButton"){
Application.Quit();
}
else{}
}
}
void OnMouseEnter(){
transform.position = new Vector3(initPos.x,initPos.y,initPos.z + 10f);
}
void OnMouseExit(){
renderer.material.color = initColor;
transform.position = initPos;
}
}
BTW, you don't need to explain like I'm a 5 year old, however, I am new to unity. Thanks for any help!
Answer by iwaldrop · Nov 22, 2013 at 05:07 AM
The OnMouseOver method will be called every frame that your mouse is over the object. What you should really use is the OnMouseDown method, and something like this:
using UnityEngine;
using System.Collections;
using System;
public class ColorChangeOnMouseOver : MonoBehaviour
{
public float transitionTime;
public Color defaultColor;
public Color hoverColor;
public Color pressedColor;
private bool isHovering;
void Awake()
{
renderer.material.color = defaultColor;
}
void OnMouseEnter()
{
isHovering = true;
SetColor(hoverColor);
}
void OnMouseExit()
{
isHovering = false;
SetColor(defaultColor);
}
void OnMouseDown()
{
SetColor(pressedColor, ()=>
{
// do whatever the button is supposed to do here; load level, etc.
if (isHovering)
SetColor(hoverColor);
});
}
void SetColor(Color targetColor, Action callback = null)
{
StartCoroutine(SetColorCoroutine(targetColor, callback));
}
IEnumerator SetColorCoroutine(Color targetColor, Action callback)
{
float startTime = Time.time;
float endTime = startTime + transitionTime;
Color startingColor = renderer.material.color;
while (endTime > Time.time)
{
renderer.material.color = Color.Lerp(startingColor, targetColor, (Time.time - startTime)/transitionTime);
yield return null;
}
if (callback != null)
callback();
}
}
Okay, thanks. Your code looks good to me, however, I'm not familiar with coroutines, from looking at your code I assume that it's what drives the color change though.
Think of coroutines as update loops where you control their starting and stopping individually, and where you can have several running concurrently. The yield statement tells Unity to come back to that point of the method again on the next frame. The fact that it's in a while loop makes it repeat until a condition is met; in this case it's based on a timer.
Coroutines can also be used for asynchronous actions that you would like to perform. Also in this case, I used an Action object as a callback to let me know when the method has finished running. It's what will allow the button color to change to the highlighted color and then run the method.
Checkout the unity docs, and/or google coroutines and the C# Action object to learn more. Also, let me know if your have any more questions about this code, or if it's not working for you. Otherwise, please accept this as answered.
Thanks.