Disable a single Dropdown option.
Hello!
I have a player setup scene where multiple players can choose their profession, they are listed in a Dropdown. When a player chooses a profession, it becomes unavailable for other players.
Right now I have a list that holds the profession name and its availability. The availability gets changed correctly and I was thinking of using that, but I got stumped at disabling the profession option in the Dropdown. Also, I'm looping through the list using a for loop, and checking the indexes to match the options for disabling.
Is it even possible to disable a single option? Seems kinda weird that that kind of a functionality is not present or easily accessible. Or is there possibly a hacky way of doing that? I mean, I can check for a match and display a message that a player should change his profession, but that's pretty much last resort.
Yeah, there is, I remember when I did a system like that...
Each Item in the Dropdown menu has an Toggle script attached, which has a variable called "Interactable". Just turn it to false.
Yeah, I noticed, but it's there only when the dropdown is open. When I collapse it or select an option, the reference to that Toggle disappears and I can't really do anything with that, as far as my knowledge goes.
Just store the options index (starting from 1, not zero) and everytime that you are going to open your dropdown menu, call that method:
[SerializeField] private RectTransform dropdown$$anonymous$$enu;
public void SetItensDisabled(int[] indexArray)
{
var content = dropdown$$anonymous$$enu.GetChild(3).GetChild(0).GetChild(0);
foreach (var index in indexArray)
{
content.GetChild(index).GetComponent<Toggle>().interactable = false;
}
}
We start at index "1" because that the first child of your content menu is just a copy of the GameObject "item" from the template, so it should remain disabled anyway.
Answer by MarkKreitler · Nov 19, 2017 at 09:33 PM
@Malkyne's reply is complete, but here's a little more detail:
To toggle individual Dropdown items' 'active' state:
1) Find the 'item' template in the hierarchy beneath your Dropdown a) You will probably find it under Dropdown -> Template -> Viewport -> Content -> Item b) This Item should have a "Toggle" script on it by default.
2) Add a script to this item. a) The script should get the item's Toggle component b) The script should set the item's 'isInteractable' bool in the Start() method
Example:
using UnityEngine;
using UnityEngine.UI;
namespace DropdownItemExample {
public class InitDropdownItem : MonoBehaviour {
[Serializable]
private MyGameController gameController = null;
protected void Start() {
Toggle toggle = gameObject.GetComponent<Toggle>();
if (toggle != null && gameController != null) {
toggle.interactable = gameController.IsItemSelectable(this);
}
}
}
}
Here, MyGameController is the object that manages your game. It could be something else. You could also have the 'item' set it's own toggle based on internal variables (like the string or sprite being displayed on the item).
Here's the key to remember: The Dropdown will create a new set of items every time the user opens the list. This means the Items' Start() method will get called every time the list opens, and that's the only time the item instances exist. That's why they have to set their toggles in the Start() method.
Answer by Malkyne · Jun 09, 2016 at 10:26 PM
You can modify the prototype Item inside the Dropdown Template in any way you feel is necessary. This includes adding scripts.
In your Start() function, you can then call out elsewhere, to see whether this item is allowed to be interacted with. When Start is running, your transform.GetSiblingIndex() should give you a correct index of this item.
So, you might write something that looks like this:
public class CharacterOptionItem : MonoBehaviour
{
[SerializeField]
private ScreenManager _screenManager;
private void Start()
{
GetComponent<Toggle>().interactable =
_screenManager.IsItemEnabled(transform.GetSiblingIndex() - 1);
}
}
Drop your script on the prototype item, and then, make sure to hook up your external authority (in this example, _screenManager), and it will be hooked up for all the child items.
Aaand what the heck would be in your Screen$$anonymous$$anager class? I tried this, and I can't figure out your IsItemEnabled function.