Files
aibis-dream/Assets/Scripts/UI/Terminal/TerminalMenuItemView.cs
T
dingyuntian e015b756f6 feat(audio-kit): 终端 UI 菜单音效与暂停菜单环境音
- 新增 TerminalUIAudio 事件通知与 TerminalUIAudioBehaviour 组件
- TerminalButton/TerminalMenuItemView/SelectItem/SliderItem 接入悬停与点击音效
- AudioManager 监听 TerminalUIEvent 播放 menu_hover/menu_click
- 新增 PauseMenu 环境音状态及恢复逻辑
- 新增 MainMenuStage FMOD 参数控制
- BaseButton 调用基类 DoStateTransition 保证状态事件正确触发
- 为 TerminalChapterPanel Prefab 添加 TerminalUIAudioBehaviour
2026-07-04 23:12:47 +08:00

191 lines
5.4 KiB
C#

using System;
using AibisDream.Utility;
using TMPro;
using UnityEngine;
using UnityEngine.Localization.Components;
using UnityEngine.UI;
namespace AibisDream.UI
{
[RequireComponent(typeof(BaseButton))]
public class TerminalMenuItemView : MonoBehaviour
{
[SerializeField] private TMP_Text labelText;
[SerializeField] private LocalizeStringEvent labelLocalize;
[SerializeField] private TMP_Text statusText;
[SerializeField] private TMP_Text detailText;
[SerializeField] private TMP_Text cursor;
[SerializeField] private Image selectionBar;
[SerializeField] private string defaultLabelKey = string.Empty;
[SerializeField] private Color normalTextColor = Color.white;
[SerializeField] private Color selectedTextColor = new Color(0.02f, 0.02f, 0.04f);
[SerializeField] private Color dangerTextColor = new Color(1f, 0.18f, 0.2f);
[SerializeField] private float disabledAlpha = 0.35f;
private BaseButton _button;
private CanvasGroup _canvasGroup;
private bool _isDanger;
private bool _isSelected;
private SelectionType _prevSelectionState = SelectionType.Normal;
public event Action<TerminalMenuItemView> Clicked;
public event Action<TerminalMenuItemView> Hovered;
private void Awake()
{
_button = GetComponent<BaseButton>();
_canvasGroup = GetComponent<CanvasGroup>();
if (_canvasGroup == null)
{
_canvasGroup = gameObject.AddComponent<CanvasGroup>();
}
if (labelLocalize == null && labelText != null)
{
labelLocalize = labelText.GetComponent<LocalizeStringEvent>();
}
_button.onClick.AddListener(HandleClick);
_button.onStateTransition.AddListener(OnButtonStateTransition);
SetSelected(false);
if (!string.IsNullOrEmpty(defaultLabelKey))
{
SetLabel(defaultLabelKey);
}
}
private void OnDestroy()
{
if (_button != null)
{
_button.onClick.RemoveListener(HandleClick);
_button.onStateTransition.RemoveListener(OnButtonStateTransition);
}
}
public void SetContent(string label, string status = "", string detail = "")
{
SetLabel(label);
if (statusText != null)
{
statusText.text = status;
}
if (detailText != null)
{
detailText.text = detail;
}
RefreshVisual();
}
public void SetLabel(string value)
{
if (labelLocalize != null && IsLocalizationKey(value))
{
labelLocalize.enabled = true;
labelLocalize.SetTable(ConstRef.UITextTable);
labelLocalize.SetEntry(value);
return;
}
if (labelLocalize != null)
{
labelLocalize.enabled = false;
}
if (labelText != null)
{
labelText.text = value;
}
}
public void SetInteractable(bool interactable)
{
if (_button != null)
{
_button.interactable = interactable;
}
if (_canvasGroup != null)
{
_canvasGroup.alpha = interactable ? 1f : disabledAlpha;
}
}
public void SetSelected(bool selected)
{
_isSelected = selected;
RefreshVisual();
}
private void HandleClick()
{
if (_button != null && _button.interactable)
{
TerminalUIAudio.NotifyClick();
}
Clicked?.Invoke(this);
}
private void OnButtonStateTransition(SelectionType state, bool instant)
{
if (_button.interactable
&& state == SelectionType.Highlighted
&& _prevSelectionState == SelectionType.Normal)
{
TerminalUIAudio.NotifyHover();
}
_prevSelectionState = state;
if (state is SelectionType.Highlighted or SelectionType.Selected or SelectionType.Pressed)
{
Hovered?.Invoke(this);
}
RefreshVisual();
}
private void RefreshVisual()
{
if (cursor != null)
{
cursor.gameObject.SetActive(_isSelected);
}
if (selectionBar != null)
{
selectionBar.gameObject.SetActive(_isSelected);
}
var color = _isDanger ? dangerTextColor : normalTextColor;
if (_isSelected && !_isDanger)
{
color = selectedTextColor;
}
SetColor(labelText, color);
SetColor(statusText, color);
SetColor(detailText, color);
SetColor(cursor, color);
}
private static void SetColor(TMP_Text text, Color color)
{
if (text != null)
{
text.color = color;
}
}
private static bool IsLocalizationKey(string value)
{
return !string.IsNullOrEmpty(value) && value.Contains("_", StringComparison.Ordinal);
}
}
}