using UnityEngine;
using UnityEngine.UI;
using LightGlue.Unity.Game;
namespace LightGlue.Unity.UI
{
///
/// 光标/跟随平滑设置的场景 UI 控制器。
/// - 通过 Toggle、Slider 修改 LightGlueCursorSettings 的参数,并自动保存到本地。
/// - 需在场景中挂到设置面板根节点,并绑定对应的 UI 组件。
///
public class LightGlueCursorSettingsUI : MonoBehaviour
{
[Header("设置数据源")]
[Tooltip("留空则使用 LightGlueCursorSettings.Instance")]
public LightGlueCursorSettings cursorSettings;
[Header("标记器跟随")]
[Tooltip("标记器平滑开关")]
public Toggle markerSmoothToggle;
[Tooltip("标记器跟随速度 Slider(建议 min=1, max=300)")]
public Slider markerLerpSlider;
[Tooltip("标记器跟随速度数值显示(可选)")]
public Text markerLerpValueText;
[Tooltip("标记器抖动阈值 Slider(建议 min=0, max=50)")]
public Slider markerJitterSlider;
[Tooltip("标记器抖动阈值数值显示(可选)")]
public Text markerJitterValueText;
[Header("相机朝向跟随")]
[Tooltip("相机旋转平滑开关")]
public Toggle cameraSmoothToggle;
[Tooltip("相机旋转速度 Slider(建议 min=1, max=300)")]
public Slider cameraLerpSlider;
[Tooltip("相机旋转速度数值显示(可选)")]
public Text cameraLerpValueText;
[Tooltip("相机旋转抖动阈值 Slider(建议 min=0, max=10,单位度)")]
public Slider cameraJitterSlider;
[Tooltip("相机旋转抖动阈值数值显示(可选)")]
public Text cameraJitterValueText;
[Header("按钮")]
[Tooltip("恢复默认并保存按钮")]
public Button resetToDefaultButton;
[Tooltip("保存到本地按钮(若希望手动保存可绑定;不绑定时各控件修改后会自动保存)")]
public Button saveButton;
[Header("Slider 范围(用于恢复默认时设置 Slider 的 value)")]
[Tooltip("标记器速度 Slider 的 min/max,用于 Refresh 时正确显示")]
public Vector2 markerLerpRange = new Vector2(1f, 300f);
public Vector2 markerJitterRange = new Vector2(0f, 50f);
public Vector2 cameraLerpRange = new Vector2(1f, 300f);
public Vector2 cameraJitterRange = new Vector2(0f, 10f);
[Header("本地存储")]
[Tooltip("滑块/开关修改后,到自动保存到本地之间的时间间隔(秒)")]
public float autoSaveIntervalSeconds = 0.5f;
private bool _ignoreChanges;
private bool _pendingSave;
private float _lastChangeTime;
private void Start()
{
if (cursorSettings == null)
cursorSettings = LightGlueCursorSettings.Instance;
if (cursorSettings == null)
{
Debug.LogWarning("[LightGlueCursorSettingsUI] 未找到 LightGlueCursorSettings,请确保场景或预制中存在该组件。");
return;
}
BindListeners();
RefreshUIFromSettings();
}
private void Update()
{
if (!_pendingSave || cursorSettings == null)
return;
if (Time.unscaledTime - _lastChangeTime >= autoSaveIntervalSeconds)
{
cursorSettings.SaveToLocal();
_pendingSave = false;
}
}
private void BindListeners()
{
if (markerSmoothToggle != null)
markerSmoothToggle.onValueChanged.AddListener(OnMarkerSmoothChanged);
if (markerLerpSlider != null)
markerLerpSlider.onValueChanged.AddListener(OnMarkerLerpChanged);
if (markerJitterSlider != null)
markerJitterSlider.onValueChanged.AddListener(OnMarkerJitterChanged);
if (cameraSmoothToggle != null)
cameraSmoothToggle.onValueChanged.AddListener(OnCameraSmoothChanged);
if (cameraLerpSlider != null)
cameraLerpSlider.onValueChanged.AddListener(OnCameraLerpChanged);
if (cameraJitterSlider != null)
cameraJitterSlider.onValueChanged.AddListener(OnCameraJitterChanged);
if (resetToDefaultButton != null)
resetToDefaultButton.onClick.AddListener(OnResetToDefaultClicked);
if (saveButton != null)
saveButton.onClick.AddListener(OnSaveClicked);
}
///
/// 根据当前 LightGlueCursorSettings 刷新所有 UI 显示(不触发保存)。
///
public void RefreshUIFromSettings()
{
if (cursorSettings == null) return;
_ignoreChanges = true;
try
{
if (markerSmoothToggle != null)
markerSmoothToggle.isOn = cursorSettings.markerEnableSmoothFollow;
if (markerLerpSlider != null)
{
markerLerpSlider.minValue = markerLerpRange.x;
markerLerpSlider.maxValue = markerLerpRange.y;
markerLerpSlider.value = cursorSettings.markerPositionLerpSpeed;
}
if (markerJitterSlider != null)
{
markerJitterSlider.minValue = markerJitterRange.x;
markerJitterSlider.maxValue = markerJitterRange.y;
markerJitterSlider.value = cursorSettings.markerJitterThresholdPixels;
}
if (cameraSmoothToggle != null)
cameraSmoothToggle.isOn = cursorSettings.cameraAimEnableSmoothRotation;
if (cameraLerpSlider != null)
{
cameraLerpSlider.minValue = cameraLerpRange.x;
cameraLerpSlider.maxValue = cameraLerpRange.y;
cameraLerpSlider.value = cursorSettings.cameraAimRotationLerpSpeed;
}
if (cameraJitterSlider != null)
{
cameraJitterSlider.minValue = cameraJitterRange.x;
cameraJitterSlider.maxValue = cameraJitterRange.y;
cameraJitterSlider.value = cursorSettings.cameraAimRotationJitterThresholdDeg;
}
UpdateValueLabels();
}
finally
{
_ignoreChanges = false;
}
}
private void UpdateValueLabels()
{
if (markerLerpValueText != null && markerLerpSlider != null)
markerLerpValueText.text = cursorSettings != null ? cursorSettings.markerPositionLerpSpeed.ToString("F0") : markerLerpSlider.value.ToString("F0");
if (markerJitterValueText != null && markerJitterSlider != null)
markerJitterValueText.text = cursorSettings != null ? cursorSettings.markerJitterThresholdPixels.ToString("F1") : markerJitterSlider.value.ToString("F1");
if (cameraLerpValueText != null && cameraLerpSlider != null)
cameraLerpValueText.text = cursorSettings != null ? cursorSettings.cameraAimRotationLerpSpeed.ToString("F0") : cameraLerpSlider.value.ToString("F0");
if (cameraJitterValueText != null && cameraJitterSlider != null)
cameraJitterValueText.text = cursorSettings != null ? cursorSettings.cameraAimRotationJitterThresholdDeg.ToString("F2") : cameraJitterSlider.value.ToString("F2");
}
private void ApplyAndSave()
{
if (cursorSettings == null || _ignoreChanges) return;
_pendingSave = true;
_lastChangeTime = Time.unscaledTime;
}
private void OnMarkerSmoothChanged(bool value)
{
if (_ignoreChanges || cursorSettings == null) return;
cursorSettings.markerEnableSmoothFollow = value;
ApplyAndSave();
}
private void OnMarkerLerpChanged(float value)
{
if (_ignoreChanges || cursorSettings == null) return;
cursorSettings.markerPositionLerpSpeed = value;
if (markerLerpValueText != null) markerLerpValueText.text = value.ToString("F0");
ApplyAndSave();
}
private void OnMarkerJitterChanged(float value)
{
if (_ignoreChanges || cursorSettings == null) return;
cursorSettings.markerJitterThresholdPixels = value;
if (markerJitterValueText != null) markerJitterValueText.text = value.ToString("F1");
ApplyAndSave();
}
private void OnCameraSmoothChanged(bool value)
{
if (_ignoreChanges || cursorSettings == null) return;
cursorSettings.cameraAimEnableSmoothRotation = value;
ApplyAndSave();
}
private void OnCameraLerpChanged(float value)
{
if (_ignoreChanges || cursorSettings == null) return;
cursorSettings.cameraAimRotationLerpSpeed = value;
if (cameraLerpValueText != null) cameraLerpValueText.text = value.ToString("F0");
ApplyAndSave();
}
private void OnCameraJitterChanged(float value)
{
if (_ignoreChanges || cursorSettings == null) return;
cursorSettings.cameraAimRotationJitterThresholdDeg = value;
if (cameraJitterValueText != null) cameraJitterValueText.text = value.ToString("F2");
ApplyAndSave();
}
private void OnResetToDefaultClicked()
{
if (cursorSettings == null) return;
cursorSettings.ResetToDefaultAndSave();
RefreshUIFromSettings();
_pendingSave = false;
}
private void OnSaveClicked()
{
if (cursorSettings == null) return;
cursorSettings.SaveToLocal();
_pendingSave = false;
}
}
}