플레이어 공격 방식 변경 완
This commit is contained in:
parent
b06747778c
commit
4fbeb8d675
|
|
@ -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}
|
||||
|
|
|
|||
155
Assets/1.myPrefab/Arrow Test.prefab
Normal file
155
Assets/1.myPrefab/Arrow Test.prefab
Normal file
|
|
@ -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}
|
||||
7
Assets/1.myPrefab/Arrow Test.prefab.meta
Normal file
7
Assets/1.myPrefab/Arrow Test.prefab.meta
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7af7365e5854aed458abd798049cc5b2
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,26 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic; // ✅ 리스트 사용 필수
|
||||
|
||||
/// <summary>
|
||||
/// 돌진 공격 몬스터 (두 번째 돌진 고장 수정판)
|
||||
/// - Agent On/Off 타이밍 완벽하게 정리
|
||||
/// 돌진 공격 몬스터
|
||||
/// </summary>
|
||||
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<GameObject> 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<PlayerHealth>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,23 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using System.Collections; // IEnumerator 사용을 위해 추가
|
||||
using System.Collections;
|
||||
using System.Collections.Generic; // ✅ 리스트 사용을 위해 필수 추가
|
||||
|
||||
/// <summary>
|
||||
/// 근접 공격 몬스터 (칼, 도끼 등)
|
||||
/// </summary>
|
||||
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<GameObject> 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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -28,18 +28,30 @@ public class PlayerAttack : MonoBehaviour
|
|||
|
||||
[SerializeField] private List<ChargeStage> 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<PlayerArrow>();
|
||||
// 🎯 저장된 방향으로 회전 계산
|
||||
Quaternion shootRotation = Quaternion.LookRotation(_pendingShootDirection);
|
||||
|
||||
// 화살 생성 (계산된 방향으로)
|
||||
GameObject arrow = Instantiate(arrowPrefab, firePoint.position, shootRotation);
|
||||
|
||||
// ArrowItem 초기화
|
||||
ArrowItem arrowItem = arrow.GetComponent<ArrowItem>();
|
||||
if (arrowItem != null)
|
||||
{
|
||||
arrowItem.Initialize(_pendingDamage, _pendingSpeed, _pendingRange);
|
||||
return;
|
||||
}
|
||||
|
||||
// 하위 호환
|
||||
PlayerArrow arrowScript = arrow.GetComponent<PlayerArrow>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
213
Assets/Scripts/Player/Controller/ArrowPickup.cs
Normal file
213
Assets/Scripts/Player/Controller/ArrowPickup.cs
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 바닥에 떨어진 화살 아이템 (발사체로도 사용 가능)
|
||||
/// 모드 전환: 아이템 모드 ↔ 발사 모드
|
||||
/// </summary>
|
||||
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<Rigidbody>();
|
||||
col = GetComponent<Collider>();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PlayerInteraction에서 호출
|
||||
/// </summary>
|
||||
public void Pickup(PlayerAttack playerAttack)
|
||||
{
|
||||
if (playerAttack == null) return;
|
||||
|
||||
// 자기 자신을 복제해서 발사용 프리팹으로 제공
|
||||
GameObject arrowPrefab = gameObject;
|
||||
playerAttack.SwapArrow(arrowPrefab);
|
||||
|
||||
Debug.Log($"화살이 [{arrowName}](으)로 교체되었습니다!");
|
||||
|
||||
// 아이템 제거
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 발사 모드
|
||||
|
||||
/// <summary>
|
||||
/// PlayerAttack에서 호출 (발사 초기화)
|
||||
/// </summary>
|
||||
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<MonsterClass>();
|
||||
if (monster != null)
|
||||
{
|
||||
monster.TakeDamage(damage);
|
||||
}
|
||||
Destroy(gameObject);
|
||||
}
|
||||
else if (other.CompareTag("Wall") || other.CompareTag("Ground"))
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 외부 설정용
|
||||
|
||||
/// <summary>
|
||||
/// 몬스터 드롭 시 화살 정보 설정
|
||||
/// </summary>
|
||||
public void SetArrowData(string name, float dmg, float spd, float rng)
|
||||
{
|
||||
arrowName = name;
|
||||
damage = dmg;
|
||||
speed = spd;
|
||||
range = rng;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
11
Assets/Scripts/Player/Controller/ArrowPickup.cs.meta
Normal file
11
Assets/Scripts/Player/Controller/ArrowPickup.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1c61ccbf2fc5f2144872ea56d89cb755
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -16,6 +16,14 @@ public class PlayerInteraction : MonoBehaviour
|
|||
Collider[] hits = Physics.OverlapSphere(transform.position, interactRange, itemLayer);
|
||||
foreach (var hit in hits)
|
||||
{
|
||||
// 🏹 [새로 추가] 화살 아이템 습득
|
||||
if (hit.TryGetComponent<ArrowItem>(out var arrowItem))
|
||||
{
|
||||
PickupArrow(arrowItem);
|
||||
break;
|
||||
}
|
||||
|
||||
// 기존 무기 습득
|
||||
if (hit.TryGetComponent<EquippableItem>(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<HealthPotion>(out var potion)) { potion.Use(GetComponent<PlayerHealth>()); break; }
|
||||
if (hit.TryGetComponent<HealthAltar>(out var altar)) { altar.Use(GetComponent<PlayerHealth>()); break; }
|
||||
}
|
||||
}
|
||||
|
||||
// 🏹 [새 함수] 화살 습득 처리
|
||||
private void PickupArrow(ArrowItem arrowItem)
|
||||
{
|
||||
if (arrowItem == null) return;
|
||||
|
||||
// PlayerAttack 찾아서 화살 교체
|
||||
PlayerAttack playerAttack = GetComponent<PlayerAttack>();
|
||||
if (playerAttack != null)
|
||||
{
|
||||
arrowItem.Pickup(playerAttack);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("PlayerAttack 컴포넌트를 찾을 수 없습니다!");
|
||||
}
|
||||
}
|
||||
|
||||
private void EquipWeapon(EquippableItem item)
|
||||
{
|
||||
if (_currentWeapon != null) _currentWeapon.OnDropped(transform.forward);
|
||||
|
|
|
|||
|
|
@ -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<MeshFilter>();
|
||||
_meshRenderer = GetComponent<MeshRenderer>();
|
||||
_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();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user