Hello All, I have used this forum many times, and this is the first time I have ever not found what I was looking for exactly, so thank you for everyone’s assistance over the last few months! In advance I would like to apologize if this is a stupid question, but I would really appreciate an answer to this specific question rather than a suggestion to do this in a different method like using the “Animation” transition type etc.
------ REQUEST ------
I would like to print the selection state of a button, once I can do this I can move forward and utilize that information to do what I require so no need to complicate the request.
------ RESEARCH ------
First off I started by adding a script to a button and I started trying to access the selection state, and I thought I was getting close when I found this:
It turns out that this only really prints out the sprite you are using if you are utilizing the below referenced “Sprite Swap” transition type:
I require the “Color Tint” transition type as referenced below:
Next I decided to look at the Button definition to search for clues, here I found a class called “Selectable” which is highlighted in the following image.
Going one level deeper into “Selectable” I found the following at the bottom:
What I would truly love to do is simply put a script on a button that is very simple and prints the SelectionState in the update method.
I can do the rest once I learn how to do this, honestly I think my struggle is coming from learning this on my own and likely missing out of some of the more complex topics that would make this more obvious.
Well the UI code is open sourced on Github, you could probably take Button and make a PowerStackSystemsButton and do what you want with it.
I imagine such a hack would be tiny (such as providing a getter), in case you ever wanted to update to a newer UI in the future: you could easily re-back-cross-port your hack.
Kurt I appreciate your effort, but you simply aren’t answering the question that was asked. I understand that what you are suggesting is an option, what I am asking is if there is a method of accessing this stored information by adding a script to the button, not by duplicating the premade button I was very specific in my original post. If you don’t know how to do that it is ok seriously, but it is neither helpful or clarifying to state most of what you have stated. If it is not possible for some specific reason that would be helpful to know as well, otherwise just leave the thread it is totally fine.
I don’t think there’s a way of directly accessing the current “selected” state, other than a comparison like EventSystem.current.currentSelectedGameObject == myObject
However, rather than checking the selected state in Update, you can attach a script to the button that implements ISelectHandler and IDeselectHandler to get callbacks when the selection state changes like this:
This is somewhat confusing to me, how can there be no way to access the current SelectionState if it is used to set the tint of the graphic and it is shown within the Selected method? Sorry if this is something I should understand already. My problem with using anything you have referenced is that it only tracks what was last clicked, it is not nearly as up to date and preintegrated with the UI system in Unity. The SelectionState number output would be perfect for many implementations for me if I could simply access the 0,1,2,3,4 listed.
As Kurt noted, the selection state variable in Selectable is marked as protected. That means the Unity developers have not chosen to make it directly accessible to other classes. You could make a class that derives from Selectable (or transitively, from Button) and use that instead of the basic Button. In that case your derived type could access its own selection state or even expose it through a public member. Seems easier to go with the ISelectHandler route I detailed above though, but it’s up to you.
I am a little lost on how I would go about implementing that so I think I have some studying to do, again I am not super experienced, but I will do my best to figure it out.
The concept you are looking for is “object inheritance” or creating subclasses. It seems like you all are talking past each other a little bit. Protected means it is accessible to subclasses, so you can make your own class that extends one of the Selectable or Button classes and then you would get access to it.
The suggestion is that perhaps you are monkeying with things that were not meant to be monkeyed with as it was not left particularly accessible by unity devs. Buyer beware and all that. It may be simpler to find another workaround (which you have likely done by now).
Hm, I’ve been trying to code a button that can tint more than just one element. This is pretty easy to do for Select, Deselect and Click.
[SerializeField] private Image[] targetImages;
//Properties
public Image[] TargetImages{get{return targetImages;}}
//Public Methods
public override void OnSelect(BaseEventData eventData)
{
base.OnSelect(eventData);
tintTargetImages(SelectionState.Selected);
}
public override void OnDeselect(BaseEventData eventData)
{
base.OnDeselect(eventData);
tintTargetImages(SelectionState.Normal);
}
public override void OnSubmit(BaseEventData eventData)
{
base.OnSubmit(eventData);
tintTargetImages(SelectionState.Pressed);
}
But how do you do it for the non-interactable and the highlight phase of the button? Is there some overridable function, or Action I could use to do this?
“What I would truly love to do is simply put a script on a button that is very simple and prints the SelectionState in the update method.” Through reflection:
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
public class SelectableStateReader : MonoBehaviour
{
public Selectable AnySelectable;
private PropertyInfo _selectableStateInfo = null;
private void Awake()
{
_selectableStateInfo = typeof(Selectable).GetProperty("currentSelectionState", BindingFlags.NonPublic | BindingFlags.Instance);
}
private void Update()
{
Debug.Log(_selectableStateInfo.GetValue(AnySelectable));
}
If you want to actually use the value you can do it like that:
private void Update()
{
int selectableState = (int)_selectableStateInfo.GetValue(AnySelectable);
switch (selectableState)
{
case 0:
//Normal Selection State
break;
case 1:
//Highlighted Selection State
break;
case 2:
//Pressed Selection State
break;
case 3:
//Selected Selection State
break;
case 4:
//Disabled Selection State
break;
}
}
Works with anything inheriting from Selectable. Buttons, dropdowns, etc.