From b70634ddcaa49c3b441bfe86a36a2dc42fe96e1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=86=E1=85=B5=E1=86=AB?= =?UTF-8?q?=E1=84=80=E1=85=AE?= Date: Wed, 8 Jul 2026 05:13:08 +0900 Subject: [PATCH] =?UTF-8?q?=EB=94=94=EB=B2=84=EA=B7=B8=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- unity-client/Assets/Scenes/battleStage.unity | 556 +++++++++++++++++- unity-client/Assets/Scripts/BattleManager.cs | 163 +++++ .../Assets/Scripts/BattleManager.cs.meta | 2 + unity-client/Assets/Scripts/Enemy.cs | 97 +++ unity-client/Assets/Scripts/Enemy.cs.meta | 2 + unity-client/Assets/Scripts/GameManager.cs | 10 + .../Assets/Scripts/NPCDialogueManager.cs | 29 - unity-client/Assets/Scripts/Player.cs | 66 +-- 8 files changed, 843 insertions(+), 82 deletions(-) create mode 100644 unity-client/Assets/Scripts/BattleManager.cs create mode 100644 unity-client/Assets/Scripts/BattleManager.cs.meta create mode 100644 unity-client/Assets/Scripts/Enemy.cs create mode 100644 unity-client/Assets/Scripts/Enemy.cs.meta diff --git a/unity-client/Assets/Scenes/battleStage.unity b/unity-client/Assets/Scenes/battleStage.unity index 400e5dd..7228803 100644 --- a/unity-client/Assets/Scenes/battleStage.unity +++ b/unity-client/Assets/Scenes/battleStage.unity @@ -5450,6 +5450,17 @@ SpriteRenderer: m_SpriteTileMode: 0 m_WasSpriteAssigned: 1 m_SpriteSortPoint: 0 +--- !u!114 &320546034 stripped +MonoBehaviour: + m_CorrespondingSourceObject: {fileID: 911507061901746167, guid: 6c5f439021e347c4f87cc1c7168e955b, type: 3} + m_PrefabInstance: {fileID: 1482696888} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image --- !u!1 &335091082 stripped GameObject: m_CorrespondingSourceObject: {fileID: 103380811750077614, guid: dc4d03e9834464d82a1dec0da2b8162f, type: 3} @@ -5536,6 +5547,143 @@ MonoBehaviour: maxHp: 5 nameText: {fileID: 0} hpImage: {fileID: 0} +--- !u!1 &366661995 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 366661996} + - component: {fileID: 366661998} + - component: {fileID: 366661997} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &366661996 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 366661995} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1853696807} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &366661997 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 366661995} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: ed494d8deb7a7455f8affd65d9a92eef, type: 2} + m_sharedMaterial: {fileID: -5035255238556258946, guid: ed494d8deb7a7455f8affd65d9a92eef, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 24 + m_fontSizeBase: 24 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_characterHorizontalScale: 1 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &366661998 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 366661995} + m_CullTransparentMesh: 1 --- !u!1 &403148640 GameObject: m_ObjectHideFlags: 0 @@ -6378,6 +6526,128 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 706593201} m_CullTransparentMesh: 1 +--- !u!1001 &792134314 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_Pivot.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_Pivot.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_AnchorMax.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_AnchorMax.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_AnchorMin.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_AnchorMin.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_SizeDelta.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_SizeDelta.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_LocalScale.x + value: 5 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_LocalScale.y + value: 5 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_LocalScale.z + value: 5 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_LocalPosition.z + value: 20.6 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_LocalRotation.w + value: 0.9999619 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_LocalRotation.x + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_LocalRotation.y + value: 0.008726557 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_LocalRotation.z + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_AnchoredPosition.x + value: 98.6 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_AnchoredPosition.y + value: -12.4 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5375047960093657315, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_ConstrainProportionsScale + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 8717663361120014766, guid: 64359be8b124840d0bb4846426882691, type: 3} + propertyPath: m_Name + value: Enemy + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: + - targetCorrespondingSourceObject: {fileID: 7979812900128732585, guid: 64359be8b124840d0bb4846426882691, type: 3} + insertIndex: -1 + addedObject: {fileID: 957116746} + - targetCorrespondingSourceObject: {fileID: 7979812900128732585, guid: 64359be8b124840d0bb4846426882691, type: 3} + insertIndex: -1 + addedObject: {fileID: 957116745} + - targetCorrespondingSourceObject: {fileID: 7979812900128732585, guid: 64359be8b124840d0bb4846426882691, type: 3} + insertIndex: -1 + addedObject: {fileID: 957116747} + m_SourcePrefab: {fileID: 100100000, guid: 64359be8b124840d0bb4846426882691, type: 3} --- !u!224 &875108180 stripped RectTransform: m_CorrespondingSourceObject: {fileID: 3800788831750671515, guid: 390aaa741d870044191b55f300c047a5, type: 3} @@ -7734,6 +8004,93 @@ Tilemap: e31: 0 e32: 0 e33: 1 +--- !u!1 &957116741 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 7979812900128732585, guid: 64359be8b124840d0bb4846426882691, type: 3} + m_PrefabInstance: {fileID: 792134314} + m_PrefabAsset: {fileID: 0} +--- !u!70 &957116745 +CapsuleCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 957116741} + m_Enabled: 1 + serializedVersion: 3 + m_Density: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_ForceSendLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ForceReceiveLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_ContactCaptureLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_CallbackLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_CompositeOperation: 0 + m_CompositeOrder: 0 + m_Offset: {x: 0, y: 0.4} + m_Size: {x: 0.5, y: 1} + m_Direction: 0 +--- !u!50 &957116746 +Rigidbody2D: + serializedVersion: 5 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 957116741} + m_BodyType: 0 + m_Simulated: 1 + m_UseFullKinematicContacts: 0 + m_UseAutoMass: 0 + m_Mass: 1 + m_LinearDamping: 0 + m_AngularDamping: 0.05 + m_GravityScale: 1 + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_Interpolate: 0 + m_SleepingMode: 1 + m_CollisionDetection: 0 + m_Constraints: 4 +--- !u!114 &957116747 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 957116741} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0c1488b68fb3e4031a2f0e33d3b95cb5, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::Enemy + enemyName: "\uACE0\uBE14\uB9B0 \uC655" + hp: 30 + maxHp: 30 + attackPower: 2 + nameText: {fileID: 1184594223} + hpImage: {fileID: 320546034} --- !u!1001 &963424159 PrefabInstance: m_ObjectHideFlags: 0 @@ -7835,6 +8192,54 @@ PrefabInstance: m_AddedGameObjects: [] m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 995fb1b7b1d40f54f9494dfbb7dedfe2, type: 3} +--- !u!1 &966922000 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 966922002} + - component: {fileID: 966922001} + m_Layer: 0 + m_Name: BattleManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &966922001 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 966922000} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 33720e9c809ea4966a8848c5535d3f20, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::BattleManager + player: {fileID: 1840371595} + enemy: {fileID: 957116747} + skillInputField: {fileID: 1568869830} + attackButton: {fileID: 1853696804} +--- !u!4 &966922002 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 966922000} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 107.055, y: -6.55568, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &976809381 GameObject: m_ObjectHideFlags: 0 @@ -8263,6 +8668,7 @@ RectTransform: - {fileID: 1925548785} - {fileID: 706593202} - {fileID: 1568869829} + - {fileID: 1853696807} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} @@ -8275,6 +8681,17 @@ RectTransform: m_CorrespondingSourceObject: {fileID: 3800788831750671515, guid: 390aaa741d870044191b55f300c047a5, type: 3} m_PrefabInstance: {fileID: 1102442793} m_PrefabAsset: {fileID: 0} +--- !u!114 &1184594223 stripped +MonoBehaviour: + m_CorrespondingSourceObject: {fileID: 7888741024357894282, guid: 390aaa741d870044191b55f300c047a5, type: 3} + m_PrefabInstance: {fileID: 1102442793} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI --- !u!1 &1339631191 GameObject: m_ObjectHideFlags: 0 @@ -18198,6 +18615,18 @@ PrefabInstance: propertyPath: m_Name value: hp bar background objectReference: {fileID: 0} + - target: {fileID: 8538378379228196241, guid: 6c5f439021e347c4f87cc1c7168e955b, type: 3} + propertyPath: m_Pivot.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8538378379228196241, guid: 6c5f439021e347c4f87cc1c7168e955b, type: 3} + propertyPath: m_AnchoredPosition.x + value: -235.55505 + objectReference: {fileID: 0} + - target: {fileID: 8538378379228196241, guid: 6c5f439021e347c4f87cc1c7168e955b, type: 3} + propertyPath: m_AnchoredPosition.y + value: 1.5000185 + objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] @@ -34080,9 +34509,9 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 9ba0864ae82c04db9a0ab083a089a388, type: 3} m_Name: m_EditorClassIdentifier: Assembly-CSharp::Player - speed: 10 + speed: 5 hp: 5 - maxHp: 0 + maxHp: 5 nameText: {fileID: 1944988752} hpImage: {fileID: 144455365} --- !u!70 &1840371596 @@ -34240,6 +34669,127 @@ SpriteRenderer: m_SpriteTileMode: 0 m_WasSpriteAssigned: 1 m_SpriteSortPoint: 0 +--- !u!1 &1853696803 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1853696807} + - component: {fileID: 1853696806} + - component: {fileID: 1853696805} + - component: {fileID: 1853696804} + m_Layer: 5 + m_Name: Button + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1853696804 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1853696803} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Button + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1853696805} + m_OnClick: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &1853696805 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1853696803} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 176924562, guid: 069a00c4a21d8654bbe27600f3ba7103, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1853696806 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1853696803} + m_CullTransparentMesh: 1 +--- !u!224 &1853696807 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1853696803} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 366661996} + m_Father: {fileID: 1183798055} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 227.16577, y: -270.35367} + m_SizeDelta: {x: 78.3315, y: 60.7073} + m_Pivot: {x: 0.5, y: 0.5} --- !u!1001 &1868975694 PrefabInstance: m_ObjectHideFlags: 0 @@ -34650,3 +35200,5 @@ SceneRoots: - {fileID: 1183798055} - {fileID: 976809384} - {fileID: 529100493} + - {fileID: 792134314} + - {fileID: 966922002} diff --git a/unity-client/Assets/Scripts/BattleManager.cs b/unity-client/Assets/Scripts/BattleManager.cs new file mode 100644 index 0000000..d852d4c --- /dev/null +++ b/unity-client/Assets/Scripts/BattleManager.cs @@ -0,0 +1,163 @@ +using System.Collections; +using UnityEngine; +using UnityEngine.Networking; + +public class BattleManager : MonoBehaviour +{ + [Header("전투 대상 오브젝트 연결")] + public Player player; // 플레이어 캐릭터 + public Enemy enemy; // 적(Enemy) 캐릭터 + + [Header("UI 연결 (선택 사항)")] + public TMPro.TMP_InputField skillInputField; // Canvas에 배치한 텍스트 입력창 + public UnityEngine.UI.Button attackButton; // Canvas에 배치한 공격 버튼 + + private string debugInputText = "불화살을 힘차게 쏜다!"; // OnGUI 디버그용 입력 기본값 + private string statusText = "스킬을 입력하여 전투를 시작하세요."; + private bool isAttacking = false; + + private void Start() + { + // 씬 내의 Player와 Enemy를 지정 안 했을 경우 자동으로 검색하여 매칭합니다. + if (player == null) player = FindObjectOfType(); + if (enemy == null) enemy = FindObjectOfType(); + + // Canvas 버튼 클릭 이벤트 바인딩 + if (attackButton != null) + { + attackButton.onClick.AddListener(OnAttackButtonClick); + } + } + + // Canvas UI의 공격 버튼을 클릭했을 때 호출되는 함수 + public void OnAttackButtonClick() + { + if (isAttacking) return; + + string prompt = ""; + if (skillInputField != null) + { + prompt = skillInputField.text; + } + + if (string.IsNullOrEmpty(prompt)) + { + statusText = "스킬 묘사 텍스트를 입력해 주세요!"; + return; + } + + StartCoroutine(AttackFlowCoroutine(prompt)); + } + + // AI 스킬 연성 및 턴제 상호작용(플레이어 공격 -> 피격 -> 적 반격)을 관리하는 코루틴 + private IEnumerator AttackFlowCoroutine(string skillPrompt) + { + isAttacking = true; + statusText = "AI가 스킬을 연성하는 중입니다..."; + Debug.Log($"[Battle] 스킬 프롬프트 전송 시도: \"{skillPrompt}\""); + + // 1. FastAPI 서버의 generate-skill API 호출 (플레이어 레벨 파라미터에는 Generation 세대값 전달) + string url = "http://127.0.0.1:8000/api/game/generate-skill"; + int playerLevel = (player != null) ? player.Generation : 1; + + SkillCreateRequest requestData = new SkillCreateRequest + { + prompt = skillPrompt, + player_level = playerLevel + }; + string jsonPayload = JsonUtility.ToJson(requestData); + + using (UnityWebRequest request = new UnityWebRequest(url, "POST")) + { + byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(jsonPayload); + request.uploadHandler = new UploadHandlerRaw(bodyRaw); + request.downloadHandler = new DownloadHandlerBuffer(); + request.SetRequestHeader("Content-Type", "application/json"); + + yield return request.SendWebRequest(); + + if (request.result == UnityWebRequest.Result.ConnectionError || + request.result == UnityWebRequest.Result.ProtocolError) + { + Debug.LogError($"[Battle] 스킬 연성 실패: {request.error}"); + statusText = "스킬 연성 실패 (서버 에러)"; + isAttacking = false; + yield break; + } + + // 스킬 데이터 파싱 + string responseText = request.downloadHandler.text; + SkillCreateResponse response = JsonUtility.FromJson(responseText); + + statusText = $"[연성 완료] 스킬: {response.name} | 피해: {response.damage}"; + Debug.Log($"[Battle] 스킬 연성 성공: {response.name} (대미지: {response.damage}) - {response.description}"); + + // 2. 플레이어 공격 애니메이션 및 적 타격 처리 + if (player != null && player.hp > 0) + { + Animator pAnim = player.GetComponentInChildren(); + if (pAnim != null) + { + pAnim.SetTrigger("2_Attack"); // 공격 모션 가동 + } + } + + yield return new WaitForSeconds(0.6f); // 공격 모션 타이밍 대기 + + if (enemy != null) + { + enemy.TakeDamage(response.damage); // 적에게 AI로 생성된 데미지 적용 + } + + // 3. 적이 쓰러졌는지 확인 + if (enemy != null && enemy.hp <= 0) + { + statusText = $"[승리] 적 {enemy.enemyName}을(를) 처치했습니다!"; + isAttacking = false; + yield break; + } + + // 4. 적의 생존 시 반격 턴 개시 (1.5초 후 적이 플레이어를 공격) + yield return new WaitForSeconds(1.5f); + + if (enemy != null && enemy.hp > 0 && player != null && player.hp > 0) + { + statusText = $"적 {enemy.enemyName}의 반격 차례!"; + enemy.Attack(player); // 적의 플레이어 타격 실행 + } + + yield return new WaitForSeconds(1.2f); // 피격 연출 대기 + + if (player != null && player.hp <= 0) + { + statusText = "[패배] 플레이어가 전사했습니다. 씬이 초기화됩니다."; + } + else + { + statusText = "전투 대기 중... 스킬을 입력하고 공격 버튼을 누르세요."; + } + isAttacking = false; + } + } + + +} + +// ---------------------------------------------------- +// JSON 연동용 API 페이로드 스키마 정의 클래스 +// ---------------------------------------------------- +[System.Serializable] +public class SkillCreateRequest +{ + public string prompt; + public int player_level; +} + +[System.Serializable] +public class SkillCreateResponse +{ + public string name; + public int damage; + public float speed; + public string description; +} diff --git a/unity-client/Assets/Scripts/BattleManager.cs.meta b/unity-client/Assets/Scripts/BattleManager.cs.meta new file mode 100644 index 0000000..9365426 --- /dev/null +++ b/unity-client/Assets/Scripts/BattleManager.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 33720e9c809ea4966a8848c5535d3f20 \ No newline at end of file diff --git a/unity-client/Assets/Scripts/Enemy.cs b/unity-client/Assets/Scripts/Enemy.cs new file mode 100644 index 0000000..079e879 --- /dev/null +++ b/unity-client/Assets/Scripts/Enemy.cs @@ -0,0 +1,97 @@ +using UnityEngine; +using UnityEngine.UI; +using TMPro; + +public class Enemy : MonoBehaviour +{ + [Header("적 스탯 설정")] + public string enemyName = "고블린 왕"; + public int hp = 30; + public int maxHp = 30; + public int attackPower = 2; // 플레이어를 공격할 때의 기본 데미지 수치 + + [Header("UI 연결")] + public TextMeshProUGUI nameText; // 적 이름 표시 TMP + public Image hpImage; // 적 체력바 이미지 + + private Animator animator; + + private void Start() + { + maxHp = hp; + + // 자식 오브젝트의 애니메이터(SPUM 리소스 구조)를 획득합니다. + animator = GetComponentInChildren(); + + // 적 캐릭터의 기본 방향을 플레이어를 바라보도록 좌측(스케일 양수)으로 정렬합니다. + Vector3 initialScale = transform.localScale; + initialScale.x = Mathf.Abs(initialScale.x); + transform.localScale = initialScale; + + // 시작 시 적 이름을 UI 텍스트에 연동합니다. + if (nameText != null) + { + nameText.text = enemyName; + } + } + + private void Update() + { + // 안전 조치: maxHp가 비정상(0 이하)이거나 현재 체력이 초과된 경우 자동 동기화 + if (maxHp <= 0 || hp > maxHp) + { + maxHp = hp; + } + + // 플레이어와 동일하게 Simple/Filled 이미지 방식 모두 가로가 정상 감축되도록 이중 연동합니다. + if (hpImage != null && maxHp > 0) + { + float fillRatio = Mathf.Clamp01((float)hp / maxHp); + hpImage.fillAmount = fillRatio; + hpImage.rectTransform.localScale = new Vector3(fillRatio, 1f, 1f); + } + } + + // 플레이어의 공격을 받아 데미지를 입는 메서드 + public void TakeDamage(int damage) + { + if (hp <= 0) return; // 이미 죽은 경우 무시 + + hp -= damage; + if (hp < 0) hp = 0; + + Debug.Log($"[Enemy] 적 {enemyName}이(가) {damage} 피해를 입었습니다. 현재 체력: {hp}/{maxHp}"); + + if (animator != null) + { + if (hp <= 0) + { + // SPUM 리소스 기준 사망(4_Death) 트리거 작동 + animator.SetTrigger("4_Death"); + Debug.Log($"[Enemy] 적 {enemyName}이(가) 사망하였습니다."); + } + else + { + // SPUM 리소스 기준 피격(3_Damaged) 트리거 작동 + animator.SetTrigger("3_Damaged"); + } + } + } + + // 플레이어를 반격 공격하는 메서드 + public void Attack(Player player) + { + if (hp <= 0 || player == null) return; + + Debug.Log($"[Enemy] 적 {enemyName}이(가) 플레이어를 공격합니다! (데미지: {attackPower})"); + + if (animator != null) + { + // SPUM 리소스 기준 공격(2_Attack) 트리거 작동 + animator.SetTrigger("2_Attack"); + } + + // 플레이어 체력 차감 전송 + player.TakeDamage(attackPower, enemyName); + } +} diff --git a/unity-client/Assets/Scripts/Enemy.cs.meta b/unity-client/Assets/Scripts/Enemy.cs.meta new file mode 100644 index 0000000..71aed10 --- /dev/null +++ b/unity-client/Assets/Scripts/Enemy.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 0c1488b68fb3e4031a2f0e33d3b95cb5 \ No newline at end of file diff --git a/unity-client/Assets/Scripts/GameManager.cs b/unity-client/Assets/Scripts/GameManager.cs index 2d3dedf..62d4e0f 100644 --- a/unity-client/Assets/Scripts/GameManager.cs +++ b/unity-client/Assets/Scripts/GameManager.cs @@ -39,4 +39,14 @@ public class GameManager : MonoBehaviour Debug.Log($"[GameManager] 캐릭터 정보 보존 세이브 완료: {playerName} ({playerGeneration}대) | HP: {playerHp}/{playerMaxHp}"); } } + + // 플레이어 보존 세션을 리셋하는 메서드 (사망 시 호출) + public void ClearPlayerData() + { + playerName = ""; + playerGeneration = 1; + playerHp = 5; + playerMaxHp = 5; + Debug.Log("[GameManager] 보존된 이전 플레이어 스탯 데이터를 비웠습니다. (신규 세대 생성 준비 완료)"); + } } diff --git a/unity-client/Assets/Scripts/NPCDialogueManager.cs b/unity-client/Assets/Scripts/NPCDialogueManager.cs index 5e6bdb3..823b36f 100644 --- a/unity-client/Assets/Scripts/NPCDialogueManager.cs +++ b/unity-client/Assets/Scripts/NPCDialogueManager.cs @@ -141,34 +141,5 @@ public class NPCDialogueManager : MonoBehaviour typingCoroutine = null; } - // 디버그용 임시 OnGUI 버튼 - private void OnGUI() - { - GUI.backgroundColor = Color.yellow; - - if (GUI.Button(new Rect(Screen.width - 240, 10, 220, 50), "Debug: Get NPC Dialogue")) - { - Player player = FindObjectOfType(); - if (player != null) - { - RequestNPCDialogue(player.Generation); - } - else - { - RequestNPCDialogue(1); - } - } - if (dialoguePanel != null && dialoguePanel.activeSelf) - { - GUI.color = Color.white; - GUI.Box(new Rect(Screen.width - 450, 70, 430, 120), "늙은 문지기 '발두르'의 조언 (Debug)"); - - GUIStyle dialogueStyle = new GUIStyle(GUI.skin.label); - dialogueStyle.wordWrap = true; - dialogueStyle.fontSize = 14; - - GUI.Label(new Rect(Screen.width - 440, 95, 410, 90), lastDialogueText, dialogueStyle); - } - } } diff --git a/unity-client/Assets/Scripts/Player.cs b/unity-client/Assets/Scripts/Player.cs index e7ebd64..e49ed73 100644 --- a/unity-client/Assets/Scripts/Player.cs +++ b/unity-client/Assets/Scripts/Player.cs @@ -217,56 +217,7 @@ public class Player : MonoBehaviour } } - // 인스펙터 우클릭 메뉴에서 데미지를 테스트할 수 있는 기능 추가 - [ContextMenu("Debug/Take 5 Damage")] - public void DebugTake5Damage() - { - TakeDamage(5, "인스펙터 디버그 공격"); - } - [ContextMenu("Debug/Restore HP")] - public void DebugRestoreHP() - { - hp = maxHp; - if (animator != null) - { - animator.Rebind(); - animator.Update(0f); - } - Debug.Log($"플레이어 체력이 {hp}로 회복되었습니다."); - - // 체력 복구 시 다음 캐릭터 이름 및 세대 정보 갱신 - StartCoroutine(GetNextGenerationFromServer()); - } - - // 임시 디버그용 화면 버튼 (게임 실행 시 화면 좌측 상단에 뜸) - private void OnGUI() - { - GUI.backgroundColor = Color.red; - if (GUI.Button(new Rect(10, 10, 180, 50), "Debug: Take 5 Damage (Trap)")) - { - TakeDamage(5, "테스트 함정"); - } - - GUI.backgroundColor = Color.blue; - // 기존 겹쳐있던 위치(10, 10)를 피해 y 좌표를 130으로 내렸습니다. - if (GUI.Button(new Rect(10, 130, 180, 50), "Debug: Take 3 Damage (Monster)")) - { - TakeDamage(3, "테스트 몬스터"); - } - - GUI.backgroundColor = Color.green; - if (GUI.Button(new Rect(10, 70, 180, 50), "Debug: Restore HP")) - { - DebugRestoreHP(); - } - - // 캐릭터 정보 UI 노출 - GUI.color = Color.white; - GUI.skin.label.fontSize = 16; - GUI.Label(new Rect(10, 200, 400, 30), $"이름: {characterName}"); - GUI.Label(new Rect(10, 230, 400, 30), $"세대: {generation}대손"); - } // 백엔드로부터 다음 세대 번호를 받아와 랜덤 이름과 매핑하는 코루틴 private System.Collections.IEnumerator GetNextGenerationFromServer() @@ -343,9 +294,22 @@ public class Player : MonoBehaviour else { Debug.Log("사망 기록 전송 성공: " + request.downloadHandler.text); - // 사망 전송 성공 즉시 다음 세대 정보 받아와 자동 갱신 - StartCoroutine(GetNextGenerationFromServer()); } + + // 1. 싱글톤 GameManager의 이전 캐릭터 정보 데이터 초기화 (신규 세대 생성 유도) + if (GameManager.Instance != null) + { + GameManager.Instance.ClearPlayerData(); + } + + // 2. 플레이어 사망 연출(2초 누워있기) 대기 후 로비 씬으로 씬 전환 실행 + yield return new WaitForSeconds(2.0f); + Debug.Log("[Death Report] 로비 씬(Lobby)으로 되돌아갑니다."); + + // 사망 연출이 종료되었으므로 플레이어 게임 오브젝트를 씬에서 완전히 파괴합니다. + Destroy(gameObject); + + UnityEngine.SceneManagement.SceneManager.LoadScene("Lobby"); } } }