diff --git a/.idea/.idea.BABA_YAGA/.idea/indexLayout.xml b/.idea/.idea.BABA_YAGA/.idea/indexLayout.xml deleted file mode 100644 index 7b08163c..00000000 --- a/.idea/.idea.BABA_YAGA/.idea/indexLayout.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/Assets/Materials/Ground.mat b/Assets/Materials/Ground.mat index 40b8cc77..436d6180 100644 --- a/Assets/Materials/Ground.mat +++ b/Assets/Materials/Ground.mat @@ -25,6 +25,7 @@ Material: m_Parent: {fileID: 0} m_ModifiedSerializedProperties: 0 m_ValidKeywords: + - _ENVIRONMENTREFLECTIONS_OFF - _NORMALMAP m_InvalidKeywords: - _GLOSSYREFLECTIONS_OFF diff --git a/Assets/Materials/Transparency.mat b/Assets/Materials/Transparency.mat index 5aa9a22e..0e5f621d 100644 --- a/Assets/Materials/Transparency.mat +++ b/Assets/Materials/Transparency.mat @@ -11,7 +11,8 @@ Material: m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} m_Parent: {fileID: 0} m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] + m_ValidKeywords: + - _ENVIRONMENTREFLECTIONS_OFF m_InvalidKeywords: - _GLOSSYREFLECTIONS_OFF m_LightmapFlags: 4 @@ -22,7 +23,6 @@ Material: RenderType: Opaque disabledShaderPasses: - MOTIONVECTORS - - SHADOWCASTER m_LockedProperties: m_SavedProperties: serializedVersion: 3 diff --git a/Assets/Prefabs/Shooter/Player/vShooterMelee_Inventory.prefab b/Assets/Prefabs/Shooter/Player/vShooterMelee_Inventory.prefab index 9d96f5dc..3eec8a03 100644 --- a/Assets/Prefabs/Shooter/Player/vShooterMelee_Inventory.prefab +++ b/Assets/Prefabs/Shooter/Player/vShooterMelee_Inventory.prefab @@ -3274,6 +3274,7 @@ GameObject: - component: {fileID: 1505227404007521061} - component: {fileID: -3829962440237222997} - component: {fileID: -3602722895466718484} + - component: {fileID: 5784434468645741687} m_Layer: 8 m_Name: vShooterMelee_Inventory m_TagString: Player @@ -5084,6 +5085,24 @@ MonoBehaviour: m_DefaultActionMap: Player m_SplitScreenIndex: -1 m_Camera: {fileID: 0} +--- !u!114 &5784434468645741687 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 146720} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c25b53df82df1fd4daabb89c90ce092a, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::OnlyScove.Player.PlayerInteraction + cameraTransform: {fileID: 0} + interactDistance: 3 + interactableLayer: + serializedVersion: 2 + m_Bits: 0 + interactKey: 101 --- !u!1 &149606 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scenes/Main Scene.unity b/Assets/Scenes/Main Scene.unity index a7272e51..b04d38b9 100644 --- a/Assets/Scenes/Main Scene.unity +++ b/Assets/Scenes/Main Scene.unity @@ -423,6 +423,18 @@ PrefabInstance: propertyPath: m_AnchorMax.y value: 0 objectReference: {fileID: 0} + - target: {fileID: 5784434468645741687, guid: 092f8aa667b2004459042a82a4c9e41d, type: 3} + propertyPath: cameraTransform + value: + objectReference: {fileID: 1153753045} + - target: {fileID: 5784434468645741687, guid: 092f8aa667b2004459042a82a4c9e41d, type: 3} + propertyPath: ignoreLayers.m_Bits + value: 256 + objectReference: {fileID: 0} + - target: {fileID: 5784434468645741687, guid: 092f8aa667b2004459042a82a4c9e41d, type: 3} + propertyPath: interactableLayer.m_Bits + value: 524544 + objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] @@ -439,6 +451,27 @@ Transform: m_CorrespondingSourceObject: {fileID: 2207112960010484425, guid: fb7874830b9e56341bf88f2a1123c677, type: 3} m_PrefabInstance: {fileID: 3886963620680427248} m_PrefabAsset: {fileID: 0} +--- !u!1 &1133189362 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 1534469393933210, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + m_PrefabInstance: {fileID: 1932644107} + m_PrefabAsset: {fileID: 0} +--- !u!114 &1133189369 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1133189362} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d41bcdbf11a6d6c4bb61a32e85d1635f, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::OnlyScove.Scripts.DoorInteractable + interactionData: {fileID: 0} + woodDoorScript: {fileID: 0} + animator: {fileID: 0} + boolParameterName: IsOpen --- !u!1 &1142785471 GameObject: m_ObjectHideFlags: 0 @@ -471,6 +504,11 @@ Transform: - {fileID: 1731534} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &1153753045 stripped +Transform: + m_CorrespondingSourceObject: {fileID: 2877311890657080738, guid: 092f8aa667b2004459042a82a4c9e41d, type: 3} + m_PrefabInstance: {fileID: 401287878} + m_PrefabAsset: {fileID: 0} --- !u!1 &1185172173 GameObject: m_ObjectHideFlags: 0 @@ -845,6 +883,82 @@ MonoBehaviour: m_EditorClassIdentifier: Assembly-CSharp::Hallucinate.GameSetup.Maze.MazeRenderer visualProfile: {fileID: 11400000, guid: 15b745b0bb979b84ea937c679ee0f1ed, type: 2} floorHeight: 3.5 +--- !u!1001 &1932644107 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 1534469393933210, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + propertyPath: m_Layer + value: 19 + objectReference: {fileID: 0} + - target: {fileID: 1831504449878450, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + propertyPath: m_Name + value: Door_1_Black + objectReference: {fileID: 0} + - target: {fileID: 1831504449878450, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + propertyPath: m_Layer + value: 19 + objectReference: {fileID: 0} + - target: {fileID: 1875921088058430, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + propertyPath: m_Layer + value: 19 + objectReference: {fileID: 0} + - target: {fileID: 1957651719448814, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + propertyPath: m_Layer + value: 19 + objectReference: {fileID: 0} + - target: {fileID: 4970741399400872, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + propertyPath: m_LocalPosition.x + value: -13.22 + objectReference: {fileID: 0} + - target: {fileID: 4970741399400872, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + propertyPath: m_LocalPosition.y + value: -4.20374 + objectReference: {fileID: 0} + - target: {fileID: 4970741399400872, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + propertyPath: m_LocalPosition.z + value: 3.39 + objectReference: {fileID: 0} + - target: {fileID: 4970741399400872, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 4970741399400872, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4970741399400872, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4970741399400872, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4970741399400872, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4970741399400872, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4970741399400872, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: + - targetCorrespondingSourceObject: {fileID: 1534469393933210, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} + insertIndex: -1 + addedObject: {fileID: 1133189369} + m_SourcePrefab: {fileID: 100100000, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3} --- !u!1 &1997343488 GameObject: m_ObjectHideFlags: 0 @@ -949,7 +1063,7 @@ PrefabInstance: m_Modifications: - target: {fileID: 2207112960010484425, guid: fb7874830b9e56341bf88f2a1123c677, type: 3} propertyPath: m_LocalPosition.x - value: 3.5546 + value: 0.78 objectReference: {fileID: 0} - target: {fileID: 2207112960010484425, guid: fb7874830b9e56341bf88f2a1123c677, type: 3} propertyPath: m_LocalPosition.y @@ -957,7 +1071,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 2207112960010484425, guid: fb7874830b9e56341bf88f2a1123c677, type: 3} propertyPath: m_LocalPosition.z - value: -5.60193 + value: -10.24 objectReference: {fileID: 0} - target: {fileID: 2207112960010484425, guid: fb7874830b9e56341bf88f2a1123c677, type: 3} propertyPath: m_LocalRotation.w @@ -995,6 +1109,10 @@ PrefabInstance: propertyPath: m_Layer value: 8 objectReference: {fileID: 0} + - target: {fileID: 2771692228748849855, guid: fb7874830b9e56341bf88f2a1123c677, type: 3} + propertyPath: m_IsActive + value: 1 + objectReference: {fileID: 0} - target: {fileID: 3657229949309460766, guid: fb7874830b9e56341bf88f2a1123c677, type: 3} propertyPath: fpvTarget value: @@ -1035,3 +1153,4 @@ SceneRoots: - {fileID: 1997343489} - {fileID: 1142785474} - {fileID: 401287878} + - {fileID: 1932644107} diff --git a/Assets/Scripts/Interaction/BaseInteractable.cs b/Assets/Scripts/Interaction/BaseInteractable.cs index d8c1452d..741a4675 100644 --- a/Assets/Scripts/Interaction/BaseInteractable.cs +++ b/Assets/Scripts/Interaction/BaseInteractable.cs @@ -4,34 +4,49 @@ namespace OnlyScove.Scripts { public abstract class BaseInteractable : MonoBehaviour, IInteractable { + [Header("Interaction Settings")] [SerializeField] protected ObjectInteraction interactionData; private float lastInteractTime; - public virtual string InteractionPrompt => interactionData != null ? interactionData.promptText : "Interact"; + public virtual string InteractionPrompt => interactionData != null ? interactionData.promptText : "Tương tác"; - // public virtual void OnInteract(PlayerStateMachine player) - // { - // if (Time.time < lastInteractTime + (interactionData != null ? interactionData.interactionCooldown : 0f)) - // return; - // - // lastInteractTime = Time.time; - // - // // Play sound if assigned - // if (interactionData != null && interactionData.interactionSound != null) - // { - // AudioSource.PlayClipAtPoint(interactionData.interactionSound, transform.position); - // } - // - // // Spawn VFX if assigned - // if (interactionData != null && interactionData.interactionVFX != null) - // { - // Instantiate(interactionData.interactionVFX, transform.position, Quaternion.identity); - // } - // - // PerformInteraction(player); - // } - // - // protected abstract void PerformInteraction(PlayerStateMachine player); + public virtual void OnInteract(GameObject interactor) + { + // Kiểm tra Cooldown + float cooldown = interactionData != null ? interactionData.interactionCooldown : 0.5f; + if (Time.time < lastInteractTime + cooldown) + return; + + lastInteractTime = Time.time; + + // Phát âm thanh nếu có + if (interactionData != null && interactionData.interactionSound != null) + { + AudioSource.PlayClipAtPoint(interactionData.interactionSound, transform.position); + } + + // Tạo hiệu ứng VFX nếu có + if (interactionData != null && interactionData.interactionVFX != null) + { + Instantiate(interactionData.interactionVFX, transform.position, Quaternion.identity); + } + + // Gọi logic tương tác cụ thể của từng loại vật thể + PerformInteraction(interactor); + } + + public virtual void OnHoverEnter() + { + // Sẽ thêm logic Highlight ở Giai đoạn 4 + } + + public virtual void OnHoverExit() + { + // Sẽ xóa logic Highlight ở Giai đoạn 4 + } + + // Logic cụ thể bắt buộc các lớp con (Cửa, Cần gạt...) phải triển khai + protected abstract void PerformInteraction(GameObject interactor); } -} \ No newline at end of file +} diff --git a/Assets/Scripts/Interaction/DoorInteractable.cs b/Assets/Scripts/Interaction/DoorInteractable.cs index 8df7de00..7e681e05 100644 --- a/Assets/Scripts/Interaction/DoorInteractable.cs +++ b/Assets/Scripts/Interaction/DoorInteractable.cs @@ -51,7 +51,6 @@ namespace OnlyScove.Scripts if (animator == null) animator = GetComponentInParent(); // 3. TỰ ĐỘNG TẮT SCRIPT XUNG ĐỘT (CameraOpenDoor) nếu nó đang tồn tại trên Camera - // Điều này giúp hệ thống của bạn chiếm quyền điều khiển hoàn toàn var conflictingScript = Object.FindFirstObjectByType(); if (conflictingScript != null) { @@ -60,31 +59,24 @@ namespace OnlyScove.Scripts } } - // protected override void PerformInteraction(PlayerStateMachine player) - // { - // Debug.Log($"[Interaction] PerformInteraction CALLED on {gameObject.name}!"); - // - // // 1. Ưu tiên script của Door Pack (Wood Door Script) - // if (woodDoorScript != null) - // { - // Debug.Log($"[Interaction] Calling woodDoorScript.OpenDoor() on {gameObject.name}. Previous state: {woodDoorScript.open}"); - // woodDoorScript.OpenDoor(); - // isOpen = woodDoorScript.open; - // Debug.Log($"[Interaction] New state: {woodDoorScript.open}"); - // return; - // } - // - // // 2. Nếu không có script Pack mới dùng Animator - // if (animator != null) - // { - // isOpen = !isOpen; - // animator.SetBool(boolParameterName, isOpen); - // Debug.Log($"[Interaction] Triggered Animator: {boolParameterName} = {isOpen}"); - // } - // else - // { - // Debug.LogError($"[Interaction] FAILED: No woodDoorScript or animator found on {gameObject.name}"); - // } - // } + protected override void PerformInteraction(GameObject interactor) + { + Debug.Log($"[Interaction] PerformInteraction CALLED on {gameObject.name}!"); + + // 1. Ưu tiên script của Door Pack (Wood Door Script) + if (woodDoorScript != null) + { + woodDoorScript.OpenDoor(); + isOpen = woodDoorScript.open; + return; + } + + // 2. Nếu không có script Pack mới dùng Animator + if (animator != null) + { + isOpen = !isOpen; + animator.SetBool(boolParameterName, isOpen); + } + } } -} \ No newline at end of file +} diff --git a/Assets/Scripts/Interaction/LampInteractable.cs b/Assets/Scripts/Interaction/LampInteractable.cs index 27e2b7ec..775590ca 100644 --- a/Assets/Scripts/Interaction/LampInteractable.cs +++ b/Assets/Scripts/Interaction/LampInteractable.cs @@ -44,14 +44,14 @@ namespace OnlyScove.Scripts UpdateLightState(); } - // protected override void PerformInteraction(PlayerStateMachine player) - // { - // isOn = !isOn; - // UpdateLightState(); - // - // // Log cực mạnh để bạn kiểm tra Console - // Debug.LogWarning($"[Lamp] Đèn đã chuyển sang: {(isOn ? "BẬT" : "TẮT")}"); - // } + protected override void PerformInteraction(GameObject interactor) + { + isOn = !isOn; + UpdateLightState(); + + // Log cực mạnh để bạn kiểm tra Console + Debug.LogWarning($"[Lamp] Đèn đã chuyển sang: {(isOn ? "BẬT" : "TẮT")}"); + } private void UpdateLightState() { diff --git a/Assets/Scripts/Interface/IInteractable.cs b/Assets/Scripts/Interface/IInteractable.cs index ed7a5ba1..bcc68207 100644 --- a/Assets/Scripts/Interface/IInteractable.cs +++ b/Assets/Scripts/Interface/IInteractable.cs @@ -1,8 +1,18 @@ +using UnityEngine; + namespace OnlyScove.Scripts { public interface IInteractable { string InteractionPrompt { get; } - // void OnInteract(PlayerStateMachine player); + + // Thực hiện tương tác + void OnInteract(GameObject interactor); + + // Xử lý khi người chơi nhìn vào vật thể + void OnHoverEnter(); + + // Xử lý khi người chơi rời mắt khỏi vật thể + void OnHoverExit(); } -} \ No newline at end of file +} diff --git a/Assets/Scripts/Player/PlayerInteraction.cs b/Assets/Scripts/Player/PlayerInteraction.cs new file mode 100644 index 00000000..e5ae579e --- /dev/null +++ b/Assets/Scripts/Player/PlayerInteraction.cs @@ -0,0 +1,105 @@ +using UnityEngine; +using OnlyScove.Scripts; +using Invector.vCamera; + +namespace OnlyScove.Player +{ + public class PlayerInteraction : MonoBehaviour + { + [Header("Settings")] + [SerializeField] private float interactDistance = 4f; + [SerializeField] private LayerMask interactableLayer; + [SerializeField] private KeyCode interactKey = KeyCode.E; + + private Camera mainCam; + private IInteractable currentInteractable; + + private void Start() + { + FindCamera(); + } + + private void FindCamera() + { + // 1. Tìm Invector Camera + if (vThirdPersonCamera.instance != null) + mainCam = vThirdPersonCamera.instance.GetComponent(); + + // 2. Dự phòng Camera.main + if (mainCam == null) mainCam = Camera.main; + + if (mainCam != null) + Debug.Log($"[Interaction] Đã kết nối với Camera: {mainCam.name}"); + } + + private void Update() + { + if (mainCam == null || !mainCam.isActiveAndEnabled) { FindCamera(); return; } + + // Vẽ tia Ray để Debug + Debug.DrawRay(mainCam.transform.position, mainCam.transform.forward * interactDistance, Color.red); + + CheckInteraction(); + HandleInput(); + } + + private void CheckInteraction() + { + // Bắn Ray từ tâm Camera (Giống logic CameraOpenDoor của Asset) + Ray ray = mainCam.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0)); + RaycastHit hit; + + // Bỏ qua Layer Player (8) để không bị chặn bởi lưng nhân vật + int layerMask = ~(1 << 8); + + if (Physics.Raycast(ray, out hit, interactDistance, layerMask)) + { + // 1. Kiểm tra Interface IInteractable (Hệ thống của chúng ta) + IInteractable interactable = hit.collider.GetComponentInParent(); + + // 2. Kiểm tra trực tiếp script Door (Nếu là Door từ Asset Wood Door Pack) + if (interactable == null) + { + var doorScript = hit.collider.GetComponentInParent(); + if (doorScript != null) + { + // Tự động bọc script Door của Asset vào hệ thống của chúng ta nếu nó chưa có + interactable = hit.collider.gameObject.GetComponentInParent(); + if (interactable == null) + { + // Nếu trúng Door mà chưa có DoorInteractable, báo để bạn biết + // Debug.LogWarning($"[Interaction] Trúng Door {hit.collider.name} nhưng thiếu script DoorInteractable!"); + } + } + } + + if (interactable != null) + { + if (currentInteractable != interactable) + { + if (currentInteractable != null) currentInteractable.OnHoverExit(); + currentInteractable = interactable; + currentInteractable.OnHoverEnter(); + Debug.Log($"[Interaction] NHÌN TRÚNG: {hit.collider.gameObject.name}"); + } + return; + } + } + + if (currentInteractable != null) + { + currentInteractable.OnHoverExit(); + currentInteractable = null; + } + } + + private void HandleInput() + { + if (currentInteractable != null && Input.GetKeyDown(interactKey)) + { + Debug.Log("[Interaction] THỰC HIỆN TƯƠNG TÁC!"); + currentInteractable.OnInteract(gameObject); + } + } + } +} diff --git a/Assets/Scripts/Player/PlayerInteraction.cs.meta b/Assets/Scripts/Player/PlayerInteraction.cs.meta new file mode 100644 index 00000000..80a144b9 --- /dev/null +++ b/Assets/Scripts/Player/PlayerInteraction.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c25b53df82df1fd4daabb89c90ce092a \ No newline at end of file diff --git a/Assets/Scripts/Tuấn.meta b/Assets/Scripts/Tuấn.meta new file mode 100644 index 00000000..b0bf5ed5 --- /dev/null +++ b/Assets/Scripts/Tuấn.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5ce3d3ef991b9c34baf5cdc7e782f909 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Tuấn/Plan.txt b/Assets/Scripts/Tuấn/Plan.txt new file mode 100644 index 00000000..5d8372aa --- /dev/null +++ b/Assets/Scripts/Tuấn/Plan.txt @@ -0,0 +1,33 @@ + 1. Hệ thống Core (Dễ) + * Mục tiêu: Xây dựng nền tảng cho mọi vật thể tương tác. + * Các bước: + * Hoàn thiện Interface IInteractable và lớp trừu tượng BaseInteractable. + * Tạo script PlayerInteraction sử dụng Raycast từ Camera để phát hiện vật thể và nhận lệnh nhấn phím (ví dụ: phím E). + + 2. UI Prompt & Âm thanh (Dễ) + * Mục tiêu: Phản hồi trực quan và âm thanh cho người chơi. + * Các bước: + * Thêm thành phần hiển thị Text vào HUD (sử dụng UIToolkit như các UI hiện tại của bạn). + * Tích hợp âm thanh từ dữ liệu ObjectInteraction (ScriptableObject) vào hàm tương tác cơ bản. + + 3. Highlight & Tương tác vật lý (Trung bình) + * Mục tiêu: Làm nổi bật vật thể và thực hiện các tương tác đóng/mở. + * Các bước: + * Object Highlight: Sử dụng Outline shader hoặc thay đổi Material khi người chơi nhìn vào vật thể. + * Door Interaction: Hoàn thiện logic mở/đóng cửa (kết nối với Animator hoặc script có sẵn). + * Lever/Switch: Tạo hệ thống cần gạt sử dụng UnityEvent để kích hoạt các sự kiện khác trong màn chơi. + + 4. Tương tác đặc biệt & Logic (Khó) + * Mục tiêu: Các cơ chế gameplay phức tạp hơn. + * Các bước: + * Fake Wall: Tường giả biến mất hoặc cho phép đi xuyên qua. + * Teleport: Dịch chuyển người chơi đến vị trí chỉ định. + * Exit: Xử lý chuyển Scene hoặc kết thúc màn chơi. + * Mirror: Hiệu ứng gương phản chiếu và logic tương tác riêng. + + 5. Đồng bộ Online & Kiểm thử (Cực khó) + * Mục tiêu: Đảm bảo hệ thống hoạt động trong môi trường Multiplayer. + * Các bước: + * Sử dụng Photon (RPC) để đồng bộ trạng thái vật thể (ví dụ: khi một người mở cửa, tất cả mọi người đều thấy cửa mở). + Cách thức triển khai: Chúng ta sẽ đi theo mô hình Modular. Tôi sẽ xây dựng hệ thống Core trước, sau đó mỗi loại vật thể (Cửa, Cần gạt, Tường giả...) sẽ là một Module riêng kế thừa từ Core. Điều này giúp code của bạn sạch, dễ + quản lý và dễ mở rộng sau này. \ No newline at end of file diff --git a/Assets/Scripts/Tuấn/Plan.txt.meta b/Assets/Scripts/Tuấn/Plan.txt.meta new file mode 100644 index 00000000..e130f4b0 --- /dev/null +++ b/Assets/Scripts/Tuấn/Plan.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 54fd09d52f600024291972ed9edfcc52 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEST CUA TUAN/Free Wood Door Pack/Scene/Demo.unity b/Assets/TEST CUA TUAN/Free Wood Door Pack/Scene/Demo.unity index 47556aec..5e2dc139 100644 --- a/Assets/TEST CUA TUAN/Free Wood Door Pack/Scene/Demo.unity +++ b/Assets/TEST CUA TUAN/Free Wood Door Pack/Scene/Demo.unity @@ -5540,7 +5540,7 @@ MonoBehaviour: m_BlockingObjects: 0 m_BlockingMask: serializedVersion: 2 - m_Bits: 4294967295 + m_Bits: 4161798071 --- !u!114 &1967599012 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset index 0aeecc0d..211596a2 100644 --- a/ProjectSettings/TagManager.asset +++ b/ProjectSettings/TagManager.asset @@ -52,7 +52,7 @@ TagManager: - BlockAIRayCast - Pushable - CoverPoint - - + - Interactable - - -