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