diff --git a/.idea/.idea.HALLUCINATE/.idea/workspace.xml b/.idea/.idea.HALLUCINATE/.idea/workspace.xml index f7666299..36a03fad 100644 --- a/.idea/.idea.HALLUCINATE/.idea/workspace.xml +++ b/.idea/.idea.HALLUCINATE/.idea/workspace.xml @@ -6,11 +6,12 @@ - - - + - + + + + @@ -137,7 +139,8 @@ - + + diff --git a/Assets/Resources/Localization.meta b/Assets/Resources/Localization.meta new file mode 100644 index 00000000..b6bc3b60 --- /dev/null +++ b/Assets/Resources/Localization.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 115b7971291d64d42bf41732f4d2fcb6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Localization/en.json b/Assets/Resources/Localization/en.json new file mode 100644 index 00000000..8050ef78 --- /dev/null +++ b/Assets/Resources/Localization/en.json @@ -0,0 +1,15 @@ +{ + "menu_create": "CREATE ROOM", + "menu_join": "JOIN ROOM", + "menu_settings": "SETTINGS", + "menu_exit": "EXIT", + "settings_title": "SETTINGS", + "settings_general": "GENERAL", + "settings_graphics": "GRAPHICS", + "settings_audio": "AUDIO", + "settings_controls": "CONTROLS", + "settings_back": "BACK", + "label_fov": "Field of View", + "label_sensitivity": "Sensitivity", + "label_language": "Language" +} diff --git a/Assets/Resources/Localization/en.json.meta b/Assets/Resources/Localization/en.json.meta new file mode 100644 index 00000000..3de9f369 --- /dev/null +++ b/Assets/Resources/Localization/en.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d949fd6576700b54eb12847a360f99cd +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Localization/vi.json b/Assets/Resources/Localization/vi.json new file mode 100644 index 00000000..a20485d2 --- /dev/null +++ b/Assets/Resources/Localization/vi.json @@ -0,0 +1,15 @@ +{ + "menu_create": "TẠO PHÒNG", + "menu_join": "VÀO PHÒNG", + "menu_settings": "CÀI ĐẶT", + "menu_exit": "THOÁT", + "settings_title": "CÀI ĐẶT", + "settings_general": "CHUNG", + "settings_graphics": "ĐỒ HỌA", + "settings_audio": "ÂM THANH", + "settings_controls": "ĐIỀU KHIỂN", + "settings_back": "QUAY LẠI", + "label_fov": "Tầm nhìn (FOV)", + "label_sensitivity": "Độ nhạy chuột", + "label_language": "Ngôn ngữ" +} diff --git a/Assets/Resources/Localization/vi.json.meta b/Assets/Resources/Localization/vi.json.meta new file mode 100644 index 00000000..4d26e944 --- /dev/null +++ b/Assets/Resources/Localization/vi.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5f5574ecd78b063488d5a0a2609bf48a +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scove/UIScaleTest.unity b/Assets/Scove/UIScaleTest.unity index 8a88abbb..a750c7ac 100644 --- a/Assets/Scove/UIScaleTest.unity +++ b/Assets/Scove/UIScaleTest.unity @@ -256,6 +256,7 @@ GameObject: m_Component: - component: {fileID: 666657093} - component: {fileID: 666657092} + - component: {fileID: 666657094} m_Layer: 0 m_Name: Doc_Profile m_TagString: Untagged @@ -301,6 +302,18 @@ Transform: m_Children: [] m_Father: {fileID: 1183887570} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &666657094 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 666657091} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fdea16b110511ef45889ed832b63560b, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::UI.ProfileController --- !u!1 &1136953558 GameObject: m_ObjectHideFlags: 0 @@ -311,6 +324,7 @@ GameObject: m_Component: - component: {fileID: 1136953560} - component: {fileID: 1136953559} + - component: {fileID: 1136953561} m_Layer: 0 m_Name: Doc_HUD m_TagString: Untagged @@ -356,6 +370,19 @@ Transform: m_Children: [] m_Father: {fileID: 1183887570} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1136953561 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1136953558} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e79b70607af6eeb458c8eb6605e39b56, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::UI.HUDController + hudDocument: {fileID: 1136953559} --- !u!1 &1183887568 GameObject: m_ObjectHideFlags: 0 @@ -382,26 +409,36 @@ MonoBehaviour: m_GameObject: {fileID: 1183887568} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 3f728362556756d45bddb65280fdab1d, type: 3} + m_Script: {fileID: 11500000, guid: bcb7b8ed439bb4546b0648c627c2ce5d, type: 3} m_Name: m_EditorClassIdentifier: Assembly-CSharp::UI.UIManager screens: - screenName: Doc_MainMenu document: {fileID: 2003742651} isActive: 0 + isOverlay: 0 + customCursor: {fileID: 0} - screenName: Doc_Lobby document: {fileID: 1471116802} isActive: 0 + isOverlay: 0 + customCursor: {fileID: 0} - screenName: Doc_HUD document: {fileID: 1136953559} isActive: 0 + isOverlay: 0 + customCursor: {fileID: 0} - screenName: Doc_Settings document: {fileID: 1582124357} isActive: 0 + isOverlay: 0 + customCursor: {fileID: 0} - screenName: Doc_Profile document: {fileID: 666657092} - isActive: 0 - globalOpacity: 1 + isActive: 1 + isOverlay: 0 + customCursor: {fileID: 0} + defaultCursor: {fileID: 0} --- !u!4 &1183887570 Transform: m_ObjectHideFlags: 0 @@ -432,6 +469,7 @@ GameObject: m_Component: - component: {fileID: 1471116803} - component: {fileID: 1471116802} + - component: {fileID: 1471116804} m_Layer: 0 m_Name: Doc_Lobby m_TagString: Untagged @@ -477,6 +515,18 @@ Transform: m_Children: [] m_Father: {fileID: 1183887570} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1471116804 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1471116801} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9c37c552a9c18a242bcc8860a0a5212f, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::UI.LobbyController --- !u!1 &1582124356 GameObject: m_ObjectHideFlags: 0 @@ -487,6 +537,7 @@ GameObject: m_Component: - component: {fileID: 1582124358} - component: {fileID: 1582124357} + - component: {fileID: 1582124359} m_Layer: 0 m_Name: Doc_Settings m_TagString: Untagged @@ -532,6 +583,18 @@ Transform: m_Children: [] m_Father: {fileID: 1183887570} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1582124359 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1582124356} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5534bcf4869df944883c6fd2a17a6a5a, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::UI.SettingsController --- !u!1 &1848374378 GameObject: m_ObjectHideFlags: 0 @@ -679,6 +742,7 @@ GameObject: m_Component: - component: {fileID: 2003742650} - component: {fileID: 2003742651} + - component: {fileID: 2003742652} m_Layer: 0 m_Name: Doc_MainMenu m_TagString: Untagged @@ -724,6 +788,18 @@ MonoBehaviour: m_PivotReferenceSize: 0 m_Pivot: 0 m_WorldSpaceCollider: {fileID: 0} +--- !u!114 &2003742652 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2003742649} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 691980524acfc544f9660cfc35ce3616, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::UI.MainMenuController --- !u!1660057539 &9223372036854775807 SceneRoots: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/Player Controller/PlayerStateMachine.cs b/Assets/Scripts/Player Controller/PlayerStateMachine.cs index ccac042f..3e302b04 100644 --- a/Assets/Scripts/Player Controller/PlayerStateMachine.cs +++ b/Assets/Scripts/Player Controller/PlayerStateMachine.cs @@ -47,36 +47,15 @@ namespace OnlyScove.Scripts [field: SerializeField] public LayerMask InteractionMask { get; private set; } [Networked] public Quaternion NetworkedCameraRotation { get; set; } - - public Quaternion CameraRotation - { - get - { - if (Runner != null && Runner.IsRunning && Object != null) - return NetworkedCameraRotation; - - if (Cam != null) - return Cam.PlanarRotation; - - return transform.rotation; - } - } - [Networked] public Vector2 NetworkedMoveInput { get; set; } [Networked] public float NetworkedSpeed { get; set; } [Networked] public Vector3 NetworkedPosition { get; set; } [Header("Player Stats")] - [Networked, OnChangedRender(nameof(OnHealthChangedRender))] - public float Health { get; set; } = 100f; + [Networked, OnChangedRender(nameof(OnHealthChangedRender))] public float Health { get; set; } = 100f; + [Networked, OnChangedRender(nameof(OnStaminaChangedRender))] public float Stamina { get; set; } = 100f; + [Networked, OnChangedRender(nameof(OnNoiseLevelChangedRender))] public float NoiseLevel { get; set; } = 0f; - [Networked, OnChangedRender(nameof(OnStaminaChangedRender))] - public float Stamina { get; set; } = 100f; - - [Networked, OnChangedRender(nameof(OnNoiseLevelChangedRender))] - public float NoiseLevel { get; set; } = 0f; - - // Sự kiện để UI lắng nghe public event System.Action OnHealthChanged; public event System.Action OnStaminaChanged; public event System.Action OnNoiseLevelChanged; @@ -87,19 +66,26 @@ namespace OnlyScove.Scripts public float VelocityY { get; set; } public bool IsGrounded { get; private set; } public bool WasGrounded { get; private set; } - - private List interactablesNearby = new List(); - private int currentInteractableIndex = 0; - public string CurrentStateName => currentState != null ? currentState.GetType().Name : "None"; - public static PlayerStateMachine Local { get; private set; } + + public Quaternion CameraRotation + { + get + { + if (Runner != null && Runner.IsRunning && Object != null) return NetworkedCameraRotation; + return Cam != null ? Cam.PlanarRotation : transform.rotation; + } + } private PlayerBaseState currentState; private bool hasControl = true; private bool hasSpeedParam; private bool hasVelocityXParam; private bool hasVelocityZParam; + private List interactablesNearby = new List(); + private int currentInteractableIndex = 0; + private float localAnimatorSpeed; protected virtual void Awake() { @@ -125,41 +111,30 @@ namespace OnlyScove.Scripts private void Start() { - if (Runner == null || !Runner.IsRunning) - { - InitializePlayer(); - } + if (Runner == null || !Runner.IsRunning) InitializePlayer(); } public override void Spawned() { InitializePlayer(); - if (Object != null && !Object.HasInputAuthority && Runner.IsClient) { if (Controller != null) Controller.enabled = false; } } - // Callbacks từ attribute OnChangedRender void OnHealthChangedRender() => OnHealthChanged?.Invoke(Health); void OnStaminaChangedRender() => OnStaminaChanged?.Invoke(Stamina); void OnNoiseLevelChangedRender() => OnNoiseLevelChanged?.Invoke(NoiseLevel); private void InitializePlayer() { - if (currentState == null) - { - SwitchState(new PlayerIdleState(this)); - } + if (currentState == null) SwitchState(new PlayerIdleState(this)); bool isOffline = Runner == null || !Runner.IsRunning; - bool hasAuthority = Object != null && Object.HasInputAuthority; - - if (isOffline || hasAuthority) + if (isOffline || (Object != null && Object.HasInputAuthority)) { Local = this; - CameraController cameraController = GameObject.FindAnyObjectByType(); if (cameraController != null) { @@ -167,26 +142,17 @@ namespace OnlyScove.Scripts Cam.followTarget = transform; Cam.inputReader = Input; } - Input.OnNextInteractEvent += OnNextInteract; Input.OnPreviousInteractEvent += OnPreviousInteract; - if (Controller != null) Controller.enabled = true; } } - private float localAnimatorSpeed; - public void Rotate(Vector3 moveDirection, float deltaTime) { if (moveDirection == Vector3.zero) return; - Quaternion targetRot = Quaternion.LookRotation(moveDirection); - transform.rotation = Quaternion.RotateTowards( - transform.rotation, - targetRot, - RotationSpeed * deltaTime - ); + transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRot, RotationSpeed * deltaTime); } public void Move(Vector3 velocity, float animatorSpeed, float deltaTime) @@ -197,40 +163,23 @@ namespace OnlyScove.Scripts if (Controller != null && Controller.enabled) { Controller.Move(velocity * deltaTime); - if (Object != null && Runner != null && Runner.IsRunning) - { - NetworkedPosition = transform.position; - } + if (Object != null && Runner != null && Runner.IsRunning) NetworkedPosition = transform.position; } localAnimatorSpeed = animatorSpeed; - if (Object != null && Object.HasStateAuthority) { NetworkedSpeed = animatorSpeed; NetworkedMoveInput = MoveInput; } - UpdateAnimator(deltaTime); } private void UpdateAnimator(float deltaTime) { if (Anim == null) return; - - float speedValue; - Vector2 inputVector; - - if (Runner == null || !Runner.IsRunning || Object.HasInputAuthority) - { - speedValue = localAnimatorSpeed; - inputVector = MoveInput; - } - else - { - speedValue = NetworkedSpeed; - inputVector = NetworkedMoveInput; - } + float speedValue = (Runner == null || !Runner.IsRunning || Object.HasInputAuthority) ? localAnimatorSpeed : NetworkedSpeed; + Vector2 inputVector = (Runner == null || !Runner.IsRunning || Object.HasInputAuthority) ? MoveInput : NetworkedMoveInput; if (hasSpeedParam) Anim.SetFloat(speedHash, speedValue, AnimationDamping, deltaTime); if (hasVelocityXParam) Anim.SetFloat(velocityXHash, inputVector.x * speedValue, AnimationDamping, deltaTime); @@ -242,14 +191,11 @@ namespace OnlyScove.Scripts bool isRunning = Runner != null && Runner.IsRunning; if (Object == null && isRunning) return; - if (isRunning && NetworkedPosition != Vector3.zero) + if (isRunning && NetworkedPosition != Vector3.zero && !Object.HasInputAuthority) { - if (Controller != null && !Object.HasInputAuthority) - { - Controller.enabled = false; - transform.position = NetworkedPosition; - Controller.enabled = true; - } + Controller.enabled = false; + transform.position = NetworkedPosition; + Controller.enabled = true; } if (GetInput(out PlayerInputData data)) @@ -269,52 +215,35 @@ namespace OnlyScove.Scripts IsSprintHeld = false; } - bool isSimulating = !isRunning || Object.HasInputAuthority || Runner.IsServer; - - if (!isSimulating) + if (!isRunning || Object.HasInputAuthority || Runner.IsServer) + { + if (hasControl) + { + WasGrounded = IsGrounded; + CheckGround(); + UpdateInteractablesList(); + currentState?.Tick(isRunning ? Runner.DeltaTime : Time.fixedDeltaTime); + } + } + else { UpdateAnimator(Runner.DeltaTime); - return; } - - if (!hasControl) return; - - WasGrounded = IsGrounded; - CheckGround(); - UpdateInteractablesList(); - - float dt = isRunning ? Runner.DeltaTime : Time.fixedDeltaTime; - currentState?.Tick(dt); } private void Update() { - if (Runner == null || !Runner.IsRunning) - { - FixedUpdateNetwork(); - } + if (Runner == null || !Runner.IsRunning) FixedUpdateNetwork(); } - private void CheckGround() - { - IsGrounded = Physics.CheckSphere(transform.TransformPoint(GroundCheckOffset), GroundCheckRadius, GroundMask); - } + private void CheckGround() => IsGrounded = Physics.CheckSphere(transform.TransformPoint(GroundCheckOffset), GroundCheckRadius, GroundMask); private void UpdateInteractablesList() { interactablesNearby.Clear(); IInteractable target = Scanner.ScanForInteractable(InteractionRange, InteractionMask); - - if (target != null) - { - interactablesNearby.Add(target); - OnInteractableTargetChanged?.Invoke(target); - } - else - { - OnInteractableTargetChanged?.Invoke(null); - } - + if (target != null) interactablesNearby.Add(target); + OnInteractableTargetChanged?.Invoke(target); currentInteractableIndex = 0; } @@ -328,22 +257,13 @@ namespace OnlyScove.Scripts private void OnPreviousInteract() { if (interactablesNearby.Count <= 1) return; - currentInteractableIndex--; - if (currentInteractableIndex < 0) currentInteractableIndex = interactablesNearby.Count - 1; + currentInteractableIndex = (currentInteractableIndex - 1 + interactablesNearby.Count) % interactablesNearby.Count; OnInteractableTargetChanged?.Invoke(GetInteractable()); } - public IInteractable GetInteractable() - { - if (interactablesNearby.Count == 0) return null; - return interactablesNearby[currentInteractableIndex]; - } + public IInteractable GetInteractable() => interactablesNearby.Count == 0 ? null : interactablesNearby[currentInteractableIndex]; - public void SetGroundCheck(float radius, Vector3 offset) - { - GroundCheckRadius = radius; - GroundCheckOffset = offset; - } + public void SetGroundCheck(float radius, Vector3 offset) { GroundCheckRadius = radius; GroundCheckOffset = offset; } public void SwitchState(PlayerBaseState newState) { diff --git a/Assets/Scripts/UI/HUDController.cs b/Assets/Scripts/UI/HUDController.cs index 1ba21f86..f9d7937f 100644 --- a/Assets/Scripts/UI/HUDController.cs +++ b/Assets/Scripts/UI/HUDController.cs @@ -23,7 +23,6 @@ namespace UI var root = hudDocument.rootVisualElement; - // Tìm các thành phần UI theo Name (Bạn cần đặt tên này trong UXML) _healthFill = root.Q("health-fill"); _staminaFill = root.Q("stamina-fill"); _healthText = root.Q