Search code examples
c#unity-game-enginebuttonhighlightunity-ui

I want to make Highlightable button while PointerEnter in Unity2D Canvas but that should be Unselectable


Buttons cannot be highlighted when they are selected in Unity Canvas. I only want mausehover/pointerEnter thing.

I am making a platform based 2D mobile game. Users can move their fingers without take off from the screen. So I don't need Pressed and Selected states.

The alpha of the button will be maximum when it is in PointerEnter state, and the alpha of the button will be like 100/255 when it is in PointerExit state. That's it.

Tried something like change Transition to Sprite Swap; like trying Toggle component instead of Button in Unity. But I'm stuck, I don't know solution is.


Solution

  • You could not use the Button component at all and rather have a simple component and "do it all yourself" - as you say using the IPonterEnterHandler / IPointerExitHandler interfaces

    public class HoverButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
    {
        [SerializeField] private Image image;
        [SerializeField] private Color normal = new Color(1f, 1f, 1f, 0.4f);
        [SerializeField] private Color hover = Color.white;
    
        // event called when pointer enters this button
        public UnityEvent onEnter;
        // event called once a frame while the button stays hovered
        public UnityEvent whileHovered;
        // event called when pointer exits this button
        public UnityEvent onExit;
    
        // wasn't sure if you still want fade effects 
        // if not you can of course skip all related stuff and just hard assign the image.color
        [SerializeField][Min(0f)] private float fadeDuration = 0.2f;
        
        private Coroutine currentRoutine;
        private float currentFactor;
    
        private void Awake()
        {
            if(!image) image = GetComponent<Image>();
        }
    
        private IEnumerator Fade(bool isHover)
        {
            var targetColor = isHover ? hover : normal;
            var targetFactor = isHover ? 1f : 0f;
    
            if(fadeDuration > 0f)
            {
                var step = (isHover ? (1 - currentFactor) : currentFactor) / fadeDuration;
    
                while(!Mathf.Approximately(currentFactor, targetFactor))
                {
                    currentFactor = Mathf.MoveTowards(currentFactor, targetFactor, step * Time.deltaTime);
                    image.color = Color.Lerp(normal, hover, currentFactor);
                    whileHovered.Invoke();
                    yield return null;
                }
            }
    
            currentFactor = targetFactor;
            image.color = targetColor;
    
            // continue calling the whileHovered every frame
            while(true)
            {
                whileHovered.Invoke();
                yield return null;
            }
        }
    
        public void OnPointerEnter(PointerEventData pointerEventData)
        {
            if(currentRoutine != null) StopCoroutine(currentRoutine);
    
            currentRoutine = StartCoroutine(Fade(true));
    
            onEnter.Invoke();
        }
    
        public void OnPointerExit(PointerEventData pointerEventData)
        {
            if(currentRoutine != null) StopCoroutine(currentRoutine);
    
            currentRoutine = StartCoroutine(Fade(false));
    
            onExit.Invoke();
        }
    }