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; } } }