update
This commit is contained in:
@@ -44,12 +44,50 @@ namespace OnlyScove.Scripts
|
||||
private float CurrentPositionSmoothTime => _currentViewMode == CameraViewMode.FirstPerson ? fpvPositionSmoothTime : positionSmoothTime;
|
||||
private float CurrentRotationSmoothTime => _currentViewMode == CameraViewMode.FirstPerson ? fpvRotationSmoothTime : rotationSmoothTime;
|
||||
|
||||
// Public properties for UI binding
|
||||
public float Sensitivity => rotationHandler != null ? GetPrivateSensitivity() : 1f;
|
||||
public bool InvertX => rotationHandler != null ? GetPrivateInvertX() : false;
|
||||
public bool InvertY => rotationHandler != null ? GetPrivateInvertY() : false;
|
||||
|
||||
private float GetPrivateSensitivity()
|
||||
{
|
||||
var field = typeof(CameraRotationHandler).GetField("sensitivity", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
return field != null ? (float)field.GetValue(rotationHandler) : 0.1f;
|
||||
}
|
||||
|
||||
private bool GetPrivateInvertX()
|
||||
{
|
||||
var field = typeof(CameraRotationHandler).GetField("invertX", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
return field != null ? (bool)field.GetValue(rotationHandler) : false;
|
||||
}
|
||||
|
||||
private bool GetPrivateInvertY()
|
||||
{
|
||||
var field = typeof(CameraRotationHandler).GetField("invertY", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
return field != null ? (bool)field.GetValue(rotationHandler) : false;
|
||||
}
|
||||
|
||||
public void SetFOV(float value)
|
||||
{
|
||||
tpvBaseFOV = value;
|
||||
if (_currentViewMode == CameraViewMode.ThirdPerson && !_inTransition)
|
||||
{
|
||||
_cam.fieldOfView = value;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (inputReader != null)
|
||||
{
|
||||
inputReader.OnToggleViewEvent += ToggleCameraView;
|
||||
}
|
||||
|
||||
if (SettingsManager.Instance != null)
|
||||
{
|
||||
SettingsManager.Instance.OnSettingsChanged += ApplyGlobalSettings;
|
||||
ApplyGlobalSettings();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
@@ -58,6 +96,28 @@ namespace OnlyScove.Scripts
|
||||
{
|
||||
inputReader.OnToggleViewEvent -= ToggleCameraView;
|
||||
}
|
||||
|
||||
if (SettingsManager.Instance != null)
|
||||
{
|
||||
SettingsManager.Instance.OnSettingsChanged -= ApplyGlobalSettings;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyGlobalSettings()
|
||||
{
|
||||
if (SettingsManager.Instance == null || SettingsManager.Instance.Settings == null) return;
|
||||
|
||||
var settings = SettingsManager.Instance.Settings;
|
||||
|
||||
// Note: Since I cannot modify CameraRotationHandler.cs, I am using reflection
|
||||
// to fulfill the "apply these values dynamically" requirement without changing the file.
|
||||
// This is a workaround requested by the user's constraint.
|
||||
var type = typeof(CameraRotationHandler);
|
||||
type.GetField("sensitivity", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.SetValue(rotationHandler, settings.sensitivity * 0.1f);
|
||||
type.GetField("invertX", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.SetValue(rotationHandler, settings.invertX);
|
||||
type.GetField("invertY", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.SetValue(rotationHandler, settings.invertY);
|
||||
|
||||
SetFOV(settings.fieldOfView);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
@@ -138,7 +198,7 @@ namespace OnlyScove.Scripts
|
||||
transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref _currentVelocity, CurrentPositionSmoothTime) + shakeManager.ShakeOffset;
|
||||
}
|
||||
|
||||
private void ToggleCameraView()
|
||||
public void ToggleCameraView()
|
||||
{
|
||||
if (_inTransition) return; // Prevent multiple toggles during transition
|
||||
|
||||
|
||||
@@ -16,16 +16,23 @@ namespace OnlyScove.Scripts
|
||||
|
||||
public void HandleSideBias(InputReader inputReader)
|
||||
{
|
||||
if (inputReader == null) return;
|
||||
float targetBias = 0f;
|
||||
|
||||
if (useSideBias)
|
||||
if (SettingsManager.Instance != null && SettingsManager.Instance.Settings != null)
|
||||
{
|
||||
float targetBias = -inputReader.MoveInput.x * horizontalBiasAmount;
|
||||
// Fixed offset based on settings
|
||||
targetBias = SettingsManager.Instance.Settings.sideBiasRight ? horizontalBiasAmount : -horizontalBiasAmount;
|
||||
}
|
||||
|
||||
if (useSideBias && inputReader != null)
|
||||
{
|
||||
// Optionally combine with movement-based bias if desired,
|
||||
// but following requirement "Toggling the camera offset between Left/Right"
|
||||
_currentSideBias = Mathf.Lerp(_currentSideBias, targetBias, biasSmoothTime * Time.deltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentSideBias = 0;
|
||||
_currentSideBias = Mathf.Lerp(_currentSideBias, 0, biasSmoothTime * Time.deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
17
Assets/Scripts/GameSetup/GameSettings.cs
Normal file
17
Assets/Scripts/GameSetup/GameSettings.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace OnlyScove.Scripts
|
||||
{
|
||||
[CreateAssetMenu(fileName = "GameSettings", menuName = "Settings/GameSettings")]
|
||||
public class GameSettings : ScriptableObject
|
||||
{
|
||||
[Header("Camera Settings")]
|
||||
public float sensitivity = 1.0f;
|
||||
public bool invertX = false;
|
||||
public bool invertY = false;
|
||||
public bool sideBiasRight = true; // true for Right, false for Left
|
||||
|
||||
[Header("Other Settings")]
|
||||
public float fieldOfView = 60f;
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/GameSetup/GameSettings.cs.meta
Normal file
2
Assets/Scripts/GameSetup/GameSettings.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e9fd2c44d7c5bc428b9b4eb12f4a7e1
|
||||
63
Assets/Scripts/GameSetup/SettingsManager.cs
Normal file
63
Assets/Scripts/GameSetup/SettingsManager.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace OnlyScove.Scripts
|
||||
{
|
||||
public class SettingsManager : MonoBehaviour
|
||||
{
|
||||
public static SettingsManager Instance { get; private set; }
|
||||
|
||||
[SerializeField] private GameSettings settings;
|
||||
public GameSettings Settings => settings;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance == null)
|
||||
{
|
||||
Instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
|
||||
if (settings == null)
|
||||
{
|
||||
// Fallback or load from Resources if needed
|
||||
settings = ScriptableObject.CreateInstance<GameSettings>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetSensitivity(float value)
|
||||
{
|
||||
settings.sensitivity = value;
|
||||
OnSettingsChanged?.Invoke();
|
||||
}
|
||||
|
||||
public void SetInvertX(bool value)
|
||||
{
|
||||
settings.invertX = value;
|
||||
OnSettingsChanged?.Invoke();
|
||||
}
|
||||
|
||||
public void SetInvertY(bool value)
|
||||
{
|
||||
settings.invertY = value;
|
||||
OnSettingsChanged?.Invoke();
|
||||
}
|
||||
|
||||
public void SetSideBias(bool isRight)
|
||||
{
|
||||
settings.sideBiasRight = isRight;
|
||||
OnSettingsChanged?.Invoke();
|
||||
}
|
||||
|
||||
public void ToggleSideBias()
|
||||
{
|
||||
settings.sideBiasRight = !settings.sideBiasRight;
|
||||
OnSettingsChanged?.Invoke();
|
||||
}
|
||||
|
||||
public event System.Action OnSettingsChanged;
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/GameSetup/SettingsManager.cs.meta
Normal file
2
Assets/Scripts/GameSetup/SettingsManager.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86e70fc045fbf71469903c69f7f54e67
|
||||
@@ -15,6 +15,7 @@ namespace UI
|
||||
private Label _noiseLabel;
|
||||
private Label _interactionLabel;
|
||||
private VisualElement _interactionPrompt;
|
||||
private Button _btnToggleView;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
@@ -29,6 +30,15 @@ namespace UI
|
||||
_noiseLabel = root.Q<Label>("noise-label");
|
||||
_interactionLabel = root.Q<Label>("interaction-text");
|
||||
_interactionPrompt = root.Q<VisualElement>("interaction-prompt");
|
||||
|
||||
_btnToggleView = root.Q<Button>("btn-toggle-view");
|
||||
if (_btnToggleView != null)
|
||||
{
|
||||
_btnToggleView.clicked += () => {
|
||||
var cam = Object.FindFirstObjectByType<CameraController>();
|
||||
if (cam != null) cam.ToggleCameraView();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
@@ -63,10 +73,13 @@ namespace UI
|
||||
_currentPlayer.OnNoiseLevelChanged += UpdateNoise;
|
||||
_currentPlayer.OnInteractableTargetChanged += UpdateInteraction;
|
||||
|
||||
// Cập nhật giá trị ban đầu
|
||||
UpdateHealth(_currentPlayer.Health);
|
||||
UpdateStamina(_currentPlayer.Stamina);
|
||||
UpdateNoise(_currentPlayer.NoiseLevel);
|
||||
// Cập nhật giá trị ban đầu - Kiểm tra xem đã Spawned chưa nếu là Network Object
|
||||
if (player.Object == null || player.Object.IsValid)
|
||||
{
|
||||
UpdateHealth(_currentPlayer.Health);
|
||||
UpdateStamina(_currentPlayer.Stamina);
|
||||
UpdateNoise(_currentPlayer.NoiseLevel);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateHealth(float health)
|
||||
|
||||
@@ -42,9 +42,50 @@ namespace UI
|
||||
var fovSlider = root.Q<Slider>("setting-fov");
|
||||
if (fovSlider != null)
|
||||
{
|
||||
if (SettingsManager.Instance != null) fovSlider.value = SettingsManager.Instance.Settings.fieldOfView;
|
||||
fovSlider.RegisterValueChangedCallback(evt => {
|
||||
// Cần expose hoặc tạo hàm SetFOV trong CameraController
|
||||
Debug.Log($"Setting FOV to: {evt.newValue}");
|
||||
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");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,29 @@ namespace UI
|
||||
private void Update()
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.Escape)) ToggleSettings();
|
||||
HandleAltCursor();
|
||||
}
|
||||
|
||||
private void HandleAltCursor()
|
||||
{
|
||||
// Only handle Alt cursor when we are in game (HUD is active)
|
||||
// and Settings is NOT currently toggled on.
|
||||
var settingsData = screens.Find(s => s.screenName == "Settings");
|
||||
bool settingsActive = settingsData != null && settingsData.isActive;
|
||||
|
||||
if (_currentScreenName == "HUD" && !settingsActive)
|
||||
{
|
||||
if (Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt))
|
||||
{
|
||||
UnityEngine.Cursor.visible = true;
|
||||
UnityEngine.Cursor.lockState = CursorLockMode.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Cursor.visible = false;
|
||||
UnityEngine.Cursor.lockState = CursorLockMode.Locked;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowOnly(string name) => ShowScreen(name);
|
||||
|
||||
Reference in New Issue
Block a user