373 lines
12 KiB
C#
373 lines
12 KiB
C#
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using TMPro;
|
||
using UnityEngine.Events;
|
||
|
||
/// <summary>
|
||
/// 通用设置项组件
|
||
/// 可复用的设置面板UI组件,支持多种控件类型
|
||
/// </summary>
|
||
public class SettingItemComponent : MonoBehaviour
|
||
{
|
||
[Header("基础设置")]
|
||
public TextMeshProUGUI TitleText;
|
||
public TextMeshProUGUI DescriptionText;
|
||
public Image IconImage;
|
||
|
||
[Header("控件容器")]
|
||
public Transform ControlContainer;
|
||
|
||
// 动态创建的控件引用
|
||
private Slider _slider;
|
||
private Toggle _toggle;
|
||
private TMP_InputField _inputField;
|
||
private TMP_Dropdown _dropdown;
|
||
private Button _actionButton;
|
||
|
||
// 事件
|
||
public UnityEvent<float> OnSliderChanged = new UnityEvent<float>();
|
||
public UnityEvent<bool> OnToggleChanged = new UnityEvent<bool>();
|
||
public UnityEvent<string> OnInputChanged = new UnityEvent<string>();
|
||
public UnityEvent<int> OnDropdownChanged = new UnityEvent<int>();
|
||
public UnityEvent OnButtonClicked = new UnityEvent();
|
||
|
||
/// <summary>
|
||
/// 设置基础信息
|
||
/// </summary>
|
||
public void SetInfo(string title, string description = "", Sprite icon = null)
|
||
{
|
||
if (TitleText != null) TitleText.text = title;
|
||
if (DescriptionText != null) DescriptionText.text = description;
|
||
if (IconImage != null)
|
||
{
|
||
IconImage.sprite = icon;
|
||
IconImage.gameObject.SetActive(icon != null);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建滑块控件
|
||
/// </summary>
|
||
public Slider CreateSlider(float minValue, float maxValue, float currentValue, bool wholeNumbers = false)
|
||
{
|
||
ClearControls();
|
||
|
||
var sliderGO = CreateSliderGameObject();
|
||
_slider = sliderGO.GetComponent<Slider>();
|
||
_slider.minValue = minValue;
|
||
_slider.maxValue = maxValue;
|
||
_slider.value = currentValue;
|
||
_slider.wholeNumbers = wholeNumbers;
|
||
|
||
_slider.onValueChanged.AddListener(OnSliderValueChanged);
|
||
|
||
return _slider;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建开关控件
|
||
/// </summary>
|
||
public Toggle CreateToggle(bool isOn)
|
||
{
|
||
ClearControls();
|
||
|
||
var toggleGO = CreateToggleGameObject();
|
||
_toggle = toggleGO.GetComponent<Toggle>();
|
||
_toggle.isOn = isOn;
|
||
|
||
_toggle.onValueChanged.AddListener(OnToggleValueChanged);
|
||
|
||
return _toggle;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建输入框控件
|
||
/// </summary>
|
||
public TMP_InputField CreateInputField(string placeholder = "", string currentValue = "")
|
||
{
|
||
ClearControls();
|
||
|
||
var inputGO = CreateInputFieldGameObject();
|
||
_inputField = inputGO.GetComponent<TMP_InputField>();
|
||
_inputField.text = currentValue;
|
||
|
||
if (!string.IsNullOrEmpty(placeholder))
|
||
{
|
||
_inputField.placeholder.GetComponent<TextMeshProUGUI>().text = placeholder;
|
||
}
|
||
|
||
_inputField.onValueChanged.AddListener(OnInputValueChanged);
|
||
|
||
return _inputField;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建下拉框控件
|
||
/// </summary>
|
||
public TMP_Dropdown CreateDropdown(string[] options, int selectedIndex = 0)
|
||
{
|
||
ClearControls();
|
||
|
||
var dropdownGO = CreateDropdownGameObject();
|
||
_dropdown = dropdownGO.GetComponent<TMP_Dropdown>();
|
||
|
||
_dropdown.options.Clear();
|
||
foreach (string option in options)
|
||
{
|
||
_dropdown.options.Add(new TMP_Dropdown.OptionData(option));
|
||
}
|
||
|
||
_dropdown.value = selectedIndex;
|
||
_dropdown.onValueChanged.AddListener(OnDropdownValueChanged);
|
||
|
||
return _dropdown;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建按钮控件
|
||
/// </summary>
|
||
public Button CreateButton(string buttonText)
|
||
{
|
||
ClearControls();
|
||
|
||
var buttonGO = CreateButtonGameObject();
|
||
_actionButton = buttonGO.GetComponent<Button>();
|
||
|
||
var buttonTextComponent = buttonGO.GetComponentInChildren<TextMeshProUGUI>();
|
||
if (buttonTextComponent != null)
|
||
buttonTextComponent.text = buttonText;
|
||
|
||
_actionButton.onClick.AddListener(OnButtonClick);
|
||
|
||
return _actionButton;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置控件的可交互状态
|
||
/// </summary>
|
||
public void SetInteractable(bool interactable)
|
||
{
|
||
if (_slider != null) _slider.interactable = interactable;
|
||
if (_toggle != null) _toggle.interactable = interactable;
|
||
if (_inputField != null) _inputField.interactable = interactable;
|
||
if (_dropdown != null) _dropdown.interactable = interactable;
|
||
if (_actionButton != null) _actionButton.interactable = interactable;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取当前控件值
|
||
/// </summary>
|
||
public object GetCurrentValue()
|
||
{
|
||
if (_slider != null) return _slider.value;
|
||
if (_toggle != null) return _toggle.isOn;
|
||
if (_inputField != null) return _inputField.text;
|
||
if (_dropdown != null) return _dropdown.value;
|
||
return null;
|
||
}
|
||
|
||
private void ClearControls()
|
||
{
|
||
if (ControlContainer != null)
|
||
{
|
||
foreach (Transform child in ControlContainer)
|
||
{
|
||
DestroyImmediate(child.gameObject);
|
||
}
|
||
}
|
||
|
||
_slider = null;
|
||
_toggle = null;
|
||
_inputField = null;
|
||
_dropdown = null;
|
||
_actionButton = null;
|
||
}
|
||
|
||
private GameObject CreateSliderGameObject()
|
||
{
|
||
var sliderGO = new GameObject("Slider", typeof(RectTransform), typeof(Slider));
|
||
sliderGO.transform.SetParent(ControlContainer, false);
|
||
|
||
// 设置RectTransform
|
||
var rect = sliderGO.GetComponent<RectTransform>();
|
||
rect.anchorMin = Vector2.zero;
|
||
rect.anchorMax = Vector2.one;
|
||
rect.offsetMin = Vector2.zero;
|
||
rect.offsetMax = Vector2.zero;
|
||
|
||
var slider = sliderGO.GetComponent<Slider>();
|
||
|
||
// 创建背景
|
||
var background = CreateSliderBackground(sliderGO);
|
||
slider.targetGraphic = background;
|
||
|
||
// 创建填充区域
|
||
var fillArea = CreateSliderFillArea(sliderGO);
|
||
slider.fillRect = fillArea.GetComponent<RectTransform>();
|
||
|
||
// 创建滑块
|
||
var handle = CreateSliderHandle(sliderGO);
|
||
slider.handleRect = handle.GetComponent<RectTransform>();
|
||
|
||
return sliderGO;
|
||
}
|
||
|
||
private Image CreateSliderBackground(GameObject parent)
|
||
{
|
||
var bgGO = new GameObject("Background", typeof(RectTransform), typeof(Image));
|
||
bgGO.transform.SetParent(parent.transform, false);
|
||
|
||
var rect = bgGO.GetComponent<RectTransform>();
|
||
rect.anchorMin = Vector2.zero;
|
||
rect.anchorMax = Vector2.one;
|
||
rect.offsetMin = Vector2.zero;
|
||
rect.offsetMax = Vector2.zero;
|
||
|
||
var image = bgGO.GetComponent<Image>();
|
||
image.color = new Color(0.2f, 0.2f, 0.2f, 1f);
|
||
|
||
return image;
|
||
}
|
||
|
||
private Image CreateSliderFillArea(GameObject parent)
|
||
{
|
||
var fillAreaGO = new GameObject("Fill Area", typeof(RectTransform));
|
||
fillAreaGO.transform.SetParent(parent.transform, false);
|
||
|
||
var fillGO = new GameObject("Fill", typeof(RectTransform), typeof(Image));
|
||
fillGO.transform.SetParent(fillAreaGO.transform, false);
|
||
|
||
var fillRect = fillGO.GetComponent<RectTransform>();
|
||
fillRect.anchorMin = Vector2.zero;
|
||
fillRect.anchorMax = Vector2.one;
|
||
fillRect.offsetMin = Vector2.zero;
|
||
fillRect.offsetMax = Vector2.zero;
|
||
|
||
var image = fillGO.GetComponent<Image>();
|
||
image.color = new Color(0.3f, 0.6f, 1f, 1f);
|
||
|
||
return image;
|
||
}
|
||
|
||
private Image CreateSliderHandle(GameObject parent)
|
||
{
|
||
var handleAreaGO = new GameObject("Handle Slide Area", typeof(RectTransform));
|
||
handleAreaGO.transform.SetParent(parent.transform, false);
|
||
|
||
var handleGO = new GameObject("Handle", typeof(RectTransform), typeof(Image));
|
||
handleGO.transform.SetParent(handleAreaGO.transform, false);
|
||
|
||
var handleRect = handleGO.GetComponent<RectTransform>();
|
||
handleRect.sizeDelta = new Vector2(20, 20);
|
||
|
||
var image = handleGO.GetComponent<Image>();
|
||
image.color = Color.white;
|
||
|
||
return image;
|
||
}
|
||
|
||
private GameObject CreateToggleGameObject()
|
||
{
|
||
var toggleGO = new GameObject("Toggle", typeof(RectTransform), typeof(Toggle));
|
||
toggleGO.transform.SetParent(ControlContainer, false);
|
||
|
||
// 创建背景和勾选标记
|
||
var background = new GameObject("Background", typeof(RectTransform), typeof(Image));
|
||
background.transform.SetParent(toggleGO.transform, false);
|
||
|
||
var checkmark = new GameObject("Checkmark", typeof(RectTransform), typeof(Image));
|
||
checkmark.transform.SetParent(background.transform, false);
|
||
|
||
// 设置Toggle组件引用
|
||
var toggle = toggleGO.GetComponent<Toggle>();
|
||
toggle.targetGraphic = background.GetComponent<Image>();
|
||
toggle.graphic = checkmark.GetComponent<Image>();
|
||
|
||
return toggleGO;
|
||
}
|
||
|
||
private GameObject CreateInputFieldGameObject()
|
||
{
|
||
var inputGO = new GameObject("InputField", typeof(RectTransform), typeof(TMP_InputField), typeof(Image));
|
||
inputGO.transform.SetParent(ControlContainer, false);
|
||
|
||
// 创建文本区域
|
||
var textArea = new GameObject("Text Area", typeof(RectTransform));
|
||
textArea.transform.SetParent(inputGO.transform, false);
|
||
|
||
// 创建占位符文本
|
||
var placeholder = new GameObject("Placeholder", typeof(RectTransform), typeof(TextMeshProUGUI));
|
||
placeholder.transform.SetParent(textArea.transform, false);
|
||
|
||
// 创建输入文本
|
||
var text = new GameObject("Text", typeof(RectTransform), typeof(TextMeshProUGUI));
|
||
text.transform.SetParent(textArea.transform, false);
|
||
|
||
// 设置InputField组件
|
||
var inputField = inputGO.GetComponent<TMP_InputField>();
|
||
inputField.textViewport = textArea.GetComponent<RectTransform>();
|
||
inputField.placeholder = placeholder.GetComponent<TextMeshProUGUI>();
|
||
inputField.textComponent = text.GetComponent<TextMeshProUGUI>();
|
||
|
||
return inputGO;
|
||
}
|
||
|
||
private GameObject CreateDropdownGameObject()
|
||
{
|
||
var dropdownGO = new GameObject("Dropdown", typeof(RectTransform), typeof(TMP_Dropdown), typeof(Image));
|
||
dropdownGO.transform.SetParent(ControlContainer, false);
|
||
|
||
// 这里应该创建完整的Dropdown结构,包括模板、选项等
|
||
// 为了简化,暂时使用基础设置
|
||
|
||
return dropdownGO;
|
||
}
|
||
|
||
private GameObject CreateButtonGameObject()
|
||
{
|
||
var buttonGO = new GameObject("Button", typeof(RectTransform), typeof(Button), typeof(Image));
|
||
buttonGO.transform.SetParent(ControlContainer, false);
|
||
|
||
// 创建按钮文本
|
||
var textGO = new GameObject("Text", typeof(RectTransform), typeof(TextMeshProUGUI));
|
||
textGO.transform.SetParent(buttonGO.transform, false);
|
||
|
||
var textRect = textGO.GetComponent<RectTransform>();
|
||
textRect.anchorMin = Vector2.zero;
|
||
textRect.anchorMax = Vector2.one;
|
||
textRect.offsetMin = Vector2.zero;
|
||
textRect.offsetMax = Vector2.zero;
|
||
|
||
var textComponent = textGO.GetComponent<TextMeshProUGUI>();
|
||
textComponent.text = "Button";
|
||
textComponent.alignment = TextAlignmentOptions.Center;
|
||
|
||
return buttonGO;
|
||
}
|
||
|
||
// 事件处理方法
|
||
private void OnSliderValueChanged(float value)
|
||
{
|
||
OnSliderChanged?.Invoke(value);
|
||
}
|
||
|
||
private void OnToggleValueChanged(bool value)
|
||
{
|
||
OnToggleChanged?.Invoke(value);
|
||
}
|
||
|
||
private void OnInputValueChanged(string value)
|
||
{
|
||
OnInputChanged?.Invoke(value);
|
||
}
|
||
|
||
private void OnDropdownValueChanged(int value)
|
||
{
|
||
OnDropdownChanged?.Invoke(value);
|
||
}
|
||
|
||
private void OnButtonClick()
|
||
{
|
||
OnButtonClicked?.Invoke();
|
||
}
|
||
} |