2026-04-25 18:20:16 +07:00
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.UIElements;
|
|
|
|
|
using OnlyScove.Scripts;
|
|
|
|
|
|
|
|
|
|
namespace UI
|
|
|
|
|
{
|
|
|
|
|
public class SettingsController : MonoBehaviour
|
|
|
|
|
{
|
|
|
|
|
private UIDocument _doc;
|
|
|
|
|
private CameraController _cameraController;
|
|
|
|
|
|
|
|
|
|
// Tabs Content
|
|
|
|
|
private VisualElement _contentGeneral, _contentGraphics, _contentAudio;
|
|
|
|
|
private Button _tabGeneral, _tabGraphics, _tabAudio, _tabControls;
|
|
|
|
|
|
|
|
|
|
private void OnEnable()
|
|
|
|
|
{
|
|
|
|
|
_doc = GetComponent<UIDocument>();
|
|
|
|
|
_cameraController = Object.FindFirstObjectByType<CameraController>();
|
|
|
|
|
|
|
|
|
|
var root = _doc.rootVisualElement;
|
|
|
|
|
|
|
|
|
|
// Query Tabs
|
|
|
|
|
_tabGeneral = root.Q<Button>("tab-general");
|
|
|
|
|
_tabGraphics = root.Q<Button>("tab-graphics");
|
|
|
|
|
_tabAudio = root.Q<Button>("tab-audio");
|
|
|
|
|
_tabControls = root.Q<Button>("tab-controls");
|
|
|
|
|
|
|
|
|
|
// Query Content
|
|
|
|
|
_contentGeneral = root.Q<VisualElement>("content-general");
|
|
|
|
|
_contentGraphics = root.Q<VisualElement>("content-graphics");
|
|
|
|
|
_contentAudio = root.Q<VisualElement>("content-audio");
|
|
|
|
|
|
|
|
|
|
// Events
|
|
|
|
|
_tabGeneral.clicked += () => SwitchTab(_contentGeneral, _tabGeneral);
|
|
|
|
|
_tabGraphics.clicked += () => SwitchTab(_contentGraphics, _tabGraphics);
|
|
|
|
|
_tabAudio.clicked += () => SwitchTab(_contentAudio, _tabAudio);
|
|
|
|
|
|
|
|
|
|
root.Q<Button>("btn-back").clicked += () => UIManager.Instance.ToggleSettings();
|
|
|
|
|
|
|
|
|
|
// Camera Binding (FOV)
|
|
|
|
|
var fovSlider = root.Q<Slider>("setting-fov");
|
|
|
|
|
if (fovSlider != null)
|
|
|
|
|
{
|
2026-04-26 00:27:56 +07:00
|
|
|
if (SettingsManager.Instance != null) fovSlider.value = SettingsManager.Instance.Settings.fieldOfView;
|
2026-04-25 18:20:16 +07:00
|
|
|
fovSlider.RegisterValueChangedCallback(evt => {
|
2026-04-26 00:27:56 +07:00
|
|
|
if (SettingsManager.Instance != null) SettingsManager.Instance.Settings.fieldOfView = evt.newValue;
|
|
|
|
|
if (_cameraController != null) _cameraController.SetFOV(evt.newValue);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sensitivity Binding
|
|
|
|
|
var sensSlider = root.Q<Slider>("setting-sensitivity");
|
|
|
|
|
if (sensSlider != null)
|
|
|
|
|
{
|
|
|
|
|
if (SettingsManager.Instance != null) sensSlider.value = SettingsManager.Instance.Settings.sensitivity;
|
|
|
|
|
sensSlider.RegisterValueChangedCallback(evt => {
|
|
|
|
|
if (SettingsManager.Instance != null) SettingsManager.Instance.SetSensitivity(evt.newValue);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Invert X Binding
|
|
|
|
|
var invertXToggle = root.Q<Toggle>("setting-invert-x");
|
|
|
|
|
if (invertXToggle != null)
|
|
|
|
|
{
|
|
|
|
|
if (SettingsManager.Instance != null) invertXToggle.value = SettingsManager.Instance.Settings.invertX;
|
|
|
|
|
invertXToggle.RegisterValueChangedCallback(evt => {
|
|
|
|
|
if (SettingsManager.Instance != null) SettingsManager.Instance.SetInvertX(evt.newValue);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Invert Y Binding
|
|
|
|
|
var invertYToggle = root.Q<Toggle>("setting-invert-y");
|
|
|
|
|
if (invertYToggle != null)
|
|
|
|
|
{
|
|
|
|
|
if (SettingsManager.Instance != null) invertYToggle.value = SettingsManager.Instance.Settings.invertY;
|
|
|
|
|
invertYToggle.RegisterValueChangedCallback(evt => {
|
|
|
|
|
if (SettingsManager.Instance != null) SettingsManager.Instance.SetInvertY(evt.newValue);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Side Bias Binding
|
|
|
|
|
var sideDropdown = root.Q<DropdownField>("setting-camera-side");
|
|
|
|
|
if (sideDropdown != null)
|
|
|
|
|
{
|
|
|
|
|
if (SettingsManager.Instance != null) sideDropdown.index = SettingsManager.Instance.Settings.sideBiasRight ? 0 : 1;
|
|
|
|
|
sideDropdown.RegisterValueChangedCallback(evt => {
|
|
|
|
|
if (SettingsManager.Instance != null) SettingsManager.Instance.SetSideBias(evt.newValue == "Right");
|
2026-04-25 18:20:16 +07:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Language Binding
|
|
|
|
|
var langDropdown = root.Q<DropdownField>("setting-language");
|
|
|
|
|
if (langDropdown != null)
|
|
|
|
|
{
|
|
|
|
|
langDropdown.RegisterValueChangedCallback(evt => {
|
|
|
|
|
string code = evt.newValue == "English" ? "en" : "vi";
|
|
|
|
|
LocalizationManager.Instance.LoadLanguage(code);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Lắng nghe sự kiện đổi ngôn ngữ để cập nhật Text
|
|
|
|
|
if (LocalizationManager.Instance != null)
|
|
|
|
|
{
|
|
|
|
|
LocalizationManager.Instance.OnLanguageChanged += UpdateTexts;
|
|
|
|
|
UpdateTexts();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Debug.LogWarning("[SettingsController] LocalizationManager Instance not found in scene!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SwitchTab(VisualElement targetContent, Button targetTab)
|
|
|
|
|
{
|
|
|
|
|
if (targetContent == null || targetTab == null) return;
|
|
|
|
|
|
|
|
|
|
// Ẩn tất cả (Thêm null check)
|
|
|
|
|
if (_contentGeneral != null) _contentGeneral.style.display = DisplayStyle.None;
|
|
|
|
|
if (_contentGraphics != null) _contentGraphics.style.display = DisplayStyle.None;
|
|
|
|
|
if (_contentAudio != null) _contentAudio.style.display = DisplayStyle.None;
|
|
|
|
|
|
|
|
|
|
if (_tabGeneral != null) _tabGeneral.RemoveFromClassList("active-tab");
|
|
|
|
|
if (_tabGraphics != null) _tabGraphics.RemoveFromClassList("active-tab");
|
|
|
|
|
if (_tabAudio != null) _tabAudio.RemoveFromClassList("active-tab");
|
|
|
|
|
|
|
|
|
|
// Hiện cái được chọn
|
|
|
|
|
targetContent.style.display = DisplayStyle.Flex;
|
|
|
|
|
targetTab.AddToClassList("active-tab");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateTexts()
|
|
|
|
|
{
|
|
|
|
|
if (LocalizationManager.Instance == null) return;
|
|
|
|
|
|
|
|
|
|
var root = _doc.rootVisualElement;
|
|
|
|
|
|
|
|
|
|
// Dùng null-conditional operator (?.) để cực kỳ an toàn
|
|
|
|
|
var titleLabel = root.Q<Label>("title");
|
|
|
|
|
if (titleLabel != null) titleLabel.text = LocalizationManager.Instance.Get("settings_title");
|
|
|
|
|
|
|
|
|
|
if (_tabGeneral != null) _tabGeneral.text = LocalizationManager.Instance.Get("settings_general");
|
|
|
|
|
if (_tabGraphics != null) _tabGraphics.text = LocalizationManager.Instance.Get("settings_graphics");
|
|
|
|
|
if (_tabAudio != null) _tabAudio.text = LocalizationManager.Instance.Get("settings_audio");
|
|
|
|
|
if (_tabControls != null) _tabControls.text = LocalizationManager.Instance.Get("settings_controls");
|
|
|
|
|
|
|
|
|
|
var btnBack = root.Q<Button>("btn-back");
|
|
|
|
|
if (btnBack != null) btnBack.text = LocalizationManager.Instance.Get("settings_back");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|