- Home /
How to change text color on hover in new GUI?
Using Unity 5 GUI, suppose I want text only menu buttons.
I make buttons with text children and disable the button's image script, so the button background does not draw, I see text only as desired.
However, the colors (normal, highlighted, pressed, disabled) do not apply to the text color. They seem to apply only to the image, which I disabled.
How can I have the text color change when the button UI is manipulated?
Also a bit of a meta comment: there needs to be a sticky FAQ thingy explaining which tags to use for old GUI stuff vs. new GUI stuff. Too convoluted, too hard to search.
Answer by lordlycastle · Apr 04, 2015 at 11:34 PM
You can do by scripting, but that’s just painful. You should rather watch this video. It tells you how to create transitions when hovering over, or clicking etc an UI element.
O$$anonymous$$ that video seems to be the best way to do it, thanks.
Answer by jcv8000 · Apr 04, 2015 at 11:27 PM
You could use the button to receive the mouse hover. Add this script to each of the buttons:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class MenuButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler {
public Text theText;
public void OnPointerEnter(PointerEventData eventData)
{
theText.color = Color.red; //Or however you do your color
}
public void OnPointerExit(PointerEventData eventData)
{
theText.color = Color.white; //Or however you do your color
}
}
(Sorry about the code not formatting correctly in the post)
set the value with this code: this.GetComponentInChildren().color = Color.red; so you don't have to have the variable "theText" at all and set it in each button where you wish this to happen...
simunovic100, see my fully plug-and-play answer on the second page...
sorry, didn't see page 2...new here...you are right, your script looks good, we don't need "this" keyword as I wrote...thanx
I still get the message "Script needs to derive from monobehaviour" after using this code anybody know how to fix this?
Answer by domussolisortum · Jan 06, 2017 at 04:59 PM
For posterity's sake, here's a C# script to change the color of Text on a GUI Button, inspired by jcv8000's script. The main difference is that this script is fully automatic and covers more cases than the others posted so far.
Features:
This script takes the text's original color into account and multiplies it by the color values that are already specified in the Button script and by the Button's color multiplier. The change in the Text's color will always match the change in the Button's color.
It has cases to handle the Button being disabled, and it even works if you've disabled the Button from an external script.
All you need to do is add the script to the Button object. No fuss.
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using UnityEngine.UI;
[RequireComponent (typeof(Button))]
public class MenuButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler
{
Text txt;
Color baseColor;
Button btn;
bool interactableDelay;
void Start ()
{
txt = GetComponentInChildren<Text>();
baseColor = txt.color;
btn = gameObject.GetComponent<Button> ();
interactableDelay = btn.interactable;
}
void Update ()
{
if (btn.interactable != interactableDelay) {
if (btn.interactable) {
txt.color = baseColor * btn.colors.normalColor * btn.colors.colorMultiplier;
} else {
txt.color = baseColor * btn.colors.disabledColor * btn.colors.colorMultiplier;
}
}
interactableDelay = btn.interactable;
}
public void OnPointerEnter (PointerEventData eventData)
{
if (btn.interactable) {
txt.color = baseColor * btn.colors.highlightedColor * btn.colors.colorMultiplier;
} else {
txt.color = baseColor * btn.colors.disabledColor * btn.colors.colorMultiplier;
}
}
public void OnPointerDown (PointerEventData eventData)
{
if (btn.interactable) {
txt.color = baseColor * btn.colors.pressedColor * btn.colors.colorMultiplier;
} else {
txt.color = baseColor * btn.colors.disabledColor * btn.colors.colorMultiplier;
}
}
public void OnPointerUp (PointerEventData eventData)
{
if (btn.interactable) {
txt.color = baseColor * btn.colors.highlightedColor * btn.colors.colorMultiplier;
} else {
txt.color = baseColor * btn.colors.disabledColor * btn.colors.colorMultiplier;
}
}
public void OnPointerExit (PointerEventData eventData)
{
if (btn.interactable) {
txt.color = baseColor * btn.colors.normalColor * btn.colors.colorMultiplier;
} else {
txt.color = baseColor * btn.colors.disabledColor * btn.colors.colorMultiplier;
}
}
}
This is a neat script, and should definitely be default behavior in Unity.
Two comments, though: It doesn't take Fade Duration into account and it doesn't take the Pressed Color into account.
Thanks for your reply. I have intended to incorporate Fade Duration but have yet to decide on the optimal method of transitioning between two colors. As for Pressed Color I'm not certain that's different from OnPointerDown. What I would also like to do is expand this script so that it accounts for keyboard interaction with buttons as well as pointer interaction.
Looking into it, I believe the correct way to do it is:
txt.CrossFadeColor(btn.colors.highlightedColor, btn.colors.fadeDuration, true, true);
I believe all your multiplication of colors is unnecessary, since this makes it 100% controlled through the Inspector.
It works very well but not for keyboard/controller input. I'm really looking forward on you figuring out another optimized script with more input support :).
Answer by zeroblackstar · Sep 09, 2015 at 11:25 AM
Right click Canvas, got to UI, add a Text element. On this text element click on add component and under UI select button.
You now have a button script attached to your text element, change the highlight colour in the button script, click Play and bask in the radiant glow of your new highlighting UI text.
Answer by x4000 · Sep 19, 2017 at 08:56 PM
Building on what @domussolisortum created, and:
making it compatible with TextMeshPro (now free)
as well as fixing a bug where if you were holding down the mouse button on a button and then moused out of it it would stay in the pressed state
as well as allowing for different colors on the text compared to the main button state, since you might be using sprite swaps on the main button for instance.
and finally, making it so that the individual states for things aren't scattered all over the place and thus potentially conflicting with one another:
Code:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using TMPro;
[RequireComponent( typeof( Button ) )]
public class FullyReactiveButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler
{
private TextMeshProUGUI txt;
private Button btn;
public Color normalColor;
public Color disabledColor;
public Color pressedColor;
public Color highlightedColor;
void Start()
{
txt = GetComponentInChildren<TextMeshProUGUI>();
btn = gameObject.GetComponent<Button>();
}
private ButtonStatus lastButtonStatus = ButtonStatus.Normal;
private bool isHighlightDesired = false;
private bool isPressedDesired = false;
void Update()
{
ButtonStatus desiredButtonStatus = ButtonStatus.Normal;
if ( !btn.interactable )
desiredButtonStatus = ButtonStatus.Disabled;
else
{
if ( isHighlightDesired )
desiredButtonStatus = ButtonStatus.Highlighted;
if ( isPressedDesired )
desiredButtonStatus = ButtonStatus.Pressed;
}
if ( desiredButtonStatus != this.lastButtonStatus )
{
this.lastButtonStatus = desiredButtonStatus;
switch ( this.lastButtonStatus )
{
case ButtonStatus.Normal:
txt.color = normalColor;
break;
case ButtonStatus.Disabled:
txt.color = disabledColor;
break;
case ButtonStatus.Pressed:
txt.color = pressedColor;
break;
case ButtonStatus.Highlighted:
txt.color = highlightedColor;
break;
}
}
}
public void OnPointerEnter( PointerEventData eventData )
{
isHighlightDesired = true;
}
public void OnPointerDown( PointerEventData eventData )
{
isPressedDesired = true;
}
public void OnPointerUp( PointerEventData eventData )
{
isPressedDesired = false;
}
public void OnPointerExit( PointerEventData eventData )
{
isHighlightDesired = false;
}
public enum ButtonStatus
{
Normal,
Disabled,
Highlighted,
Pressed
}
}