The options are quire long by now. Modern game have sections. Instead of section tabs/buttons, how about making the sections foldable and remembering the state?
To get this:
Drag the following onto the Canvas Pause Menu/Pause Menu/Options object in the Objects/Canvas Pause Menu.prefab
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AutoFoldout : MonoBehaviour
{
void Start()
{
Transform content = transform.Find("Viewport/Content");
List<Transform> labels = new();
foreach (Transform child in content)
{
if (child.name.StartsWith("Label "))
labels.Add(child);
}
for (int i = 0; i < labels.Count; i++)
{
Transform label = labels[i];
// WRAPPER OBJECT
GameObject header = new GameObject(label.name + "_Header");
header.transform.SetParent(content, false);
int originalIndex = label.GetSiblingIndex();
header.transform.SetSiblingIndex(originalIndex);
RectTransform headerRect = header.AddComponent<RectTransform>();
headerRect.anchorMin = new Vector2(0, 1);
headerRect.anchorMax = new Vector2(1, 1);
headerRect.pivot = new Vector2(0.5f, 0.5f);
headerRect.sizeDelta = new Vector2(0, 30);
Image image = header.AddComponent<Image>();
image.color = new Color(0, 0, 0, 0.001f);
Button button = header.AddComponent<Button>();
// MOVE LABEL INTO HEADER
label.SetParent(header.transform, false);
Text text = label.GetComponent<Text>();
if (text)
text.raycastTarget = false;
RectTransform labelRect = label.GetComponent<RectTransform>();
labelRect.anchorMin = new Vector2(0, 0);
labelRect.anchorMax = new Vector2(1, 1);
labelRect.offsetMin = new Vector2(10, 0);
labelRect.offsetMax = new Vector2(-40, 0);
// ARROW
GameObject arrowObj = new GameObject("Arrow");
arrowObj.transform.SetParent(header.transform, false);
RectTransform arrowRect = arrowObj.AddComponent<RectTransform>();
arrowRect.anchorMin = new Vector2(1, 0);
arrowRect.anchorMax = new Vector2(1, 1);
arrowRect.pivot = new Vector2(1, 0.5f);
arrowRect.sizeDelta = new Vector2(30, 0);
arrowRect.anchoredPosition = new Vector2(-10, 0);
Text arrow = arrowObj.AddComponent<Text>();
arrow.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
arrow.alignment = TextAnchor.MiddleCenter;
arrow.color = Color.white;
arrow.raycastTarget = false;
// CONTENT
List<GameObject> controlled = new();
int start = originalIndex + 1;
int end = i + 1 < labels.Count
? labels[i + 1].GetSiblingIndex()
: content.childCount;
for (int j = start; j < end; j++)
{
Transform child = content.GetChild(j);
if (child != header.transform)
controlled.Add(child.gameObject);
}
string key = "foldout_" + label.name;
bool open = PlayerPrefs.GetInt(key, 1) == 1;
void Apply()
{
arrow.text = open ? "▼" : "◄";
foreach (var obj in controlled)
obj.SetActive(open);
LayoutRebuilder.ForceRebuildLayoutImmediate(
content.GetComponent<RectTransform>()
);
}
button.onClick.AddListener(() =>
{
open = !open;
PlayerPrefs.SetInt(key, open ? 1 : 0);
PlayerPrefs.Save();
Apply();
});
Apply();
}
}
}
License: CC0 and especially Wolfire can do whatever they want with this.
The options are quire long by now. Modern game have sections. Instead of section tabs/buttons, how about making the sections foldable and remembering the state?
To get this:
Drag the following onto the
Canvas Pause Menu/Pause Menu/Optionsobject in theObjects/Canvas Pause Menu.prefabLicense: CC0 and especially Wolfire can do whatever they want with this.