using System.Collections.Generic;
using BumpCombat.Audio;
using BumpCombat.Core;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.UI;
namespace BumpCombat.UI
{
///
/// Runtime title, pause, and settings panels. The RunManager owns state;
/// this component only presents and requests those transitions.
///
[DisallowMultipleComponent]
public sealed class RunMenuController : MonoBehaviour
{
private enum Screen
{
None,
Title,
TitleModes,
Pause,
Settings,
}
private Screen currentScreen;
private Screen settingsCaller;
private RunManager runManager;
private BumpCombatAudioService audioService;
private GameObject panel;
private GameObject modalDim;
private Text titleText;
private Text subtitleText;
private Text inputHelpText;
private readonly List buttons = new();
private readonly List buttonFocusMarkers = new();
private readonly GameObject[] settingsFocusRows = new GameObject[4];
private Slider masterSlider;
private Slider musicSlider;
private Slider sfxSlider;
private Text masterValueText;
private Text musicValueText;
private Text sfxValueText;
private int selectedButton;
private int selectedSettingsControl;
public bool IsVisible => panel != null && panel.activeSelf;
private void Start()
{
runManager = RunManager.Instance;
audioService = BumpCombatAudioService.Instance;
PresentationUiStyle.EnsureEventSystem(
clearMenuNavigationActions: true);
CreatePanel();
if (runManager != null)
{
runManager.OnTitleChanged += HandleTitleChanged;
runManager.OnPauseChanged += HandlePauseChanged;
runManager.OnGameOver += HandleGameOver;
}
if (runManager != null && runManager.IsTitleScreen)
{
SetScreen(Screen.Title);
}
else
{
SetScreen(Screen.None);
}
}
private void OnDestroy()
{
if (runManager != null)
{
runManager.OnTitleChanged -= HandleTitleChanged;
runManager.OnPauseChanged -= HandlePauseChanged;
runManager.OnGameOver -= HandleGameOver;
}
}
private void Update()
{
if (runManager == null || Keyboard.current == null)
{
return;
}
Keyboard keyboard = Keyboard.current;
if (keyboard.escapeKey.wasPressedThisFrame)
{
if (currentScreen == Screen.Settings)
{
SetScreen(settingsCaller);
}
else if (currentScreen == Screen.TitleModes)
{
SetScreen(Screen.Title);
}
else if (currentScreen == Screen.Pause)
{
runManager.ClosePause();
}
else if (currentScreen == Screen.None
&& !runManager.IsSelectionOpen
&& !runManager.IsGameOver
&& !runManager.IsTitleScreen)
{
if (runManager.TryOpenPause())
{
SetScreen(Screen.Pause);
}
}
return;
}
if (!IsVisible)
{
return;
}
if (currentScreen == Screen.Settings)
{
HandleSettingsKeyboard(keyboard);
return;
}
bool moved = false;
if (keyboard.upArrowKey.wasPressedThisFrame)
{
selectedButton = FindNextActiveButton(-1);
moved = true;
}
else if (keyboard.downArrowKey.wasPressedThisFrame)
{
selectedButton = FindNextActiveButton(1);
moved = true;
}
if (moved)
{
SelectButton(selectedButton, true);
}
if (keyboard.enterKey.wasPressedThisFrame
|| keyboard.numpadEnterKey.wasPressedThisFrame
|| keyboard.spaceKey.wasPressedThisFrame)
{
if (selectedButton >= 0 && selectedButton < buttons.Count)
{
Button selected = buttons[selectedButton];
if (selected != null && selected.interactable)
{
audioService?.PlayUi("ui_confirm");
selected.onClick.Invoke();
}
}
}
}
private void LateUpdate()
{
if (!IsVisible || modalDim == null || panel == null)
{
return;
}
Transform panelParent = panel.transform.parent;
if (panelParent == null || modalDim.transform.parent != panelParent)
{
return;
}
int lastIndex = panelParent.childCount - 1;
int modalIndex = modalDim.transform.GetSiblingIndex();
int panelIndex = panel.transform.GetSiblingIndex();
if (panelIndex == lastIndex && modalIndex == lastIndex - 1)
{
return;
}
modalDim.transform.SetAsLastSibling();
panel.transform.SetAsLastSibling();
}
private void HandleTitleChanged(bool isOpen)
{
if (isOpen)
{
SetScreen(Screen.Title);
}
else if (currentScreen == Screen.Title)
{
SetScreen(Screen.None);
}
}
private void HandlePauseChanged(bool isOpen)
{
if (isOpen)
{
SetScreen(Screen.Pause);
}
else if (currentScreen == Screen.Pause)
{
SetScreen(Screen.None);
}
}
private void HandleGameOver()
{
SetScreen(Screen.None);
}
private void SetScreen(Screen screen)
{
currentScreen = screen;
if (panel == null)
{
return;
}
panel.SetActive(screen != Screen.None);
if (modalDim != null)
{
modalDim.SetActive(screen != Screen.None);
}
if (screen == Screen.None)
{
return;
}
panel.transform.SetAsLastSibling();
HideAllControls();
switch (screen)
{
case Screen.Title:
titleText.text = "Tiny Tackle Heroes";
subtitleText.text = "DIRECTIONAL ACTION SURVIVAL";
inputHelpText.text = "항목 이동: 위/아래 선택: Enter/Space";
ShowButton(0, "게임시작", OpenTitleModes);
ShowButton(1, "설정", OpenTitleSettings);
ShowButton(2, "업적", OpenTitleAchievements);
ShowButton(3, "나가기", QuitGame);
break;
case Screen.TitleModes:
titleText.text = "게임 시작";
subtitleText.text = "모드를 선택하세요";
inputHelpText.text = "항목 이동: 위/아래 선택: Enter/Space 뒤로: Esc";
ShowTitleModeButtons();
break;
case Screen.Pause:
titleText.text = "PAUSED";
subtitleText.text = "THE RUN IS WAITING";
inputHelpText.text = "항목 이동: 위/아래 선택: Enter/Space 계속: Esc";
ShowButton(0, "계속", ContinueRun);
ShowButton(1, "설정", OpenPauseSettings);
ShowButton(2, "다시 시작", RestartRun);
ShowButton(3, "타이틀", ReturnToTitle);
break;
case Screen.Settings:
titleText.text = "설정";
subtitleText.text = "음량";
inputHelpText.text = "항목 이동: 위/아래 음량 조절: 왼쪽/오른쪽\n뒤로 선택: Enter/Space 즉시 뒤로: Esc";
ShowSlider(masterSlider, masterValueText, "전체", audioService?.MasterVolume ?? 0.8f);
ShowSlider(musicSlider, musicValueText, "음악", audioService?.MusicVolume ?? 0.55f);
ShowSlider(sfxSlider, sfxValueText, "효과음", audioService?.SfxVolume ?? 0.8f);
ShowButton(3, "뒤로", BackFromSettings);
break;
}
if (screen == Screen.Settings)
{
selectedSettingsControl = 0;
SelectSettingsControl(false);
}
else
{
selectedButton = FindFirstActiveButton();
SelectButton(selectedButton, false);
}
}
private void HideAllControls()
{
for (int i = 0; i < buttons.Count; i++)
{
buttons[i].gameObject.SetActive(false);
}
SetControlVisible(masterSlider, false);
SetControlVisible(musicSlider, false);
SetControlVisible(sfxSlider, false);
masterValueText.gameObject.SetActive(false);
musicValueText.gameObject.SetActive(false);
sfxValueText.gameObject.SetActive(false);
for (int i = 0; i < settingsFocusRows.Length; i++)
{
settingsFocusRows[i]?.SetActive(false);
}
}
private void ShowButton(int index, string label, UnityEngine.Events.UnityAction action)
{
Button button = GetButton(index);
button.gameObject.SetActive(true);
button.interactable = true;
PositionButton(button, 95f - index * 88f);
Text labelText = button.GetComponentInChildren();
labelText.text = label;
labelText.color = Color.white;
button.onClick.RemoveAllListeners();
button.onClick.AddListener(action);
}
private Button GetButton(int index)
{
Transform child = panel.transform.Find($"Button {index + 1}");
Button button = child.GetComponent();
buttons[index] = button;
return button;
}
private void SelectButton(int index, bool playSound)
{
if (buttons.Count == 0 || index < 0 || index >= buttons.Count)
{
return;
}
Button button = buttons[index];
if (!IsButtonSelectable(button))
{
return;
}
for (int i = 0; i < buttonFocusMarkers.Count; i++)
{
buttonFocusMarkers[i].SetActive(currentScreen != Screen.Settings && i == index);
}
EventSystem.current?.SetSelectedGameObject(button.gameObject);
if (playSound)
{
audioService?.PlayUi("ui_move");
}
}
private int FindFirstActiveButton()
{
for (int i = 0; i < buttons.Count; i++)
{
if (IsButtonSelectable(buttons[i]))
{
return i;
}
}
return -1;
}
private int FindNextActiveButton(int direction)
{
if (buttons.Count == 0)
{
return -1;
}
int candidate = selectedButton;
for (int i = 0; i < buttons.Count; i++)
{
candidate = (candidate + direction + buttons.Count) % buttons.Count;
if (IsButtonSelectable(buttons[candidate]))
{
return candidate;
}
}
return selectedButton;
}
private static bool IsButtonSelectable(Button button)
{
return button != null
&& button.gameObject.activeSelf
&& button.interactable;
}
private void HandleSettingsKeyboard(Keyboard keyboard)
{
if (keyboard.upArrowKey.wasPressedThisFrame)
{
selectedSettingsControl = (selectedSettingsControl + 3) % 4;
SelectSettingsControl(true);
}
else if (keyboard.downArrowKey.wasPressedThisFrame)
{
selectedSettingsControl = (selectedSettingsControl + 1) % 4;
SelectSettingsControl(true);
}
if (selectedSettingsControl < 3
&& (keyboard.leftArrowKey.wasPressedThisFrame
|| keyboard.rightArrowKey.wasPressedThisFrame))
{
Slider slider = GetSettingsSlider(selectedSettingsControl);
float delta = keyboard.rightArrowKey.wasPressedThisFrame ? 0.05f : -0.05f;
slider.value = Mathf.Clamp01(slider.value + delta);
}
else if (selectedSettingsControl == 3
&& (keyboard.enterKey.wasPressedThisFrame
|| keyboard.numpadEnterKey.wasPressedThisFrame
|| keyboard.spaceKey.wasPressedThisFrame))
{
audioService?.PlayUi("ui_confirm");
buttons[3].onClick.Invoke();
}
}
private Slider GetSettingsSlider(int index)
{
return index switch
{
0 => masterSlider,
1 => musicSlider,
_ => sfxSlider,
};
}
private void SelectSettingsControl(bool playSound)
{
for (int i = 0; i < settingsFocusRows.Length; i++)
{
if (settingsFocusRows[i] != null)
{
settingsFocusRows[i].SetActive(i == selectedSettingsControl);
}
}
if (selectedSettingsControl == 3)
{
SelectButton(3, playSound);
return;
}
Slider slider = GetSettingsSlider(selectedSettingsControl);
EventSystem.current?.SetSelectedGameObject(slider.gameObject);
if (playSound)
{
audioService?.PlayUi("ui_move");
}
}
private void BeginDevelopmentRun()
{
BeginRun(RunMode.Development);
}
private void BeginProductionRun()
{
BeginRun(RunMode.Production);
}
private void OpenTitleModes()
{
SetScreen(Screen.TitleModes);
}
private void ShowTitleModeButtons()
{
int index = 0;
if (IsDevelopmentStartVisible(Application.isEditor, Debug.isDebugBuild))
{
ShowButton(index++, "개발용 시작", BeginDevelopmentRun);
}
ShowButton(index++, "기본 모드", BeginProductionRun);
ShowDisabledButton(index++, "챌린지 모드(준비 중)");
ShowDisabledButton(index++, "하드코어 모드(준비 중)");
ShowButton(index, "뒤로", ReturnToTitleMenu);
int visibleButtonCount = index + 1;
float top = (visibleButtonCount - 1) * 36f;
for (int buttonIndex = 0; buttonIndex < visibleButtonCount; buttonIndex++)
{
RectTransform rect = buttons[buttonIndex].GetComponent();
rect.anchoredPosition = new Vector2(
rect.anchoredPosition.x,
top - buttonIndex * 72f);
}
}
private void ShowDisabledButton(int index, string label)
{
Button button = GetButton(index);
button.gameObject.SetActive(true);
button.interactable = false;
PositionButton(button, 95f - index * 88f);
Text labelText = button.GetComponentInChildren();
labelText.text = label;
labelText.color = new Color32(166, 171, 181, 255);
button.onClick.RemoveAllListeners();
}
private static bool IsDevelopmentStartVisible(
bool isEditor,
bool isDevelopmentBuild)
{
return isEditor || isDevelopmentBuild;
}
private static void PositionButton(Button button, float y)
{
RectTransform rect = button.GetComponent();
rect.anchoredPosition = new Vector2(rect.anchoredPosition.x, y);
}
private void OpenTitleAchievements()
{
MissionAchievementPanel achievements = GetComponent();
SetScreen(Screen.None);
if (achievements == null
|| !achievements.OpenTitleAchievements(ReturnToTitleMenu))
{
SetScreen(Screen.Title);
return;
}
audioService?.PlayUi("ui_confirm");
}
private void ReturnToTitleMenu()
{
if (runManager != null && runManager.IsTitleScreen)
{
SetScreen(Screen.Title);
}
}
private void BeginRun(RunMode mode)
{
if (runManager == null || !runManager.BeginRun(mode))
{
return;
}
audioService?.PlayUi("ui_confirm");
SetScreen(Screen.None);
}
private void ContinueRun()
{
audioService?.PlayUi("ui_confirm");
runManager?.ClosePause();
}
private void OpenTitleSettings()
{
settingsCaller = Screen.Title;
SetScreen(Screen.Settings);
}
private void OpenPauseSettings()
{
settingsCaller = Screen.Pause;
SetScreen(Screen.Settings);
}
private void BackFromSettings()
{
SetScreen(settingsCaller);
}
private void RestartRun()
{
audioService?.PlayUi("ui_confirm");
runManager?.RestartRun();
}
private void ReturnToTitle()
{
audioService?.PlayUi("ui_confirm");
runManager?.RestartToTitle();
}
private static void QuitGame()
{
Application.Quit();
}
private void ShowSlider(
Slider slider,
Text valueText,
string label,
float value)
{
slider.gameObject.SetActive(true);
valueText.gameObject.SetActive(true);
slider.value = Mathf.Clamp01(value);
valueText.text = $"{label} {Mathf.RoundToInt(slider.value * 100f)}%";
}
private void HandleMasterSlider(float value)
{
audioService?.SetMasterVolume(value);
masterValueText.text = $"MASTER {Mathf.RoundToInt(value * 100f)}%";
}
private void HandleMusicSlider(float value)
{
audioService?.SetMusicVolume(value);
musicValueText.text = $"MUSIC {Mathf.RoundToInt(value * 100f)}%";
}
private void HandleSfxSlider(float value)
{
audioService?.SetSfxVolume(value);
sfxValueText.text = $"SFX {Mathf.RoundToInt(value * 100f)}%";
}
private void CreatePanel()
{
Font font = PresentationUiStyle.GetGalmuriFont();
panel = PresentationUiStyle.CreatePanel(
transform,
"Run Menu",
new Vector2(0.5f, 0.5f),
Vector2.zero,
new Vector2(1180f, 720f),
Color.white);
PresentationUiStyle.ApplyPanel(panel.GetComponent());
modalDim = new GameObject(
"Run Menu Modal Dim",
typeof(RectTransform),
typeof(CanvasRenderer),
typeof(Image));
modalDim.transform.SetParent(transform, false);
RectTransform modalRect = modalDim.GetComponent();
modalRect.anchorMin = Vector2.zero;
modalRect.anchorMax = Vector2.one;
modalRect.offsetMin = Vector2.zero;
modalRect.offsetMax = Vector2.zero;
Image modalImage = modalDim.GetComponent();
modalImage.color = new Color(0f, 0f, 0f, 0.72f);
modalImage.raycastTarget = true;
modalDim.transform.SetSiblingIndex(panel.transform.GetSiblingIndex());
titleText = CreateText(panel.transform, "Title", font, 46, new Vector2(0f, 260f), new Vector2(1000f, 70f));
subtitleText = CreateText(panel.transform, "Subtitle", font, 18, new Vector2(0f, 205f), new Vector2(1000f, 40f));
inputHelpText = CreateText(panel.transform, "Menu Input Help", font, 18, Vector2.zero, new Vector2(1100f, 40f));
RectTransform inputHelpRect = inputHelpText.rectTransform;
inputHelpRect.anchorMin = Vector2.zero;
inputHelpRect.anchorMax = Vector2.zero;
inputHelpRect.pivot = Vector2.zero;
inputHelpRect.anchoredPosition = new Vector2(32f, 24f);
inputHelpRect.sizeDelta = new Vector2(1100f, 60f);
inputHelpText.alignment = TextAnchor.MiddleLeft;
inputHelpText.color = new Color32(200, 208, 218, 255);
CreateSettingsFocusRows(panel.transform);
for (int i = 0; i < 5; i++)
{
Button button = CreateButton(panel.transform, $"Button {i + 1}", font, new Vector2(0f, 95f - i * 88f));
button.gameObject.SetActive(false);
buttons.Add(button);
buttonFocusMarkers.Add(CreateButtonFocusMarker(button.transform));
AddButtonPointerSelection(button, i);
}
masterSlider = CreateSlider(panel.transform, "Master Slider", new Vector2(0f, 90f));
musicSlider = CreateSlider(panel.transform, "Music Slider", new Vector2(0f, 0f));
sfxSlider = CreateSlider(panel.transform, "Sfx Slider", new Vector2(0f, -90f));
masterValueText = CreateText(panel.transform, "Master Value", font, 22, new Vector2(-230f, 90f), new Vector2(280f, 50f));
musicValueText = CreateText(panel.transform, "Music Value", font, 22, new Vector2(-230f, 0f), new Vector2(280f, 50f));
sfxValueText = CreateText(panel.transform, "Sfx Value", font, 22, new Vector2(-230f, -90f), new Vector2(280f, 50f));
masterSlider.onValueChanged.AddListener(HandleMasterSlider);
musicSlider.onValueChanged.AddListener(HandleMusicSlider);
sfxSlider.onValueChanged.AddListener(HandleSfxSlider);
AddSliderPointerSelection(masterSlider, 0);
AddSliderPointerSelection(musicSlider, 1);
AddSliderPointerSelection(sfxSlider, 2);
panel.SetActive(false);
}
private void CreateSettingsFocusRows(Transform parent)
{
for (int i = 0; i < settingsFocusRows.Length; i++)
{
bool isBackButton = i == 3;
float y = isBackButton ? -169f : 90f - i * 90f;
Vector2 size = isBackButton
? new Vector2(520f, 76f)
: new Vector2(820f, 52f);
GameObject row = new($"Settings Focus {i}", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image));
row.transform.SetParent(parent, false);
RectTransform rowRect = row.GetComponent();
rowRect.anchorMin = new Vector2(0.5f, 0.5f);
rowRect.anchorMax = new Vector2(0.5f, 0.5f);
rowRect.pivot = new Vector2(0.5f, 0.5f);
rowRect.anchoredPosition = new Vector2(isBackButton ? 0f : 5f, y);
rowRect.sizeDelta = size;
Image rowImage = row.GetComponent();
rowImage.color = new Color32(75, 128, 148, 72);
rowImage.raycastTarget = false;
GameObject marker = new($"Marker {i}", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image));
marker.transform.SetParent(row.transform, false);
RectTransform markerRect = marker.GetComponent();
markerRect.anchorMin = new Vector2(0.5f, 0.5f);
markerRect.anchorMax = new Vector2(0.5f, 0.5f);
markerRect.pivot = new Vector2(0.5f, 0.5f);
markerRect.anchoredPosition = new Vector2(-size.x * 0.5f + 12f, 0f);
markerRect.sizeDelta = new Vector2(6f, 34f);
Image markerImage = marker.GetComponent();
markerImage.color = new Color32(240, 196, 92, 255);
markerImage.raycastTarget = false;
row.SetActive(false);
settingsFocusRows[i] = row;
}
}
private static GameObject CreateButtonFocusMarker(Transform parent)
{
GameObject marker = new("Focus Marker", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image));
marker.transform.SetParent(parent, false);
RectTransform rect = marker.GetComponent();
rect.anchorMin = new Vector2(0.5f, 0.5f);
rect.anchorMax = new Vector2(0.5f, 0.5f);
rect.pivot = new Vector2(0.5f, 0.5f);
rect.anchoredPosition = new Vector2(-210f, 0f);
rect.sizeDelta = new Vector2(6f, 38f);
Image image = marker.GetComponent();
image.color = new Color32(240, 196, 92, 255);
image.raycastTarget = false;
marker.SetActive(false);
return marker;
}
private static Text CreateText(
Transform parent,
string name,
Font font,
int fontSize,
Vector2 position,
Vector2 size)
{
return PresentationUiStyle.CreateText(
parent,
name,
font,
fontSize,
TextAnchor.MiddleCenter,
position,
size);
}
private static Button CreateButton(
Transform parent,
string name,
Font font,
Vector2 position)
{
GameObject buttonObject = new(name, typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button));
buttonObject.transform.SetParent(parent, false);
RectTransform rect = buttonObject.GetComponent();
rect.anchorMin = new Vector2(0.5f, 0.5f);
rect.anchorMax = new Vector2(0.5f, 0.5f);
rect.pivot = new Vector2(0.5f, 0.5f);
rect.anchoredPosition = position;
rect.sizeDelta = new Vector2(460f, 68f);
Button button = buttonObject.GetComponent();
Image image = buttonObject.GetComponent();
button.targetGraphic = image;
Navigation navigation = button.navigation;
navigation.mode = Navigation.Mode.None;
button.navigation = navigation;
PresentationUiStyle.ApplyButton(button);
Text text = CreateText(buttonObject.transform, "Label", font, 24, Vector2.zero, new Vector2(430f, 58f));
text.raycastTarget = false;
return button;
}
private static Slider CreateSlider(Transform parent, string name, Vector2 position)
{
GameObject sliderObject = new(name, typeof(RectTransform), typeof(Slider));
sliderObject.transform.SetParent(parent, false);
RectTransform rect = sliderObject.GetComponent();
rect.anchorMin = new Vector2(0.5f, 0.5f);
rect.anchorMax = new Vector2(0.5f, 0.5f);
rect.pivot = new Vector2(0.5f, 0.5f);
rect.anchoredPosition = position + Vector2.right * 130f;
rect.sizeDelta = new Vector2(500f, 42f);
Slider slider = sliderObject.GetComponent();
slider.minValue = 0f;
slider.maxValue = 1f;
slider.wholeNumbers = false;
GameObject backgroundObject = new("Background", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image));
backgroundObject.transform.SetParent(sliderObject.transform, false);
RectTransform backgroundRect = backgroundObject.GetComponent();
backgroundRect.anchorMin = new Vector2(0f, 0.5f);
backgroundRect.anchorMax = new Vector2(1f, 0.5f);
backgroundRect.sizeDelta = new Vector2(0f, 18f);
Image background = backgroundObject.GetComponent();
background.color = new Color(0.16f, 0.19f, 0.24f, 1f);
GameObject fillAreaObject = new("Fill Area", typeof(RectTransform));
fillAreaObject.transform.SetParent(sliderObject.transform, false);
RectTransform fillAreaRect = fillAreaObject.GetComponent();
fillAreaRect.anchorMin = new Vector2(0f, 0.5f);
fillAreaRect.anchorMax = new Vector2(1f, 0.5f);
fillAreaRect.sizeDelta = new Vector2(0f, 18f);
GameObject fillObject = new("Fill", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image));
fillObject.transform.SetParent(fillAreaObject.transform, false);
RectTransform fillRect = fillObject.GetComponent();
fillRect.anchorMin = Vector2.zero;
fillRect.anchorMax = Vector2.one;
fillRect.offsetMin = Vector2.zero;
fillRect.offsetMax = Vector2.zero;
Image fillImage = fillObject.GetComponent();
fillImage.color = new Color32(222, 183, 112, 255);
GameObject handleAreaObject = new("Handle Area", typeof(RectTransform));
handleAreaObject.transform.SetParent(sliderObject.transform, false);
RectTransform handleAreaRect = handleAreaObject.GetComponent();
handleAreaRect.anchorMin = new Vector2(0f, 0.5f);
handleAreaRect.anchorMax = new Vector2(1f, 0.5f);
handleAreaRect.sizeDelta = Vector2.zero;
GameObject handleObject = new("Handle", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image));
handleObject.transform.SetParent(handleAreaObject.transform, false);
RectTransform handleRect = handleObject.GetComponent();
handleRect.anchorMin = new Vector2(0f, 0.5f);
handleRect.anchorMax = new Vector2(0f, 0.5f);
handleRect.sizeDelta = new Vector2(24f, 36f);
Image handleImage = handleObject.GetComponent();
handleImage.color = new Color32(240, 216, 153, 255);
slider.fillRect = fillRect;
slider.handleRect = handleRect;
slider.targetGraphic = handleImage;
Navigation navigation = slider.navigation;
navigation.mode = Navigation.Mode.None;
slider.navigation = navigation;
slider.direction = Slider.Direction.LeftToRight;
return slider;
}
private void AddButtonPointerSelection(Button button, int index)
{
EventTrigger trigger = button.gameObject.AddComponent();
EventTrigger.Entry entry = new() { eventID = EventTriggerType.PointerEnter };
entry.callback.AddListener(_ =>
{
if (!button.interactable)
{
return;
}
selectedButton = index;
if (currentScreen == Screen.Settings && index == 3)
{
selectedSettingsControl = 3;
SelectSettingsControl(false);
}
else
{
SelectButton(index, false);
}
});
trigger.triggers.Add(entry);
}
private void AddSliderPointerSelection(Slider slider, int index)
{
EventTrigger trigger = slider.gameObject.AddComponent();
EventTrigger.Entry entry = new() { eventID = EventTriggerType.PointerEnter };
entry.callback.AddListener(_ =>
{
selectedSettingsControl = index;
SelectSettingsControl(false);
});
trigger.triggers.Add(entry);
}
private static void SetControlVisible(Component control, bool visible)
{
if (control != null)
{
control.gameObject.SetActive(visible);
}
}
}
}