From ab734e8081d7909423652b84cda9c906f58b35a5 Mon Sep 17 00:00:00 2001 From: Jeonghyeon Ha Date: Thu, 28 Aug 2025 16:52:18 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9D=B8=ED=84=B0=EB=9E=99=EC=85=98=20?= =?UTF-8?q?=EC=88=A8=EA=B9=80=20=EC=A1=B0=EA=B1=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/RestaurantOrder.prefab | 266 +++++++++++++++++- .../_Scripts/Game/GameEvent/IInteractable.cs | 2 +- .../Customer/Actions/StartRestaurantOrder.cs | 2 - .../Character/Core/CharacterInteraction.cs | 9 +- .../Character/Player/PlayerInteraction.cs | 12 +- .../Event/Cosmetic/InteractableHighlight.cs | 5 +- .../Event/RestaurantInteractionComponent.cs | 21 +- 7 files changed, 305 insertions(+), 12 deletions(-) diff --git a/Assets/_DDD/Restaurant/Environments/Interactables/Common/RestaurantOrder.prefab b/Assets/_DDD/Restaurant/Environments/Interactables/Common/RestaurantOrder.prefab index 546d96553..6220a9d00 100644 --- a/Assets/_DDD/Restaurant/Environments/Interactables/Common/RestaurantOrder.prefab +++ b/Assets/_DDD/Restaurant/Environments/Interactables/Common/RestaurantOrder.prefab @@ -98,6 +98,9 @@ GameObject: - component: {fileID: 3697702677815423220} - component: {fileID: 3591347921553422000} - component: {fileID: 4456475204957017828} + - component: {fileID: 2950132940454135295} + - component: {fileID: 29040892075516248} + - component: {fileID: 1332098886975329103} m_Layer: 7 m_Name: RestaurantOrder m_TagString: Untagged @@ -154,4 +157,265 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: c0b1e0992510498b8d33d5b6094b8f4b, type: 3} m_Name: m_EditorClassIdentifier: - orderType: 0 + _currentRestaurantOrderType: 0 +--- !u!135 &2950132940454135295 +SphereCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4103096974375017811} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 1 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Radius: 0.2 + m_Center: {x: -0.4, y: 0, z: 0} +--- !u!114 &29040892075516248 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4103096974375017811} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 888380afc233049ce9e618f9f36c8ba8, type: 3} + m_Name: + m_EditorClassIdentifier: + profile: {fileID: 0} + profileSync: 0 + camerasLayerMask: + serializedVersion: 2 + m_Bits: 4294967295 + effectGroup: 0 + effectTarget: {fileID: 0} + effectGroupLayer: + serializedVersion: 2 + m_Bits: 4294967295 + effectNameFilter: + effectNameUseRegEx: 0 + combineMeshes: 0 + alphaCutOff: 0.5 + cullBackFaces: 0 + padding: 0 + ignoreObjectVisibility: 0 + reflectionProbes: 0 + GPUInstancing: 1 + sortingPriority: 0 + optimizeSkinnedMesh: 1 + depthClip: 0 + cameraDistanceFade: 0 + cameraDistanceFadeNear: 0 + cameraDistanceFadeFar: 1000 + normalsOption: 0 + ignore: 0 + _highlighted: 0 + fadeInDuration: 0 + fadeOutDuration: 0 + flipY: 0 + constantWidth: 1 + extraCoveragePixels: 0 + minimumWidth: 0 + subMeshMask: -1 + overlay: 0 + overlayMode: 0 + overlayColor: {r: 1, g: 0.92156863, b: 0.015686275, a: 1} + overlayAnimationSpeed: 1 + overlayMinIntensity: 0.5 + overlayBlending: 1 + overlayTexture: {fileID: 0} + overlayTextureUVSpace: 0 + overlayTextureScale: 1 + overlayTextureScrolling: {x: 0, y: 0} + overlayVisibility: 0 + outline: 1 + outlineColor: {r: 0, g: 0, b: 0, a: 1} + outlineColorStyle: 0 + outlineGradient: + serializedVersion: 2 + key0: {r: 1, g: 1, b: 1, a: 1} + key1: {r: 1, g: 1, b: 1, a: 1} + key2: {r: 0, g: 0, b: 0, a: 0} + key3: {r: 0, g: 0, b: 0, a: 0} + key4: {r: 0, g: 0, b: 0, a: 0} + key5: {r: 0, g: 0, b: 0, a: 0} + key6: {r: 0, g: 0, b: 0, a: 0} + key7: {r: 0, g: 0, b: 0, a: 0} + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_ColorSpace: -1 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + outlineGradientInLocalSpace: 0 + outlineWidth: 0.45 + outlineBlurPasses: 2 + outlineQuality: 2 + outlineEdgeMode: 0 + outlineEdgeThreshold: 0.995 + outlineSharpness: 1 + outlineDownsampling: 1 + outlineVisibility: 0 + glowBlendMode: 0 + outlineBlitDebug: 0 + outlineIndependent: 0 + outlineContourStyle: 0 + outlineMaskMode: 0 + glow: 0 + glowWidth: 0.4 + glowQuality: 2 + glowBlurMethod: 0 + glowDownsampling: 2 + glowHQColor: {r: 0.64, g: 1, b: 0, a: 1} + glowDithering: 1 + glowDitheringStyle: 0 + glowMagicNumber1: 0.75 + glowMagicNumber2: 0.5 + glowAnimationSpeed: 1 + glowVisibility: 0 + glowBlitDebug: 0 + glowBlendPasses: 1 + glowPasses: + - offset: 4 + alpha: 0.1 + color: {r: 0.64, g: 1, b: 0, a: 1} + - offset: 3 + alpha: 0.2 + color: {r: 0.64, g: 1, b: 0, a: 1} + - offset: 2 + alpha: 0.3 + color: {r: 0.64, g: 1, b: 0, a: 1} + - offset: 1 + alpha: 0.4 + color: {r: 0.64, g: 1, b: 0, a: 1} + glowMaskMode: 0 + innerGlow: 0 + innerGlowWidth: 1 + innerGlowColor: {r: 1, g: 1, b: 1, a: 1} + innerGlowBlendMode: 0 + innerGlowVisibility: 0 + targetFX: 0 + targetFXTexture: {fileID: 0} + targetFXColor: {r: 1, g: 1, b: 1, a: 1} + targetFXCenter: {fileID: 0} + targetFXRotationSpeed: 50 + targetFXInitialScale: 4 + targetFXEndScale: 1.5 + targetFXScaleToRenderBounds: 1 + targetFXUseEnclosingBounds: 0 + targetFXAlignToGround: 0 + targetFXOffset: {x: 0, y: 0, z: 0} + targetFXFadePower: 32 + targetFXGroundMaxDistance: 10 + targetFXGroundLayerMask: + serializedVersion: 2 + m_Bits: 4294967295 + targetFXTransitionDuration: 0.5 + targetFXStayDuration: 1.5 + targetFXVisibility: 1 + iconFX: 0 + iconFXMesh: {fileID: 0} + iconFXLightColor: {r: 1, g: 1, b: 1, a: 1} + iconFXDarkColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + iconFXCenter: {fileID: 0} + iconFXRotationSpeed: 50 + iconFXAnimationOption: 0 + iconFXAnimationAmount: 0.1 + iconFXAnimationSpeed: 3 + iconFXScale: 1 + iconFXScaleToRenderBounds: 0 + iconFXOffset: {x: 0, y: 1, z: 0} + iconFXTransitionDuration: 0.5 + iconFXStayDuration: 1.5 + seeThrough: 2 + seeThroughOccluderMask: + serializedVersion: 2 + m_Bits: 4294967295 + seeThroughOccluderThreshold: 0.3 + seeThroughOccluderMaskAccurate: 0 + seeThroughOccluderCheckInterval: 1 + seeThroughOccluderCheckIndividualObjects: 0 + seeThroughDepthOffset: 0 + seeThroughMaxDepth: 0 + seeThroughIntensity: 0.8 + seeThroughTintAlpha: 0.5 + seeThroughTintColor: {r: 1, g: 0, b: 0, a: 1} + seeThroughNoise: 1 + seeThroughBorder: 0 + seeThroughBorderColor: {r: 0, g: 0, b: 0, a: 1} + seeThroughBorderOnly: 0 + seeThroughBorderWidth: 0.45 + seeThroughOrdered: 0 + seeThroughTexture: {fileID: 0} + seeThroughTextureUVSpace: 0 + seeThroughTextureScale: 1 + seeThroughChildrenSortingMode: 0 + rmsCount: 1 + hitFxInitialIntensity: 0 + hitFxMode: 0 + hitFxFadeOutDuration: 0.25 + hitFxColor: {r: 1, g: 1, b: 1, a: 1} + hitFxRadius: 0.5 +--- !u!114 &1332098886975329103 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4103096974375017811} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f0feb22ab60a4d1885271637838f43b9, type: 3} + m_Name: + m_EditorClassIdentifier: + _availableStyle: + Color: {r: 1, g: 1, b: 1, a: 1} + Width: 1 + Opacity: 1 + _focusedStyle: + Color: {r: 1, g: 0.92156863, b: 0.015686275, a: 1} + Width: 1 + Opacity: 1 + _unavailableStyle: + Color: {r: 0.5, g: 0.5, b: 0.5, a: 1} + Width: 0.5 + Opacity: 1 + _objectiveStyle: + Color: {r: 0, g: 1, b: 1, a: 1} + Width: 1 + Opacity: 1 + _breathingSpeed: 2 + _breathingRange: 0.3 + _enableBreathingEffect: 1 + _alphaCutOff: 0.5 + _combineMeshes: 1 + _constantWidth: 1 + _outlineQuality: 2 + _outlineIndependent: 1 + _outlineBlurPasses: 1 + _outlineSharpness: 8 + _currentOutlineType: 0 + _currentOpacityMultiplier: 1 diff --git a/Assets/_DDD/_Scripts/Game/GameEvent/IInteractable.cs b/Assets/_DDD/_Scripts/Game/GameEvent/IInteractable.cs index 72831c1fd..8131ac6dd 100644 --- a/Assets/_DDD/_Scripts/Game/GameEvent/IInteractable.cs +++ b/Assets/_DDD/_Scripts/Game/GameEvent/IInteractable.cs @@ -39,7 +39,7 @@ public InteractionDisplayParameters(string messageKey = "") public interface IInteractable { bool CanInteract(); - bool IsInteractionHidden(); + bool IsInteractionHidden(IInteractor interactor = null); void OnInteracted(IInteractor interactor, ScriptableObject causerPayload = null); InteractionType GetInteractionType(); GameObject GetInteractableGameObject(); diff --git a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/StartRestaurantOrder.cs b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/StartRestaurantOrder.cs index 0e5cd3b9d..f294c5c79 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/StartRestaurantOrder.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/StartRestaurantOrder.cs @@ -25,7 +25,6 @@ public override TaskStatus OnUpdate() var blackboard = gameObject.GetComponent(); var target = blackboard?.GetBlackboardGameObject(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget)); IInteractable currentInteractable = target?.GetComponent(); - if (_targetOrderType == RestaurantOrderType.Wait) { // 레스토랑 주문 인터랙션 후보를 가져옴 @@ -54,7 +53,6 @@ public override TaskStatus OnUpdate() return TaskStatus.Failure; } } - if (currentInteractable == null) { diff --git a/Assets/_DDD/_Scripts/Restaurant/Character/Core/CharacterInteraction.cs b/Assets/_DDD/_Scripts/Restaurant/Character/Core/CharacterInteraction.cs index 5ec7c67ac..c8352108f 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Character/Core/CharacterInteraction.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Character/Core/CharacterInteraction.cs @@ -84,7 +84,7 @@ public bool CanSolveInteractionType(InteractionType type) { if (_cachedSolvers.TryGetValue(type, out var cachedSolver)) return cachedSolver != null; - if (RestaurantInteractionEventSolvers.TypeToSolver.TryGetValue(type, out var solverType) == false) return false; + if (!FetchSolverTypeForInteraction(type, out var solverType)) return false; if (transform.TryGetComponent(solverType, out var component) == false) return false; @@ -92,7 +92,12 @@ public bool CanSolveInteractionType(InteractionType type) _cachedSolvers[type] = solver; return solver != null; } - + + protected virtual bool FetchSolverTypeForInteraction(InteractionType type, out Type solverType) + { + return RestaurantInteractionEventSolvers.TypeToSolver.TryGetValue(type, out solverType); + } + public bool CanInteractTo(IInteractable interactable, ScriptableObject payloadSo = null) { if (interactable == null) return false; diff --git a/Assets/_DDD/_Scripts/Restaurant/Character/Player/PlayerInteraction.cs b/Assets/_DDD/_Scripts/Restaurant/Character/Player/PlayerInteraction.cs index 6053e032b..c9db8be25 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Character/Player/PlayerInteraction.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Character/Player/PlayerInteraction.cs @@ -185,7 +185,7 @@ protected IInteractable GetNearestInteractable() if (col.TryGetComponent(out var interactable) == false) continue; var type = interactable.GetInteractionType(); - if (interactable.IsInteractionHidden()) continue; + if (interactable.IsInteractionHidden(this)) continue; if (CanSolveInteractionType(type) == false) continue; float distance = Vector3.Distance(transform.position, col.transform.position); @@ -198,5 +198,15 @@ protected IInteractable GetNearestInteractable() return closest; } + + protected override bool FetchSolverTypeForInteraction(InteractionType type, out Type solverType) + { + if (RestaurantInteractionEventSolvers.TypeToPlayerSolver.TryGetValue(type, out solverType)) + { + return true; + } + + return base.FetchSolverTypeForInteraction(type, out solverType); + } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Event/Cosmetic/InteractableHighlight.cs b/Assets/_DDD/_Scripts/Restaurant/Event/Cosmetic/InteractableHighlight.cs index 8d6272b14..24006ed2f 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Event/Cosmetic/InteractableHighlight.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Event/Cosmetic/InteractableHighlight.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using UnityEngine; using Sirenix.OdinInspector; @@ -157,8 +158,8 @@ private InteractionOutlineType GetCurrentOutlineType() // IInteractable 인터페이스로 캐스팅하여 상태 확인 if (_interactionComponent is not IInteractable interactable) return InteractionOutlineType.None; - - if (_interactionComponent.IsInteractionHidden()) + + if (_interactionComponent.IsInteractionHidden(_interactor)) { return InteractionOutlineType.None; } diff --git a/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantInteractionComponent.cs b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantInteractionComponent.cs index f13b03a20..7d757bfdd 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantInteractionComponent.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantInteractionComponent.cs @@ -67,11 +67,26 @@ public virtual bool CanInteract() return isInteractionVisible && hasValidSubsystem; } - public virtual bool IsInteractionHidden() + public virtual bool IsInteractionHidden(IInteractor interactor = null) { var currentGameFlowState = GameFlowManager.Instance.GameFlowDataSo.CurrentGameState; var flowDisabled = (currentGameFlowState & _interactionAvailableFlows) == 0; - return flowDisabled; + if (flowDisabled) + { + return true; + } + + // only check if interactor is valid. if not, pass the check. + if (interactor != null && HasSubsystem(_interactionType)) + { + bool canSolve = interactor.CanSolveInteractionType(_interactionType); + if (!canSolve) + { + return true; + } + } + + return false; } public virtual void OnInteracted(IInteractor interactor, ScriptableObject payload = null) @@ -119,7 +134,7 @@ private bool HasSubsystem(InteractionType interactionType) private IInteractionSubsystemObject GetSubsystem(InteractionType interactionType) { - return _subsystems.GetValueOrDefault(interactionType) as IInteractionSubsystemObject; + return _subsystems.GetValueOrDefault(interactionType); } private bool TryGetSubsystem(InteractionType interactionType, out IInteractionSubsystemObject subsystem)