Instantly share code, notes, and snippets.
dylanwolf/Submenu.cs Secret
Created
April 11, 2023 05:01
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save dylanwolf/603980854435b22c50c6c3833c87099e to your computer and use it in GitHub Desktop.
Unity UI Submenu
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.EventSystems; | |
using UnityEngine.UI; | |
public class Submenu : MonoBehaviour { | |
[System.NonSerialized] | |
public SubmenuItem SelectedItem; | |
Selectable firstAvailable; | |
public SubmenuItem[] Items; | |
GameObject[] objects; | |
public Selectable Previous; | |
public Selectable Next; | |
public Sprite InactiveFrame; | |
public Sprite ClearFrame; | |
EventSystem evt; | |
public enum ButtonDirection | |
{ | |
Horizontal, | |
Vertical | |
} | |
public ButtonDirection Direction; | |
private void Start() | |
{ | |
InitChildren(); | |
} | |
bool hasInit = false; | |
public void InitChildren() | |
{ | |
if (!hasInit) | |
{ | |
for (int i = 0; i < Items.Length; i++) | |
{ | |
InitChild(Items[i]); | |
} | |
RewireControls(); | |
hasInit = true; | |
} | |
} | |
void InitChild(SubmenuItem child) | |
{ | |
Debug.Log("Setting " + child.name + " to " + this.name); | |
child.Container = this; | |
child.Selectable.SetNavigationType(Navigation.Mode.Explicit); | |
} | |
void SetNextAndPrevious(Selectable sel, Selectable previous, Selectable nxt) | |
{ | |
if (Direction == ButtonDirection.Horizontal) | |
sel.SetLeftAndRight(previous, nxt); | |
else | |
sel.SetUpAndDown(previous, nxt); | |
} | |
void SetPrevious(Selectable sel, Selectable prev) | |
{ | |
if (Direction == ButtonDirection.Horizontal) | |
sel.SetLeft(prev); | |
else | |
sel.SetUp(prev); | |
} | |
void SetNext(Selectable sel, Selectable nxt) | |
{ | |
if (Direction == ButtonDirection.Horizontal) | |
sel.SetRight(nxt); | |
else | |
sel.SetDown(nxt); | |
} | |
public void RewireControls() | |
{ | |
firstAvailable = null; | |
int? lastIndex = null; | |
for (int i = 0; i < Items.Length; i++) | |
{ | |
// Set enter/exit navigation | |
if (Direction == ButtonDirection.Horizontal) | |
Items[i].Selectable.SetUpAndDown(Previous, Next); | |
else | |
Items[i].Selectable.SetLeftAndRight(Previous, Next); | |
// Interactable: set this in order | |
if (Items[i].Selectable.IsInteractable()) | |
{ | |
// Is first enabled item in the list | |
if (!lastIndex.HasValue) | |
{ | |
// Clear all the navigation | |
SetNextAndPrevious(Items[i].Selectable, null, null); | |
firstAvailable = Items[i].Selectable; | |
} | |
else | |
{ | |
// Set the previous item to the last enabled item | |
SetNextAndPrevious(Items[i].Selectable, Items[lastIndex.Value].Selectable, null); | |
// Reverse the wiring | |
SetNext(Items[lastIndex.Value].Selectable, Items[i].Selectable); | |
} | |
lastIndex = i; | |
} | |
// Not interactable: remove this from the order | |
else | |
{ | |
// Clear all the navigation | |
SetNextAndPrevious(Items[i].Selectable, null, null); | |
} | |
} | |
RewireNextAndPrevious(); | |
} | |
public void SelectItem(SubmenuItem selected) | |
{ | |
SelectedItem = selected; | |
RewireNextAndPrevious(); | |
} | |
public void ForceSelection(SubmenuItem selected) | |
{ | |
if (evt == null) | |
evt = EventSystem.current; | |
evt.SetSelectedGameObject(null); | |
evt.SetSelectedGameObject(selected.gameObject); | |
RewireNextAndPrevious(); | |
} | |
Selectable SelectedOrFirst | |
{ | |
get | |
{ | |
return (SelectedItem != null && SelectedItem.Selectable != null) ? SelectedItem.Selectable : firstAvailable; | |
} | |
} | |
public void RewireNextAndPrevious() | |
{ | |
if (Direction == ButtonDirection.Horizontal) | |
{ | |
if (Previous != null) | |
Previous.SetDown(SelectedOrFirst); | |
if (Next != null) | |
Next.SetUp(SelectedOrFirst); | |
} | |
else | |
{ | |
if (Previous != null) | |
Previous.SetRight(SelectedOrFirst); | |
if (Next != null) | |
Next.SetLeft(SelectedOrFirst); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment