Daniel Lip
Daniel Lip

Reputation: 11319

How can I make a button to act like a toggle or maybe using a toggle and make the toggle to looks like a button?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class GenerateUIButtons : MonoBehaviour
{
    public Button buttonPrefab;
    public GameObject parent;
    public int numberOfButtons;
    public float spaceBetweenButtons;

    private Button[] buttons;

    // Start is called before the first frame update
    void Start()
    {
        buttons = new Button[Rotate.names.Length];

        for (int i = 0; i < buttons.Length; i++)
        {
            buttons[i] = Instantiate(buttonPrefab) as Button;
            buttons[i].name = Rotate.names[i];
            buttons[i].transform.SetParent(parent.transform, false);
            int j = i;
            buttons[i].onClick.AddListener(() => ButtonClicked(j));
        }
    }

    void ButtonClicked(int buttonNo)
    {
        Debug.Log("Clicked On " + buttons[buttonNo]);
    }

    // Update is called once per frame
    void Update()
    {

    }
}

I want that inside the ButtonClicked when clicking on a button the text inside color will change to green and stay green for the clicked button. And if clicking on the same green button again change the color back to the original.

Like a switch.

Upvotes: 0

Views: 3336

Answers (1)

giacomelli
giacomelli

Reputation: 7407

I created a custom one few days ago, take a look on the code below.

Here you can see it in action: https://youtu.be/sl9EheTbmhE

ToggleButton.cs

using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[RequireComponent(typeof(Image))]
public class ToggleButton : MonoBehaviour, IPointerClickHandler
{
    public ToggleEvent CheckedChanged = new ToggleEvent();

    Image _image;
    Color _originalColor;

    bool _checked;
    [SerializeField] Color _checkedColor;
    [SerializeField] ToggleButtonGroup _group;


    [SerializeField]
    public bool Checked
    {
        get
        {
            return _checked;
        }
        set
        {
            if (_checked != value)
            {
                _checked = value;
                UpdateVisual();
                CheckedChanged.Invoke(this);
            }
        }
    }

    void Start()
    {
        _image = GetComponent<Image>();
        _originalColor = _image.color;

        if (_group != null)
            _group.RegisterToggle(this);
    }

    private void UpdateVisual()
    {
        _image.color = Checked ? _checkedColor : _originalColor;
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        Checked = !Checked;
    }

    [Serializable]
    public class ToggleEvent : UnityEvent<ToggleButton>
    {
    }
}

ToggleButtonGroup.cs

using System.Collections.Generic;
using UnityEngine;

public class ToggleButtonGroup : MonoBehaviour
{
    List<ToggleButton> _toggles = new List<ToggleButton>();

    public void RegisterToggle(ToggleButton toggle)
    {
        _toggles.Add(toggle);
        toggle.CheckedChanged.AddListener(HandleCheckedChanged);
    }

    void HandleCheckedChanged(ToggleButton toggle)
    {
        if (toggle.Checked)
        {
            foreach (var item in _toggles)
            {
                if (item.GetInstanceID() != toggle.GetInstanceID())
                {
                    item.Checked = false;
                }
            }
        }
    }
}

Upvotes: 1

Related Questions