diff --git a/Assets/0.SCENE/MainGame.unity b/Assets/0.SCENE/MainGame.unity index c4a83406..db198210 100644 --- a/Assets/0.SCENE/MainGame.unity +++ b/Assets/0.SCENE/MainGame.unity @@ -162648,103 +162648,6 @@ Transform: m_CorrespondingSourceObject: {fileID: 4946034908522688, guid: 0b4ec2079abd9a64390cf77971445fc5, type: 3} m_PrefabInstance: {fileID: 1531559788} m_PrefabAsset: {fileID: 0} ---- !u!1001 &1532158138 -PrefabInstance: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_Modification: - serializedVersion: 3 - m_TransformParent: {fileID: 0} - m_Modifications: - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalScale.x - value: 218.43205 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalScale.y - value: 222.09297 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalScale.z - value: 227.48624 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalPosition.x - value: 24.215 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalPosition.y - value: 10.136 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalPosition.z - value: 13.717 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalRotation.w - value: 0.12382896 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalRotation.x - value: 0.5433104 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalRotation.y - value: -0.066823 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalRotation.z - value: 0.82765627 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalEulerAnglesHint.x - value: 14.192 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalEulerAnglesHint.y - value: 65.587 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalEulerAnglesHint.z - value: 172.153 - objectReference: {fileID: 0} - - target: {fileID: 2669107996035270001, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_ConstrainProportionsScale - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 4085536598674672635, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_Size.x - value: 0.003 - objectReference: {fileID: 0} - - target: {fileID: 4085536598674672635, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_Size.y - value: 0.008 - objectReference: {fileID: 0} - - target: {fileID: 4906676340306482370, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: config - value: - objectReference: {fileID: 11400000, guid: 602c0bb77ce70104ab6768b08772132f, type: 2} - - target: {fileID: 5253520193507450777, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_Layer - value: 8 - objectReference: {fileID: 0} - - target: {fileID: 6875888761843048781, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_Enabled - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 8071134912250732547, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_Name - value: "\uCE7C (5)" - objectReference: {fileID: 0} - - target: {fileID: 8071134912250732547, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_Layer - value: 8 - objectReference: {fileID: 0} - m_RemovedComponents: [] - m_RemovedGameObjects: [] - m_AddedGameObjects: [] - m_AddedComponents: [] - m_SourcePrefab: {fileID: 100100000, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} --- !u!1001 &1532898197 PrefabInstance: m_ObjectHideFlags: 0 @@ -203177,7 +203080,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!114 &1927423249 MonoBehaviour: m_ObjectHideFlags: 0 @@ -203975,17 +203878,6 @@ Transform: m_CorrespondingSourceObject: {fileID: 4899585634617078, guid: 9b42f9d14b52bd840afbef0e34f754f2, type: 3} m_PrefabInstance: {fileID: 1938154977} m_PrefabAsset: {fileID: 0} ---- !u!114 &1938848879 stripped -MonoBehaviour: - m_CorrespondingSourceObject: {fileID: 124746496204996812, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - m_PrefabInstance: {fileID: 7969472841528762147} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: bcf8987df4d20a442a8ae5028c602e03, type: 3} - m_Name: - m_EditorClassIdentifier: --- !u!1001 &1940581791 PrefabInstance: m_ObjectHideFlags: 0 @@ -226661,6 +226553,75 @@ GameObject: m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 +--- !u!1001 &1175521096951328089 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 529370269987782371, guid: 7af7365e5854aed458abd798049cc5b2, type: 3} + propertyPath: m_LocalScale.x + value: 0.23480867 + objectReference: {fileID: 0} + - target: {fileID: 529370269987782371, guid: 7af7365e5854aed458abd798049cc5b2, type: 3} + propertyPath: m_LocalScale.y + value: 0.20066422 + objectReference: {fileID: 0} + - target: {fileID: 529370269987782371, guid: 7af7365e5854aed458abd798049cc5b2, type: 3} + propertyPath: m_LocalScale.z + value: 3.2097 + objectReference: {fileID: 0} + - target: {fileID: 529370269987782371, guid: 7af7365e5854aed458abd798049cc5b2, type: 3} + propertyPath: m_LocalPosition.x + value: 38 + objectReference: {fileID: 0} + - target: {fileID: 529370269987782371, guid: 7af7365e5854aed458abd798049cc5b2, type: 3} + propertyPath: m_LocalPosition.y + value: 7.99 + objectReference: {fileID: 0} + - target: {fileID: 529370269987782371, guid: 7af7365e5854aed458abd798049cc5b2, type: 3} + propertyPath: m_LocalPosition.z + value: 41 + objectReference: {fileID: 0} + - target: {fileID: 529370269987782371, guid: 7af7365e5854aed458abd798049cc5b2, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 529370269987782371, guid: 7af7365e5854aed458abd798049cc5b2, type: 3} + propertyPath: m_LocalRotation.x + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 529370269987782371, guid: 7af7365e5854aed458abd798049cc5b2, type: 3} + propertyPath: m_LocalRotation.y + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 529370269987782371, guid: 7af7365e5854aed458abd798049cc5b2, type: 3} + propertyPath: m_LocalRotation.z + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 529370269987782371, guid: 7af7365e5854aed458abd798049cc5b2, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 529370269987782371, guid: 7af7365e5854aed458abd798049cc5b2, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 529370269987782371, guid: 7af7365e5854aed458abd798049cc5b2, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 2943732763553649162, guid: 7af7365e5854aed458abd798049cc5b2, type: 3} + propertyPath: m_Name + value: Arrow Test + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: 7af7365e5854aed458abd798049cc5b2, type: 3} --- !u!114 &1189169361667733870 MonoBehaviour: m_ObjectHideFlags: 0 @@ -227318,6 +227279,18 @@ PrefabInstance: propertyPath: m_Avatar value: objectReference: {fileID: 9000000, guid: 76cee5628aa6b874c96342f004fa138b, type: 3} + - target: {fileID: 7686598050579119226, guid: c34da37720b95c84887eda34e2d90e5b, type: 3} + propertyPath: lineWidth + value: 0.6 + objectReference: {fileID: 0} + - target: {fileID: 7686598050579119226, guid: c34da37720b95c84887eda34e2d90e5b, type: 3} + propertyPath: maxLength + value: 3 + objectReference: {fileID: 0} + - target: {fileID: 7686598050579119226, guid: c34da37720b95c84887eda34e2d90e5b, type: 3} + propertyPath: minLength + value: 0.2 + objectReference: {fileID: 0} - target: {fileID: 8965661853020836870, guid: c34da37720b95c84887eda34e2d90e5b, type: 3} propertyPath: arrowPrefab value: @@ -227325,7 +227298,15 @@ PrefabInstance: - target: {fileID: 8965661853020836870, guid: c34da37720b95c84887eda34e2d90e5b, type: 3} propertyPath: weaponHitBox value: - objectReference: {fileID: 1938848879} + objectReference: {fileID: 0} + - target: {fileID: 8965661853020836870, guid: c34da37720b95c84887eda34e2d90e5b, type: 3} + propertyPath: aimAssistStrength + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 8965661853020836870, guid: c34da37720b95c84887eda34e2d90e5b, type: 3} + propertyPath: enemyLayer.m_Bits + value: 64 + objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] @@ -227772,83 +227753,6 @@ GameObject: m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!1001 &7969472841528762147 -PrefabInstance: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_Modification: - serializedVersion: 3 - m_TransformParent: {fileID: 0} - m_Modifications: - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalPosition.x - value: 20.274 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalPosition.y - value: 9.322 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalPosition.z - value: 13.741 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalRotation.w - value: 0.12382896 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalRotation.x - value: 0.5433104 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalRotation.y - value: -0.066823 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalRotation.z - value: 0.82765627 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalEulerAnglesHint.x - value: 14.192 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalEulerAnglesHint.y - value: 65.587 - objectReference: {fileID: 0} - - target: {fileID: 450992007138140667, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_LocalEulerAnglesHint.z - value: 172.153 - objectReference: {fileID: 0} - - target: {fileID: 4085536598674672635, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_Size.x - value: 0.003 - objectReference: {fileID: 0} - - target: {fileID: 4085536598674672635, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_Size.y - value: 0.008 - objectReference: {fileID: 0} - - target: {fileID: 5253520193507450777, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_Layer - value: 8 - objectReference: {fileID: 0} - - target: {fileID: 6875888761843048781, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_Enabled - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 8071134912250732547, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_Name - value: "\uCE7C (4)" - objectReference: {fileID: 0} - - target: {fileID: 8071134912250732547, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} - propertyPath: m_Layer - value: 8 - objectReference: {fileID: 0} - m_RemovedComponents: [] - m_RemovedGameObjects: [] - m_AddedGameObjects: [] - m_AddedComponents: [] - m_SourcePrefab: {fileID: 100100000, guid: 9f51c4433e5c81644807e9e547b7826c, type: 3} --- !u!222 &8011247558027849043 CanvasRenderer: m_ObjectHideFlags: 0 @@ -228007,8 +227911,6 @@ SceneRoots: - {fileID: 4755848957906863847} - {fileID: 398512784} - {fileID: 1390519481} - - {fileID: 7969472841528762147} - - {fileID: 1532158138} - {fileID: 1992891316} - {fileID: 2112919309} - {fileID: 2119519052} @@ -228020,6 +227922,7 @@ SceneRoots: - {fileID: 1824697940} - {fileID: 216801511} - {fileID: 85056390} + - {fileID: 1175521096951328089} - {fileID: 600231664} - {fileID: 1927423250} - {fileID: 2067270637} diff --git a/Assets/1.myPrefab/Arrow Test.prefab b/Assets/1.myPrefab/Arrow Test.prefab new file mode 100644 index 00000000..f5815f63 --- /dev/null +++ b/Assets/1.myPrefab/Arrow Test.prefab @@ -0,0 +1,155 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &2943732763553649162 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 529370269987782371} + - component: {fileID: 5228667605444404581} + - component: {fileID: 4979562685888428679} + - component: {fileID: 8230402311320924260} + - component: {fileID: 3429443446101725902} + - component: {fileID: -1087238979925095596} + m_Layer: 8 + m_Name: Arrow Test + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &529370269987782371 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2943732763553649162} + serializedVersion: 2 + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 38, y: 7.99, z: 41} + m_LocalScale: {x: 0.073155954, y: 0.06251806, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &5228667605444404581 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2943732763553649162} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &4979562685888428679 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2943732763553649162} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!65 &8230402311320924260 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2943732763553649162} + 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_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!54 &3429443446101725902 +Rigidbody: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2943732763553649162} + serializedVersion: 4 + m_Mass: 1 + m_Drag: 0 + m_AngularDrag: 0.05 + m_CenterOfMass: {x: 0, y: 0, z: 0} + m_InertiaTensor: {x: 1, y: 1, z: 1} + m_InertiaRotation: {x: 0, y: 0, z: 0, w: 1} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ImplicitCom: 1 + m_ImplicitTensor: 1 + m_UseGravity: 1 + m_IsKinematic: 0 + m_Interpolate: 0 + m_Constraints: 0 + m_CollisionDetection: 0 +--- !u!114 &-1087238979925095596 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2943732763553649162} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1c61ccbf2fc5f2144872ea56d89cb755, type: 3} + m_Name: + m_EditorClassIdentifier: + arrowName: "\uAE30\uBCF8 \uD654\uC0B4" + damage: 15 + speed: 20 + range: 15 + pickupUI: {fileID: 0} + uiDisplayRange: 3 + visualModel: {fileID: 2943732763553649162} diff --git a/Assets/1.myPrefab/Arrow Test.prefab.meta b/Assets/1.myPrefab/Arrow Test.prefab.meta new file mode 100644 index 00000000..2804f6d6 --- /dev/null +++ b/Assets/1.myPrefab/Arrow Test.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7af7365e5854aed458abd798049cc5b2 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/1.myPrefab/Arrow.prefab b/Assets/1.myPrefab/Arrow.prefab index ecc77cd8..b6e910db 100644 --- a/Assets/1.myPrefab/Arrow.prefab +++ b/Assets/1.myPrefab/Arrow.prefab @@ -56,37 +56,32 @@ PrefabInstance: propertyPath: m_Name value: Arrow objectReference: {fileID: 0} + - target: {fileID: 919132149155446097, guid: 6ecc17433e8741d4c990408160a2a534, type: 3} + propertyPath: m_Layer + value: 8 + objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] m_AddedComponents: - - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 6ecc17433e8741d4c990408160a2a534, type: 3} - insertIndex: -1 - addedObject: {fileID: -8985903288884462599} - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 6ecc17433e8741d4c990408160a2a534, type: 3} insertIndex: -1 addedObject: {fileID: -3399849508453939123} - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 6ecc17433e8741d4c990408160a2a534, type: 3} insertIndex: -1 addedObject: {fileID: -2262200229160577635} + - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 6ecc17433e8741d4c990408160a2a534, type: 3} + insertIndex: -1 + addedObject: {fileID: 8027594905793114800} + - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 6ecc17433e8741d4c990408160a2a534, type: 3} + insertIndex: -1 + addedObject: {fileID: -3219543398048858031} m_SourcePrefab: {fileID: 100100000, guid: 6ecc17433e8741d4c990408160a2a534, type: 3} --- !u!1 &791703799912573729 stripped GameObject: m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: 6ecc17433e8741d4c990408160a2a534, type: 3} m_PrefabInstance: {fileID: 449757124165146224} m_PrefabAsset: {fileID: 0} ---- !u!114 &-8985903288884462599 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 791703799912573729} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 473d386fc9b5d9c49aac6669d6973f71, type: 3} - m_Name: - m_EditorClassIdentifier: --- !u!65 &-3399849508453939123 BoxCollider: m_ObjectHideFlags: 0 @@ -135,3 +130,43 @@ Rigidbody: m_Interpolate: 0 m_Constraints: 0 m_CollisionDetection: 0 +--- !u!135 &8027594905793114800 +SphereCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 791703799912573729} + 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: 2.9 + m_Center: {x: -0.0006635487, y: -0.00016829367, z: 0.00038632748} +--- !u!114 &-3219543398048858031 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 791703799912573729} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1c61ccbf2fc5f2144872ea56d89cb755, type: 3} + m_Name: + m_EditorClassIdentifier: + arrowName: "\uC880\uB354 \uC388 \uD654\uC0B4" + damage: 15 + speed: 20 + range: 15 + pickupUI: {fileID: 0} + uiDisplayRange: 3 + visualModel: {fileID: 791703799912573729} diff --git a/Assets/1.myPrefab/MyMonster/RushMonster.prefab b/Assets/1.myPrefab/MyMonster/RushMonster.prefab index 08b654b6..6e30707e 100644 --- a/Assets/1.myPrefab/MyMonster/RushMonster.prefab +++ b/Assets/1.myPrefab/MyMonster/RushMonster.prefab @@ -927,6 +927,9 @@ MonoBehaviour: chargeDuration: 2 chargeDelay: 3 prepareTime: 0.5 + dropItemPrefabs: + - {fileID: 791703799912573729, guid: e9867839af14eb14ca3d49ee41fc5390, type: 3} + dropChance: 100 chargeAnimation: Monster_Charge prepareAnimation: Monster_ChargePrepare Monster_Walk: Monster_Walk diff --git a/Assets/1.myPrefab/MyMonster/RushMonster2.prefab b/Assets/1.myPrefab/MyMonster/RushMonster2.prefab index ee09d124..79754797 100644 --- a/Assets/1.myPrefab/MyMonster/RushMonster2.prefab +++ b/Assets/1.myPrefab/MyMonster/RushMonster2.prefab @@ -364,6 +364,9 @@ MonoBehaviour: chargeDuration: 2 chargeDelay: 3 prepareTime: 3 + dropItemPrefabs: + - {fileID: 791703799912573729, guid: e9867839af14eb14ca3d49ee41fc5390, type: 3} + dropChance: 100 chargeAnimation: Run-run prepareAnimation: Run-wait Monster_Walk: Run-walk diff --git a/Assets/1.myPrefab/MyMonster/SwordMonster.prefab b/Assets/1.myPrefab/MyMonster/SwordMonster.prefab index 6c9564c6..1f07f9da 100644 --- a/Assets/1.myPrefab/MyMonster/SwordMonster.prefab +++ b/Assets/1.myPrefab/MyMonster/SwordMonster.prefab @@ -1524,6 +1524,11 @@ MonoBehaviour: impactSpawnPoint: {fileID: 0} attackRange: 2 attackDelay: 1.5 + dropItemPrefabs: + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + dropChance: 30 attackAnimations: - ghoul_attack Monster_Walk: ghoul_walk diff --git a/Assets/1.myPrefab/Player.prefab b/Assets/1.myPrefab/Player.prefab index ddfc3712..f6506d74 100644 --- a/Assets/1.myPrefab/Player.prefab +++ b/Assets/1.myPrefab/Player.prefab @@ -110,13 +110,13 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 3835737397246117387} serializedVersion: 2 - m_LocalRotation: {x: 0.7027862, y: 0.23967019, z: -0.29418004, w: -0.60175407} - m_LocalPosition: {x: -0.00007, y: 0.0012, z: 0.00026} - m_LocalScale: {x: 0.00999999, y: 0.009999995, z: 0.010000003} + m_LocalRotation: {x: -0.119923264, y: 0.000000029802322, z: 0.000000044470653, w: 0.9927832} + m_LocalPosition: {x: -0.00024, y: -0.00444, z: 0.00469} + m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 642015492957721826} - m_LocalEulerAnglesHint: {x: -44.813, y: 261.676, z: 103.109} + m_LocalEulerAnglesHint: {x: -13.775, y: 0, z: 0} --- !u!1 &4977077540650227567 GameObject: m_ObjectHideFlags: 0 @@ -276,11 +276,10 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: attackScript: {fileID: 8965661853020836870} - interaction: {fileID: 8385686067015665091} - radius: 5 - segments: 20 - fanColor: {r: 1, g: 0.9, b: 0, a: 0.4} - minAngle: 2 + uiColor: {r: 1, g: 1, b: 0, a: 0.5} + lineWidth: 1 + minLength: 5 + maxLength: 20 --- !u!1001 &1112926104530361804 PrefabInstance: m_ObjectHideFlags: 0 @@ -1338,13 +1337,13 @@ MonoBehaviour: chargeStages: - chargeTime: 1 damageMult: 1.5 - rangeMult: 1.2 + rangeMult: 1.1 - chargeTime: 2 damageMult: 2 - rangeMult: 1.5 + rangeMult: 1.2 - chargeTime: 3 damageMult: 2.5 - rangeMult: 2 + rangeMult: 1.5 --- !u!114 &8160405634931995834 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/Assets/Player Character/Main character/Celycia/Meshes/root_Fire.anim b/Assets/Player Character/Main character/Celycia/Meshes/root_Fire.anim index 3232c48a..8c788166 100644 --- a/Assets/Player Character/Main character/Celycia/Meshes/root_Fire.anim +++ b/Assets/Player Character/Main character/Celycia/Meshes/root_Fire.anim @@ -32414,7 +32414,7 @@ AnimationClip: m_AdditiveReferencePoseClip: {fileID: 0} m_AdditiveReferencePoseTime: 0 m_StartTime: 0 - m_StopTime: 0.15 + m_StopTime: 0.116666675 m_OrientationOffsetY: 0 m_Level: 0 m_CycleOffset: 0 @@ -127013,7 +127013,7 @@ AnimationClip: floatParameter: 0 intParameter: 0 messageOptions: 0 - - time: 0.15 + - time: 0.11666667 functionName: OnAttackEnd data: objectReferenceParameter: {fileID: 0} diff --git a/Assets/Scripts/Enemy/AI/ChargeMonster.cs b/Assets/Scripts/Enemy/AI/ChargeMonster.cs index 9a322f76..d4a32f69 100644 --- a/Assets/Scripts/Enemy/AI/ChargeMonster.cs +++ b/Assets/Scripts/Enemy/AI/ChargeMonster.cs @@ -1,19 +1,26 @@ using UnityEngine; using UnityEngine.AI; using System.Collections; +using System.Collections.Generic; // ✅ 리스트 사용 필수 /// -/// 돌진 공격 몬스터 (두 번째 돌진 고장 수정판) -/// - Agent On/Off 타이밍 완벽하게 정리 +/// 돌진 공격 몬스터 /// public class ChargeMonster : MonsterClass { [Header("=== 돌진 공격 설정 ===")] - [SerializeField] private float chargeSpeed = 15f; // 돌진 속도 - [SerializeField] private float chargeRange = 10f; // 돌진 시작 거리 - [SerializeField] private float chargeDuration = 2f; // 돌진 지속 시간 - [SerializeField] private float chargeDelay = 3f; // 돌진 쿨타임 - [SerializeField] private float prepareTime = 0.5f; // 돌진 준비 시간 + [SerializeField] private float chargeSpeed = 15f; + [SerializeField] private float chargeRange = 10f; + [SerializeField] private float chargeDuration = 2f; + [SerializeField] private float chargeDelay = 3f; + [SerializeField] private float prepareTime = 0.5f; + + // 🎁 [추가] 드랍 아이템 리스트 + [Header("=== 드랍 아이템 설정 ===")] + [Tooltip("드랍 가능한 아이템 리스트 (랜덤 1개)")] + [SerializeField] private List dropItemPrefabs; + [Tooltip("아이템이 나올 확률 (0 ~ 100%)")] + [Range(0, 100)][SerializeField] private float dropChance = 30f; private float lastChargeTime; private bool isCharging = false; @@ -67,17 +74,14 @@ public class ChargeMonster : MonsterClass void HandleChargeCombat(float distance) { - // 쿨타임 체크 & 사거리 체크 if (distance <= chargeRange && Time.time >= lastChargeTime + chargeDelay) { StartCoroutine(PrepareCharge()); } - // 추적 모드 else if (!isCharging && !isPreparing) { if (agent.isOnNavMesh) { - // ⭐ [수정] 추적 시작할 때 "나 멈춰있니?" 확인하고 풀어주기 if (agent.isStopped) agent.isStopped = false; agent.SetDestination(playerTransform.position); } @@ -87,8 +91,6 @@ public class ChargeMonster : MonsterClass IEnumerator PrepareCharge() { isPreparing = true; - - // 이동 완전 정지 if (agent.isOnNavMesh) { agent.isStopped = true; @@ -96,12 +98,10 @@ public class ChargeMonster : MonsterClass agent.velocity = Vector3.zero; } - // 방향 설정 chargeDirection = (playerTransform.position - transform.position).normalized; chargeDirection.y = 0; if (chargeDirection != Vector3.zero) transform.rotation = Quaternion.LookRotation(chargeDirection); - // 준비 애니메이션 if (!string.IsNullOrEmpty(prepareAnimation)) animator.Play(prepareAnimation, 0, 0f); Debug.Log("[ChargeMonster] 돌진 준비..."); @@ -116,10 +116,7 @@ public class ChargeMonster : MonsterClass isCharging = true; lastChargeTime = Time.time; - // ⭐ [핵심 수정] 조건 없이 강제로 끄기! (NavMesh 위에 있든 말든 일단 꺼야 물리 이동 가능) if (agent != null) agent.enabled = false; - - // 물리 켜기 if (_rigidbody != null) _rigidbody.isKinematic = false; animator.Play(chargeAnimation, 0, 0f); @@ -129,30 +126,22 @@ public class ChargeMonster : MonsterClass while (Time.time < chargeStartTime + chargeDuration) { - // 돌진 중에도 방향을 잃지 않도록 if (_rigidbody != null) - { _rigidbody.velocity = chargeDirection * chargeSpeed; - } else - { transform.position += chargeDirection * chargeSpeed * Time.deltaTime; - } yield return null; } - // 돌진 끝 정리 if (_rigidbody != null) { _rigidbody.velocity = Vector3.zero; _rigidbody.isKinematic = true; } - // Agent 다시 켜기 if (agent != null) { agent.enabled = true; - // 켜지자마자 미끄러짐 방지 agent.ResetPath(); agent.velocity = Vector3.zero; } @@ -164,8 +153,6 @@ public class ChargeMonster : MonsterClass void UpdateMovementAnimation() { if (isCharging || isPreparing || isHit || isResting) return; - - // Agent가 켜져 있고 움직일 때만 걷기 모션 if (agent.enabled && agent.velocity.magnitude > 0.1f) animator.Play(Monster_Walk); else @@ -175,7 +162,6 @@ public class ChargeMonster : MonsterClass void Patrol() { if (Time.time < nextPatrolTime) return; - Vector3 randomPoint = transform.position + new Vector3( Random.Range(-patrolRadius, patrolRadius), 0, @@ -191,15 +177,30 @@ public class ChargeMonster : MonsterClass private void OnCollisionEnter(Collision collision) { if (!isCharging) return; - if (collision.gameObject.CompareTag("Player")) { if (collision.gameObject.TryGetComponent(out var playerHealth)) { if (!playerHealth.isInvincible) - { playerHealth.TakeDamage(attackDamage); - Debug.Log($"[ChargeMonster] 쾅! 데미지: {attackDamage}"); + } + } + } + + // ☠️ [추가] 죽을 때 아이템 드랍 + protected override void OnDie() + { + if (_rigidbody != null) _rigidbody.velocity = Vector3.zero; + + if (dropItemPrefabs != null && dropItemPrefabs.Count > 0) + { + float randomValue = Random.Range(0f, 100f); + if (randomValue <= dropChance) + { + int randomIndex = Random.Range(0, dropItemPrefabs.Count); + if (dropItemPrefabs[randomIndex] != null) + { + Instantiate(dropItemPrefabs[randomIndex], transform.position + Vector3.up * 0.5f, Quaternion.identity); } } } diff --git a/Assets/Scripts/Enemy/AI/NormalMonster.cs b/Assets/Scripts/Enemy/AI/NormalMonster.cs index a540c3d9..78af6565 100644 --- a/Assets/Scripts/Enemy/AI/NormalMonster.cs +++ b/Assets/Scripts/Enemy/AI/NormalMonster.cs @@ -1,17 +1,23 @@ using UnityEngine; using UnityEngine.AI; -using System.Collections; // IEnumerator 사용을 위해 추가 +using System.Collections; +using System.Collections.Generic; // ✅ 리스트 사용을 위해 필수 추가 -/// -/// 근접 공격 몬스터 (칼, 도끼 등) -/// public class MeleeMonster : MonsterClass { [Header("=== 근접 공격 설정 ===")] - // [SerializeField] private MonsterWeapon myWeapon; + //[SerializeField] private MonsterWeapon myWeapon; // ✅ 주석 해제됨 (이제 무기 연결 가능!) [SerializeField] private float attackRange = 2f; [SerializeField] private float attackDelay = 1.5f; + // 🎁 [수정] 단일 아이템 -> 리스트로 변경 + [Header("=== 드랍 아이템 설정 ===")] + [Tooltip("드랍 가능한 아이템들을 여기에 여러 개 등록하세요. (랜덤 1개 드랍)")] + [SerializeField] private List dropItemPrefabs; + + [Tooltip("아이템이 나올 확률 (0 ~ 100%)")] + [Range(0, 100)][SerializeField] private float dropChance = 30f; // 기본 30% + private float lastAttackTime; [Header("공격 / 이동 애니메이션")] @@ -29,10 +35,6 @@ public class MeleeMonster : MonsterClass private int attackIndex; private bool isPlayerInZone; - // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - // 초기화 - // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - protected override void Init() { if (agent != null) agent.stoppingDistance = attackRange - 0.4f; @@ -41,17 +43,12 @@ public class MeleeMonster : MonsterClass protected override void OnResetStats() { - // 무기에 데미지 설정 if (myWeapon != null) { myWeapon.SetDamage(attackDamage); } } - // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - // AI 로직 - // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - protected override void ExecuteAILogic() { if (isHit || isAttacking || isResting) return; @@ -124,14 +121,8 @@ public class MeleeMonster : MonsterClass nextPatrolTime = Time.time + patrolInterval; } - // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - // 공격 이벤트 (애니메이션에서 호출) - // ⭐ [핵심 수정] override 추가! - // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - public override void OnAttackStart() { - // base.OnAttackStart(); // 부모 기능도 쓰고 싶으면 주석 해제 isAttacking = true; isResting = false; if (myWeapon != null) myWeapon.EnableHitBox(); @@ -144,7 +135,6 @@ public class MeleeMonster : MonsterClass if (!isDead && !isHit) StartCoroutine(RestAfterAttack()); } - // ⭐ [핵심 수정] override 및 protected 추가! protected override IEnumerator RestAfterAttack() { isResting = true; @@ -152,23 +142,36 @@ public class MeleeMonster : MonsterClass isResting = false; } - // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - // 피격 / 사망 시 무기 끄기 - // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - protected override void OnStartHit() { if (myWeapon != null) myWeapon.DisableHitBox(); } + // 🎲 [핵심 수정] 리스트에서 랜덤 뽑기 + 확률 체크 protected override void OnDie() { if (myWeapon != null) myWeapon.DisableHitBox(); - } - // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - // Trigger 감지 (플레이어 인식 영역) - // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + // 1. 리스트에 아이템이 하나라도 있는지 확인 + if (dropItemPrefabs != null && dropItemPrefabs.Count > 0) + { + // 2. 확률 체크 (0 ~ 100) + float randomValue = Random.Range(0f, 100f); + + if (randomValue <= dropChance) // 당첨! + { + // 3. 리스트에서 랜덤하게 하나 뽑기 (0번 ~ 마지막 번호 중 하나) + int randomIndex = Random.Range(0, dropItemPrefabs.Count); + GameObject selectedItem = dropItemPrefabs[randomIndex]; + + if (selectedItem != null) + { + Instantiate(selectedItem, transform.position + Vector3.up * 0.5f, Quaternion.identity); + // Debug.Log($"🎉 아이템 드랍! ({selectedItem.name})"); + } + } + } + } private void OnTriggerEnter(Collider other) { diff --git a/Assets/Scripts/Player/Combat/Attack.cs b/Assets/Scripts/Player/Combat/Attack.cs index 7e3dd888..78036e51 100644 --- a/Assets/Scripts/Player/Combat/Attack.cs +++ b/Assets/Scripts/Player/Combat/Attack.cs @@ -28,18 +28,30 @@ public class PlayerAttack : MonoBehaviour [SerializeField] private List chargeStages; + [Header("--- 🎯 에임 보정 설정 ---")] + [SerializeField] private bool enableAutoAim = true; // 자동 조준 켜기/끄기 + [SerializeField] private float autoAimRange = 15f; // 자동 조준 감지 범위 + [SerializeField] private float autoAimAngle = 45f; // 마우스 커서 기준 각도 (넓을수록 감지 잘됨) + [Range(0f, 1f)] + [Tooltip("에임 보정 강도 (0: 보정 없음, 1: 완전 자동 조준)")] + [SerializeField] private float aimAssistStrength = 0.4f; // 40% 보정 (에임핵 느낌) + [SerializeField] private LayerMask enemyLayer; // 적 레이어 + [Tooltip("차징 최대 단계에서만 자동 조준 활성화")] + [SerializeField] private bool onlyMaxCharge = true; // 최대 차징에서만 작동 + private float _lastAttackTime; private float _chargeTimer; private bool _isCharging = false; private bool _isAttacking = false; - - // 재장전 잠금 장치 (한 발 쏘면 우클릭 뗄 때까지 발사 불가) private bool _waitForRelease = false; private float _pendingDamage; private float _pendingSpeed; private float _pendingRange; + // 🎯 발사 방향 저장 + private Vector3 _pendingShootDirection; + public bool IsCharging => _isCharging; public bool IsAttacking { @@ -59,6 +71,14 @@ public class PlayerAttack : MonoBehaviour new ChargeStage { chargeTime = 2f, damageMult = 2.5f, rangeMult = 1.5f } }; } + + float calculatedMaxTime = 0f; + foreach (var stage in chargeStages) + { + if (stage.chargeTime > calculatedMaxTime) + calculatedMaxTime = stage.chargeTime; + } + maxChargeTime = Mathf.Max(calculatedMaxTime, 0.1f); } private void Update() @@ -79,6 +99,9 @@ public class PlayerAttack : MonoBehaviour _pendingSpeed = normalSpeed; _pendingRange = normalRange; + // 🎯 마우스 방향 계산 (일반 공격은 자동 조준 없음) + _pendingShootDirection = GetMouseDirection(); + _lastAttackTime = Time.time; if (pAnim != null) pAnim.TriggerThrow(); @@ -89,7 +112,6 @@ public class PlayerAttack : MonoBehaviour // --- [2] 차징 시작 --- public void StartCharging() { - // 🔒 잠금 상태(방금 쏨)라면 차징 시작 안 함 (손 떼야 풀림) if (_waitForRelease) return; _isCharging = true; @@ -99,7 +121,6 @@ public class PlayerAttack : MonoBehaviour if (CinemachineShake.Instance != null) CinemachineShake.Instance.SetZoom(true); } - // 내부용: 효과 끄기 private void ResetChargingEffects() { _isCharging = false; @@ -109,14 +130,14 @@ public class PlayerAttack : MonoBehaviour if (CinemachineShake.Instance != null) CinemachineShake.Instance.SetZoom(false); } - // 외부 호출: 우클릭 뗐을 때 (여기서 잠금을 풉니다) + // --- [3] 차징 취소 --- public void CancelCharging() { ResetChargingEffects(); - _waitForRelease = false; // ✅ 잠금 해제! 다시 쏠 수 있음 + _waitForRelease = false; } - // --- [3] 차징 발사 --- + // --- [4] 차징 발사 --- public void ReleaseAttack() { if (!_isCharging) return; @@ -131,43 +152,143 @@ public class PlayerAttack : MonoBehaviour _pendingSpeed = normalSpeed * currentStage.rangeMult; _pendingRange = normalRange * currentStage.rangeMult; + // 🎯 발사 방향 계산 (차징 최대 시 자동 조준) + bool isMaxCharge = _chargeTimer >= maxChargeTime * 0.95f; // 95% 이상이면 최대 차징 + _pendingShootDirection = GetShootDirection(isMaxCharge); + if (pAnim != null) pAnim.TriggerThrow(); - // 🔒 발사했으므로 잠금! (우클릭 뗄 때까지 차징 불가) _waitForRelease = true; - _lastAttackTime = Time.time; StartCoroutine(AttackRoutine()); } - // --- [4] 이벤트: 화살 생성 --- + // --- [5] 🎯 마우스 방향 계산 --- + private Vector3 GetMouseDirection() + { + // 마우스 위치 → 월드 좌표 + Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); + Plane groundPlane = new Plane(Vector3.up, transform.position); + + if (groundPlane.Raycast(ray, out float distance)) + { + Vector3 worldMousePos = ray.GetPoint(distance); + Vector3 direction = (worldMousePos - firePoint.position).normalized; + direction.y = 0; // 수평 발사 + return direction; + } + + // 실패 시 플레이어 정면 + return transform.forward; + } + + // --- [6] 🎯 발사 방향 계산 (에임 어시스트 포함) --- + private Vector3 GetShootDirection(bool isMaxCharge) + { + Vector3 mouseDir = GetMouseDirection(); + + // 자동 조준 비활성화 또는 최대 차징 아님 + if (!enableAutoAim || (onlyMaxCharge && !isMaxCharge)) + { + return mouseDir; + } + + // 🎯 적 탐색 + Transform bestTarget = FindBestTarget(mouseDir); + + if (bestTarget != null) + { + // 적 방향 계산 (중심부 조준) + Vector3 targetPos = bestTarget.position + Vector3.up * 1.2f; + Vector3 targetDir = (targetPos - firePoint.position).normalized; + targetDir.y = 0; // 수평 발사 + + // ✨ 에임 어시스트: 마우스 방향과 적 방향을 섞음! + // aimAssistStrength = 0.4 → 마우스 60% + 적 40% + Vector3 assistedDir = Vector3.Lerp(mouseDir, targetDir, aimAssistStrength); + assistedDir.y = 0; + assistedDir.Normalize(); + + Debug.Log($"🎯 에임 어시스트 활성화! 타겟: {bestTarget.name}, 보정 강도: {aimAssistStrength * 100}%"); + return assistedDir; + } + + // 적 없으면 마우스 방향 + return mouseDir; + } + + // --- [7] 🎯 최적 타겟 찾기 --- + private Transform FindBestTarget(Vector3 mouseDirection) + { + Collider[] enemies = Physics.OverlapSphere(transform.position, autoAimRange, enemyLayer); + + if (enemies.Length == 0) return null; + + Transform bestTarget = null; + float bestScore = float.MaxValue; + + foreach (var enemy in enemies) + { + Vector3 dirToEnemy = (enemy.transform.position - transform.position).normalized; + + // 마우스 방향과의 각도 체크 + float angle = Vector3.Angle(mouseDirection, dirToEnemy); + if (angle > autoAimAngle) continue; // 각도 범위 밖 + + // 거리 체크 + float distance = Vector3.Distance(transform.position, enemy.transform.position); + + // 점수 계산: 각도 + 거리 (낮을수록 좋음) + float score = angle * 0.5f + distance * 0.5f; + + if (score < bestScore) + { + bestScore = score; + bestTarget = enemy.transform; + } + } + + return bestTarget; + } + + // --- [8] 이벤트: 화살 생성 --- public void OnShootArrow() { if (arrowPrefab == null || firePoint == null) return; - GameObject arrow = Instantiate(arrowPrefab, firePoint.position, transform.rotation); - PlayerArrow arrowScript = arrow.GetComponent(); + // 🎯 저장된 방향으로 회전 계산 + Quaternion shootRotation = Quaternion.LookRotation(_pendingShootDirection); + // 화살 생성 (계산된 방향으로) + GameObject arrow = Instantiate(arrowPrefab, firePoint.position, shootRotation); + + // ArrowItem 초기화 + ArrowItem arrowItem = arrow.GetComponent(); + if (arrowItem != null) + { + arrowItem.Initialize(_pendingDamage, _pendingSpeed, _pendingRange); + return; + } + + // 하위 호환 + PlayerArrow arrowScript = arrow.GetComponent(); if (arrowScript != null) { arrowScript.Initialize(_pendingDamage, _pendingSpeed, _pendingRange); } } - // --- [5] 이벤트: 공격 끝 (정상적인 경우) --- + // --- [9] 이벤트: 공격 끝 --- public void OnAttackEnd() { _isAttacking = false; ResetChargingEffects(); } - // --- [6] 안전장치 코루틴 --- + // --- [10] 안전장치 코루틴 --- private IEnumerator AttackRoutine() { _isAttacking = true; - - // 🚨 안전장치: 0.6초 뒤에는 무조건 공격 상태를 풉니다! - // (애니메이션 이벤트 OnAttackEnd가 씹혀도 멈추지 않게 함) yield return new WaitForSeconds(0.6f); if (_isAttacking) @@ -177,6 +298,59 @@ public class PlayerAttack : MonoBehaviour } } + // --- [11] 화살 교체 --- + public void SwapArrow(GameObject newArrow) + { + if (newArrow == null) return; + arrowPrefab = newArrow; + Debug.Log($"화살이 {newArrow.name}(으)로 교체되었습니다!"); + } + public void StartWeaponCollision() { } public void StopWeaponCollision() { } + + // --- [12] 🎯 디버그: 감지 범위 시각화 --- + private void OnDrawGizmosSelected() + { + if (!enableAutoAim) return; + + // 자동 조준 범위 (노란색 원) + Gizmos.color = Color.yellow; + Gizmos.DrawWireSphere(transform.position, autoAimRange); + + // 마우스 방향 (파란색 선) + if (Application.isPlaying && firePoint != null) + { + Vector3 mouseDir = GetMouseDirection(); + Gizmos.color = Color.blue; + Gizmos.DrawRay(firePoint.position, mouseDir * 5f); + + // 🎯 에임 어시스트 방향 (빨간색 선) + Transform target = FindBestTarget(mouseDir); + if (target != null) + { + Vector3 targetPos = target.position + Vector3.up * 1.2f; + Vector3 targetDir = (targetPos - firePoint.position).normalized; + targetDir.y = 0; + + // 보정된 최종 방향 + Vector3 assistedDir = Vector3.Lerp(mouseDir, targetDir, aimAssistStrength); + assistedDir.Normalize(); + + Gizmos.color = Color.red; + Gizmos.DrawRay(firePoint.position, assistedDir * 7f); + + // 타겟 위치 표시 + Gizmos.color = Color.green; + Gizmos.DrawWireSphere(targetPos, 0.3f); + } + + // 감지 각도 (연한 초록색 선) + Gizmos.color = new Color(0, 1, 0, 0.3f); + Vector3 leftBound = Quaternion.Euler(0, -autoAimAngle, 0) * mouseDir; + Vector3 rightBound = Quaternion.Euler(0, autoAimAngle, 0) * mouseDir; + Gizmos.DrawRay(firePoint.position, leftBound * autoAimRange); + Gizmos.DrawRay(firePoint.position, rightBound * autoAimRange); + } + } } \ No newline at end of file diff --git a/Assets/Scripts/Player/Controller/ArrowPickup.cs b/Assets/Scripts/Player/Controller/ArrowPickup.cs new file mode 100644 index 00000000..a8939f5f --- /dev/null +++ b/Assets/Scripts/Player/Controller/ArrowPickup.cs @@ -0,0 +1,213 @@ +using UnityEngine; + +/// +/// 바닥에 떨어진 화살 아이템 (발사체로도 사용 가능) +/// 모드 전환: 아이템 모드 ↔ 발사 모드 +/// +public class ArrowItem : MonoBehaviour +{ + [Header("--- 화살 정보 ---")] + [SerializeField] private string arrowName = "기본 화살"; + [SerializeField] private float damage = 15f; + [SerializeField] private float speed = 20f; + [SerializeField] private float range = 15f; + + [Header("--- UI 표시 (아이템 모드) ---")] + [SerializeField] private GameObject pickupUI; + [SerializeField] private float uiDisplayRange = 3f; + + [Header("--- 비주얼 ---")] + [SerializeField] private GameObject visualModel; // 화살 모델 + + private Transform playerTransform; + private Rigidbody rb; + private Collider col; + + // 모드 구분 + private bool isItemMode = true; // true: 아이템 모드, false: 발사 모드 + private Vector3 startPos; + private bool isFired = false; + + private void Awake() + { + rb = GetComponent(); + col = GetComponent(); + } + + private void Start() + { + if (isItemMode) + { + SetupAsItem(); + } + } + + private void Update() + { + if (isItemMode) + { + UpdateItemMode(); + } + else + { + UpdateProjectileMode(); + } + } + + #region 아이템 모드 + + private void SetupAsItem() + { + // 플레이어 찾기 + GameObject player = GameObject.FindGameObjectWithTag("Player"); + if (player != null) + { + playerTransform = player.transform; + } + + // UI 숨기기 + if (pickupUI != null) + { + pickupUI.SetActive(false); + } + + // 물리 설정 (바닥에 떨어진 아이템) + if (rb != null) + { + rb.useGravity = true; + rb.isKinematic = false; + } + + if (col != null) + { + col.isTrigger = true; + } + } + + private void UpdateItemMode() + { + if (playerTransform == null || pickupUI == null) return; + + // 플레이어와의 거리 체크 (UI 표시용) + float distance = Vector3.Distance(transform.position, playerTransform.position); + bool isNear = distance <= uiDisplayRange; + + pickupUI.SetActive(isNear); + } + + /// + /// PlayerInteraction에서 호출 + /// + public void Pickup(PlayerAttack playerAttack) + { + if (playerAttack == null) return; + + // 자기 자신을 복제해서 발사용 프리팹으로 제공 + GameObject arrowPrefab = gameObject; + playerAttack.SwapArrow(arrowPrefab); + + Debug.Log($"화살이 [{arrowName}](으)로 교체되었습니다!"); + + // 아이템 제거 + Destroy(gameObject); + } + + #endregion + + #region 발사 모드 + + /// + /// PlayerAttack에서 호출 (발사 초기화) + /// + public void Initialize(float dmg, float arrowSpeed, float maxRange) + { + Debug.Log($"🏹 화살 발사! 방향: {transform.forward}, 속도: {arrowSpeed}"); + + // 발사 모드로 전환 + isItemMode = false; + isFired = true; + + // 스탯 설정 + this.damage = dmg; + this.speed = arrowSpeed; + this.range = maxRange; + this.startPos = transform.position; + + // UI 숨기기 + if (pickupUI != null) + { + pickupUI.SetActive(false); + } + + // 물리 설정 (발사체) + if (rb != null) + { + rb.useGravity = false; + rb.isKinematic = false; + + // ✅ [중요] transform.forward 방향으로 발사 + // 화살이 Z축(파란 화살표) 방향을 앞으로 향하고 있어야 함! + Vector3 shootDirection = transform.forward; + rb.velocity = shootDirection * speed; + + Debug.Log($"📍 발사 방향: {shootDirection}, 속도 벡터: {rb.velocity}"); + } + + if (col != null) + { + col.isTrigger = true; + } + + // 5초 후 자동 삭제 + Destroy(gameObject, 5f); + } + + private void UpdateProjectileMode() + { + if (!isFired) return; + + // 최대 사거리 체크 + if (Vector3.Distance(startPos, transform.position) >= range) + { + Destroy(gameObject); + } + } + + private void OnTriggerEnter(Collider other) + { + // 아이템 모드에서는 충돌 무시 + if (isItemMode) return; + + // 발사 모드: 적 또는 벽 충돌 + if (other.CompareTag("Enemy")) + { + var monster = other.GetComponent(); + if (monster != null) + { + monster.TakeDamage(damage); + } + Destroy(gameObject); + } + else if (other.CompareTag("Wall") || other.CompareTag("Ground")) + { + Destroy(gameObject); + } + } + + #endregion + + #region 외부 설정용 + + /// + /// 몬스터 드롭 시 화살 정보 설정 + /// + public void SetArrowData(string name, float dmg, float spd, float rng) + { + arrowName = name; + damage = dmg; + speed = spd; + range = rng; + } + + #endregion +} \ No newline at end of file diff --git a/Assets/Scripts/Player/Controller/ArrowPickup.cs.meta b/Assets/Scripts/Player/Controller/ArrowPickup.cs.meta new file mode 100644 index 00000000..2e961b19 --- /dev/null +++ b/Assets/Scripts/Player/Controller/ArrowPickup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1c61ccbf2fc5f2144872ea56d89cb755 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Player/Interaction/PlayerInteraction.cs b/Assets/Scripts/Player/Interaction/PlayerInteraction.cs index 1d9ad838..3226b4b2 100644 --- a/Assets/Scripts/Player/Interaction/PlayerInteraction.cs +++ b/Assets/Scripts/Player/Interaction/PlayerInteraction.cs @@ -16,6 +16,14 @@ public class PlayerInteraction : MonoBehaviour Collider[] hits = Physics.OverlapSphere(transform.position, interactRange, itemLayer); foreach (var hit in hits) { + // 🏹 [새로 추가] 화살 아이템 습득 + if (hit.TryGetComponent(out var arrowItem)) + { + PickupArrow(arrowItem); + break; + } + + // 기존 무기 습득 if (hit.TryGetComponent(out var item)) { if (playerStats.Strength >= item.Config.RequiredStrength) @@ -25,11 +33,30 @@ public class PlayerInteraction : MonoBehaviour } else { CinemachineShake.Instance?.ShakeNoNo(); continue; } } + + // 기존 포션/제단 if (hit.TryGetComponent(out var potion)) { potion.Use(GetComponent()); break; } if (hit.TryGetComponent(out var altar)) { altar.Use(GetComponent()); break; } } } + // 🏹 [새 함수] 화살 습득 처리 + private void PickupArrow(ArrowItem arrowItem) + { + if (arrowItem == null) return; + + // PlayerAttack 찾아서 화살 교체 + PlayerAttack playerAttack = GetComponent(); + if (playerAttack != null) + { + arrowItem.Pickup(playerAttack); + } + else + { + Debug.LogWarning("PlayerAttack 컴포넌트를 찾을 수 없습니다!"); + } + } + private void EquipWeapon(EquippableItem item) { if (_currentWeapon != null) _currentWeapon.OnDropped(transform.forward); diff --git a/Assets/Scripts/UI/HUD/CrossHairUI.cs b/Assets/Scripts/UI/HUD/CrossHairUI.cs index 6c78b254..bcabf362 100644 --- a/Assets/Scripts/UI/HUD/CrossHairUI.cs +++ b/Assets/Scripts/UI/HUD/CrossHairUI.cs @@ -1,18 +1,23 @@ using UnityEngine; [RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))] -public class PureUnityFan : MonoBehaviour +public class ArrowRangeUI : MonoBehaviour { + // 🚨 수정됨: 끝부분의 \ 기호를 모두 삭제했습니다. [Header("--- 참조 ---")] - [SerializeField] private PlayerAttack attackScript; - [SerializeField] private PlayerInteraction interaction; + [SerializeField] private PlayerAttack attackScript; // PlayerAttack 스크립트 연결 - [Header("--- 부채꼴 설정 ---")] - [SerializeField] private float radius = 5f; - [SerializeField] private int segments = 40; - [SerializeField] private Color fanColor = new Color(1f, 0.9f, 0f, 0.4f); - [Tooltip("풀차징 시에도 유지할 최소 부채꼴 각도 (너무 얇으면 안 보일 수 있음)")] - [SerializeField] private float minAngle = 2f; // ⭐ [추가] 최소 두께 설정 + [Header("--- UI 설정 ---")] + [Tooltip("사거리 표시기의 색상")] + [SerializeField] private Color uiColor = new Color(1f, 1f, 0f, 0.5f); // 노란색 반투명 + [Tooltip("화살표 UI의 폭 (두께)")] + [SerializeField] private float lineWidth = 1.0f; + + [Header("--- 길이 설정 ---")] + [Tooltip("차징 0%일 때의 최소 길이 (기본 사거리)")] + [SerializeField] private float minLength = 5f; + [Tooltip("풀차징일 때의 최대 길이 (최대 사거리)")] + [SerializeField] private float maxLength = 20f; private Mesh _mesh; private MeshFilter _meshFilter; @@ -20,19 +25,24 @@ public class PureUnityFan : MonoBehaviour private void Awake() { + // 메쉬 초기화 _mesh = new Mesh(); _meshFilter = GetComponent(); _meshRenderer = GetComponent(); _meshFilter.mesh = _mesh; - _meshRenderer.material.color = fanColor; + + // 재질(Material)이 없다면 임시로 생성 + if (_meshRenderer.material == null) + { + _meshRenderer.material = new Material(Shader.Find("Sprites/Default")); + } + _meshRenderer.material.color = uiColor; } private void Update() { - // 1. 참조 확인 및 예외 처리 - if (attackScript == null || interaction == null) return; - - if (!attackScript.IsCharging || interaction.CurrentWeapon == null) + // 1. 공격 스크립트가 없거나 차징 중이 아니면 끄기 + if (attackScript == null || !attackScript.IsCharging) { _meshRenderer.enabled = false; return; @@ -40,58 +50,52 @@ public class PureUnityFan : MonoBehaviour _meshRenderer.enabled = true; - // 2. 점진적 보간(Lerp)을 통한 부드러운 정확도 계산 - float progress = attackScript.ChargeProgress; // 0.0 ~ 1.0 - float smoothSpread; + // 2. 차징 진행도(0.0 ~ 1.0) 가져오기 + float progress = attackScript.ChargeProgress; - var config = interaction.CurrentWeapon.Config; - float s1 = config.GetSpread(1); // 시작 정확도 - float s2 = config.GetSpread(2); // 중간 정확도 - float s3 = config.GetSpread(3); // 최종 정확도 (0) + // 3. 진행도에 따라 길이 계산 (Lerp로 부드럽게 늘어남) + float currentLength = Mathf.Lerp(minLength, maxLength, progress); - if (progress < 0.5f) - { - smoothSpread = Mathf.Lerp(s1, s2, progress * 2f); - } - else - { - smoothSpread = Mathf.Lerp(s2, s3, (progress - 0.5f) * 2f); - } - - // 3. ⭐ [핵심 수정] 계산된 각도가 설정한 최소 각도보다 작아지지 않도록 제한 - // (WeaponConfig에서 0을 반환하더라도, UI는 최소 minAngle만큼은 유지함) - float targetAngle = Mathf.Max(smoothSpread * 2f, minAngle); - - CreateFanMesh(targetAngle); + // 4. 직사각형 메쉬 그리기 + CreateRectangleMesh(currentLength, lineWidth); } - private void CreateFanMesh(float angle) + // 직사각형 메쉬 생성 함수 + private void CreateRectangleMesh(float length, float width) { - // 메쉬 생성 로직 (기존과 동일) - int vertexCount = segments + 2; - Vector3[] vertices = new Vector3[vertexCount]; - int[] triangles = new int[segments * 3]; + Vector3[] vertices = new Vector3[4]; + int[] triangles = new int[6]; + Vector2[] uvs = new Vector2[4]; - vertices[0] = Vector3.zero; - float halfAngle = angle / 2f; + float halfWidth = width / 2f; - for (int i = 0; i <= segments; i++) - { - float currAngle = Mathf.Lerp(-halfAngle, halfAngle, (float)i / segments); - float rad = currAngle * Mathf.Deg2Rad; - vertices[i + 1] = new Vector3(Mathf.Sin(rad), 0, Mathf.Cos(rad)) * radius; + // 정점 4개 정의 (플레이어 발밑 기준 앞으로 뻗어나감) + vertices[0] = new Vector3(-halfWidth, 0.1f, 0); + vertices[1] = new Vector3(halfWidth, 0.1f, 0); + vertices[2] = new Vector3(-halfWidth, 0.1f, length); + vertices[3] = new Vector3(halfWidth, 0.1f, length); - if (i < segments) - { - triangles[i * 3] = 0; - triangles[i * 3 + 1] = i + 1; - triangles[i * 3 + 2] = i + 2; - } - } + // 삼각형 연결 + triangles[0] = 0; + triangles[1] = 2; + triangles[2] = 1; + triangles[3] = 2; + triangles[4] = 3; + triangles[5] = 1; + + // UV 매핑 + uvs[0] = new Vector2(0, 0); + uvs[1] = new Vector2(1, 0); + uvs[2] = new Vector2(0, 1); + uvs[3] = new Vector2(1, 1); + + // 메쉬 적용 _mesh.Clear(); _mesh.vertices = vertices; _mesh.triangles = triangles; + _mesh.uv = uvs; _mesh.RecalculateNormals(); + _mesh.RecalculateBounds(); } } \ No newline at end of file