Refactor course maps and travel UI
This commit is contained in:
@@ -1,281 +1,5 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &1166831543635676
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4518572068955746}
|
||||
- component: {fileID: 212503073192347908}
|
||||
- component: {fileID: 61881790296472918}
|
||||
m_Layer: 0
|
||||
m_Name: Obstacle Right
|
||||
m_TagString: Dead
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4518572068955746
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1166831543635676}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0.44, y: 1, z: 0}
|
||||
m_LocalScale: {x: 0.22222222, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4447057583457146}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!212 &212503073192347908
|
||||
SpriteRenderer:
|
||||
serializedVersion: 2
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1166831543635676}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 0
|
||||
m_ReceiveShadows: 0
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 4294967295
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 10754, 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: 0
|
||||
m_SelectedEditorRenderState: 0
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: -294611229
|
||||
m_SortingLayer: 2
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_Sprite: {fileID: 21300000, guid: c786e87f13804e37be5de982aee4f675, type: 3}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_FlipX: 0
|
||||
m_FlipY: 0
|
||||
m_DrawMode: 0
|
||||
m_Size: {x: 1.4, y: 1.4}
|
||||
m_AdaptiveModeThreshold: 0.5
|
||||
m_SpriteTileMode: 0
|
||||
m_WasSpriteAssigned: 1
|
||||
m_SpriteSortPoint: 0
|
||||
--- !u!61 &61881790296472918
|
||||
BoxCollider2D:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1166831543635676}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_Density: 1
|
||||
m_Material: {fileID: 0}
|
||||
m_IncludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_ExcludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_LayerOverridePriority: 0
|
||||
m_ForceSendLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ForceReceiveLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ContactCaptureLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_CallbackLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_IsTrigger: 1
|
||||
m_UsedByEffector: 0
|
||||
m_CompositeOperation: 0
|
||||
m_CompositeOrder: 0
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_SpriteTilingProperty:
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
oldSize: {x: 1.6, y: 1}
|
||||
newSize: {x: 1.4, y: 1.4}
|
||||
adaptiveTilingThreshold: 0.5
|
||||
drawMode: 0
|
||||
adaptiveTiling: 0
|
||||
m_AutoTiling: 0
|
||||
m_Size: {x: 1.2, y: 1}
|
||||
m_EdgeRadius: 0
|
||||
--- !u!1 &1297539188427694
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4605692002121302}
|
||||
- component: {fileID: 212000956051026164}
|
||||
- component: {fileID: 61237356497549858}
|
||||
m_Layer: 0
|
||||
m_Name: Obstacle Left
|
||||
m_TagString: Dead
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4605692002121302
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1297539188427694}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: -0.44, y: 1, z: 0}
|
||||
m_LocalScale: {x: 0.22222222, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4447057583457146}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!212 &212000956051026164
|
||||
SpriteRenderer:
|
||||
serializedVersion: 2
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1297539188427694}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 0
|
||||
m_ReceiveShadows: 0
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 4294967295
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 10754, 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: 0
|
||||
m_SelectedEditorRenderState: 0
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: -294611229
|
||||
m_SortingLayer: 2
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_Sprite: {fileID: 21300000, guid: c786e87f13804e37be5de982aee4f675, type: 3}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_FlipX: 0
|
||||
m_FlipY: 0
|
||||
m_DrawMode: 0
|
||||
m_Size: {x: 1.4, y: 1.4}
|
||||
m_AdaptiveModeThreshold: 0.5
|
||||
m_SpriteTileMode: 0
|
||||
m_WasSpriteAssigned: 1
|
||||
m_SpriteSortPoint: 0
|
||||
--- !u!61 &61237356497549858
|
||||
BoxCollider2D:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1297539188427694}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_Density: 1
|
||||
m_Material: {fileID: 0}
|
||||
m_IncludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_ExcludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_LayerOverridePriority: 0
|
||||
m_ForceSendLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ForceReceiveLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ContactCaptureLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_CallbackLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_IsTrigger: 1
|
||||
m_UsedByEffector: 0
|
||||
m_CompositeOperation: 0
|
||||
m_CompositeOrder: 0
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_SpriteTilingProperty:
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
oldSize: {x: 1.6, y: 1}
|
||||
newSize: {x: 1.4, y: 1.4}
|
||||
adaptiveTilingThreshold: 0.5
|
||||
drawMode: 0
|
||||
adaptiveTiling: 0
|
||||
m_AutoTiling: 0
|
||||
m_Size: {x: 1.2, y: 1}
|
||||
m_EdgeRadius: 0
|
||||
--- !u!1 &1671242928466520
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -308,11 +32,7 @@ Transform:
|
||||
m_LocalPosition: {x: 15.2227, y: 0.0055, z: 0}
|
||||
m_LocalScale: {x: 4.778359, y: 1.011, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 4605692002121302}
|
||||
- {fileID: 4014685509531708}
|
||||
- {fileID: 4518572068955746}
|
||||
- {fileID: 4987654321098765}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!212 &212850827289184248
|
||||
@@ -445,575 +165,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 9f975ef653abb48238f62061ebab1c23, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Platform
|
||||
obstacles:
|
||||
- {fileID: 1297539188427694}
|
||||
- {fileID: 1832961231703714}
|
||||
- {fileID: 1166831543635676}
|
||||
- {fileID: 1987654321098765}
|
||||
emptyPatternWeight: 2
|
||||
mileageSprite: {fileID: 21300000, guid: 8b2f1d0c3e4a5b6f9d7e0123456789ab, type: 3}
|
||||
mileagePatternChance: 50
|
||||
smallMileageValue: 10
|
||||
bonusMileageValue: 30
|
||||
--- !u!1 &1832961231703714
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4014685509531708}
|
||||
- component: {fileID: 212599298415523624}
|
||||
- component: {fileID: 61928244072500108}
|
||||
m_Layer: 0
|
||||
m_Name: Obstacle Mid
|
||||
m_TagString: Dead
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4014685509531708
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1832961231703714}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 1, z: 0}
|
||||
m_LocalScale: {x: 0.22222222, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4447057583457146}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!212 &212599298415523624
|
||||
SpriteRenderer:
|
||||
serializedVersion: 2
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1832961231703714}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 0
|
||||
m_ReceiveShadows: 0
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 4294967295
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 10754, 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: 0
|
||||
m_SelectedEditorRenderState: 0
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: -294611229
|
||||
m_SortingLayer: 2
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_Sprite: {fileID: 21300000, guid: c786e87f13804e37be5de982aee4f675, type: 3}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_FlipX: 0
|
||||
m_FlipY: 0
|
||||
m_DrawMode: 0
|
||||
m_Size: {x: 1.4, y: 1.4}
|
||||
m_AdaptiveModeThreshold: 0.5
|
||||
m_SpriteTileMode: 0
|
||||
m_WasSpriteAssigned: 1
|
||||
m_SpriteSortPoint: 0
|
||||
--- !u!61 &61928244072500108
|
||||
BoxCollider2D:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1832961231703714}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_Density: 1
|
||||
m_Material: {fileID: 0}
|
||||
m_IncludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_ExcludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_LayerOverridePriority: 0
|
||||
m_ForceSendLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ForceReceiveLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ContactCaptureLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_CallbackLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_IsTrigger: 1
|
||||
m_UsedByEffector: 0
|
||||
m_CompositeOperation: 0
|
||||
m_CompositeOrder: 0
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_SpriteTilingProperty:
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
oldSize: {x: 1.6, y: 1}
|
||||
newSize: {x: 1.4, y: 1.4}
|
||||
adaptiveTilingThreshold: 0.5
|
||||
drawMode: 0
|
||||
adaptiveTiling: 0
|
||||
m_AutoTiling: 0
|
||||
m_Size: {x: 1.2, y: 1}
|
||||
m_EdgeRadius: 0
|
||||
--- !u!1 &1928374650918273
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3876501129384756}
|
||||
- component: {fileID: 212887766554433221}
|
||||
- component: {fileID: 61988776655443322}
|
||||
m_Layer: 0
|
||||
m_Name: Obstacle High Left
|
||||
m_TagString: Dead
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &3876501129384756
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1928374650918273}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: -1.35, y: 2.68, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4987654321098765}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!212 &212887766554433221
|
||||
SpriteRenderer:
|
||||
serializedVersion: 2
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1928374650918273}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 0
|
||||
m_ReceiveShadows: 0
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 4294967295
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 10754, 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: 0
|
||||
m_SelectedEditorRenderState: 0
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: -294611229
|
||||
m_SortingLayer: 2
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_Sprite: {fileID: 21300000, guid: c7ce697688684c84928ff860570a69b3, type: 3}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_FlipX: 0
|
||||
m_FlipY: 0
|
||||
m_DrawMode: 0
|
||||
m_Size: {x: 1.4, y: 1.4}
|
||||
m_AdaptiveModeThreshold: 0.5
|
||||
m_SpriteTileMode: 0
|
||||
m_WasSpriteAssigned: 1
|
||||
m_SpriteSortPoint: 0
|
||||
--- !u!61 &61988776655443322
|
||||
BoxCollider2D:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1928374650918273}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_Density: 1
|
||||
m_Material: {fileID: 0}
|
||||
m_IncludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_ExcludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_LayerOverridePriority: 0
|
||||
m_ForceSendLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ForceReceiveLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ContactCaptureLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_CallbackLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_IsTrigger: 1
|
||||
m_UsedByEffector: 0
|
||||
m_CompositeOperation: 0
|
||||
m_CompositeOrder: 0
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_SpriteTilingProperty:
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
oldSize: {x: 1.6, y: 1}
|
||||
newSize: {x: 1.4, y: 1.4}
|
||||
adaptiveTilingThreshold: 0.5
|
||||
drawMode: 0
|
||||
adaptiveTiling: 0
|
||||
m_AutoTiling: 0
|
||||
m_Size: {x: 1.55, y: 0.7}
|
||||
m_EdgeRadius: 0
|
||||
--- !u!1 &1987654321098765
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4987654321098765}
|
||||
- component: {fileID: 114987654321098765}
|
||||
m_Layer: 0
|
||||
m_Name: Slide Obstacle Pattern
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4987654321098765
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1987654321098765}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0.22222222, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 4987654321098766}
|
||||
- {fileID: 3876501129384756}
|
||||
- {fileID: 4987654321098767}
|
||||
m_Father: {fileID: 4447057583457146}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &114987654321098765
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1987654321098765}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 9dcd5b5fbb7b40d4b86fa136c439d1b7, type: 3}
|
||||
m_Name: SlideObstaclePattern
|
||||
m_EditorClassIdentifier: Assembly-CSharp::SlideObstaclePattern
|
||||
obstacles:
|
||||
- {fileID: 3876501129384756}
|
||||
- {fileID: 4987654321098767}
|
||||
xPositions:
|
||||
- -1.65
|
||||
- -0.55
|
||||
- 0.55
|
||||
- 1.65
|
||||
minSpacing: 1.5
|
||||
layout: 0
|
||||
--- !u!1 &1987654321098766
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4987654321098766}
|
||||
- component: {fileID: 212887766554433222}
|
||||
m_Layer: 0
|
||||
m_Name: Ceiling Platform
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4987654321098766
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1987654321098766}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: -0.09999995, y: 3.5000005, z: 0}
|
||||
m_LocalScale: {x: 3, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4987654321098765}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!212 &212887766554433222
|
||||
SpriteRenderer:
|
||||
serializedVersion: 2
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1987654321098766}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 0
|
||||
m_ReceiveShadows: 0
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 4294967295
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 10754, 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: 0
|
||||
m_SelectedEditorRenderState: 0
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: -591980115
|
||||
m_SortingLayer: 3
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_Sprite: {fileID: 21300000, guid: c61ae3691bcf45deabea44aed605c29d, type: 3}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_FlipX: 0
|
||||
m_FlipY: 0
|
||||
m_DrawMode: 0
|
||||
m_Size: {x: 7.6, y: 1.88}
|
||||
m_AdaptiveModeThreshold: 0.5
|
||||
m_SpriteTileMode: 0
|
||||
m_WasSpriteAssigned: 1
|
||||
m_SpriteSortPoint: 0
|
||||
--- !u!1 &1987654321098767
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4987654321098767}
|
||||
- component: {fileID: 212887766554433223}
|
||||
- component: {fileID: 61988776655443323}
|
||||
m_Layer: 0
|
||||
m_Name: Obstacle High Right
|
||||
m_TagString: Dead
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4987654321098767
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1987654321098767}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 1.1199999, y: 2.6800003, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4987654321098765}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!212 &212887766554433223
|
||||
SpriteRenderer:
|
||||
serializedVersion: 2
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1987654321098767}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 0
|
||||
m_ReceiveShadows: 0
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 4294967295
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 10754, 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: 0
|
||||
m_SelectedEditorRenderState: 0
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: -294611229
|
||||
m_SortingLayer: 2
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_Sprite: {fileID: 21300000, guid: c7ce697688684c84928ff860570a69b3, type: 3}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_FlipX: 0
|
||||
m_FlipY: 0
|
||||
m_DrawMode: 0
|
||||
m_Size: {x: 1.4, y: 1.4}
|
||||
m_AdaptiveModeThreshold: 0.5
|
||||
m_SpriteTileMode: 0
|
||||
m_WasSpriteAssigned: 1
|
||||
m_SpriteSortPoint: 0
|
||||
--- !u!61 &61988776655443323
|
||||
BoxCollider2D:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1987654321098767}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_Density: 1
|
||||
m_Material: {fileID: 0}
|
||||
m_IncludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_ExcludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_LayerOverridePriority: 0
|
||||
m_ForceSendLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ForceReceiveLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ContactCaptureLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_CallbackLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_IsTrigger: 1
|
||||
m_UsedByEffector: 0
|
||||
m_CompositeOperation: 0
|
||||
m_CompositeOrder: 0
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_SpriteTilingProperty:
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
oldSize: {x: 1.6, y: 1}
|
||||
newSize: {x: 1.4, y: 1.4}
|
||||
adaptiveTilingThreshold: 0.5
|
||||
drawMode: 0
|
||||
adaptiveTiling: 0
|
||||
m_AutoTiling: 0
|
||||
m_Size: {x: 1.55, y: 0.7}
|
||||
m_EdgeRadius: 0
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 287 KiB |
@@ -0,0 +1,143 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93a27e424cd947568993dbf3a6d1e931
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 1
|
||||
swizzle: 50462976
|
||||
cookieLightType: 1
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 4
|
||||
buildTarget: iOS
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 4
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: f455a5c527e246d2a2a51e974d147d2c
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
@@ -0,0 +1,143 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7c3aa91d47245efb7e68f53a025cb4d
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 1
|
||||
swizzle: 50462976
|
||||
cookieLightType: 1
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 4
|
||||
buildTarget: iOS
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 4
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: abbbda8464dc4b17a7dcc4997a22d398
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e8469e5a7a7443f9adff42c0c7bf921
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,6 @@
|
||||
public enum CoursePlatformType {
|
||||
Basic,
|
||||
Jump,
|
||||
Slide,
|
||||
ForceHit
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02a1bb5c51284fd8ad76d51d8327a14c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
[Serializable]
|
||||
public class CourseStep {
|
||||
public CoursePlatformType coursePlatformType;
|
||||
public Platform.PlatformPattern platformPattern;
|
||||
public Platform.MileagePattern mileagePattern;
|
||||
public SlideObstaclePattern.SlideLayout slideLayout;
|
||||
public Platform.ItemPattern itemPattern;
|
||||
public GameManager.TutorialGuideType guideType;
|
||||
public float yPosition;
|
||||
public float spawnInterval;
|
||||
public string title;
|
||||
public string message;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21d873850c7043ef8b2854e1a5f16d9b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,189 @@
|
||||
public static class CourseStepFactory {
|
||||
public const float GroundY = -2.4f;
|
||||
public const float AerialY = -0.85f;
|
||||
public const float BasicSpacing = 0.58f;
|
||||
public const float ActionSpacing = 0.72f;
|
||||
public const float LandingSpacing = 0.64f;
|
||||
public const float AerialSpacing = 2.05f;
|
||||
|
||||
public static CourseStep[] CreateEasyLoop() {
|
||||
return new CourseStep[] {
|
||||
Basic(),
|
||||
Jump(),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Aerial(),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Slide(SlideObstaclePattern.SlideLayout.CenterPair),
|
||||
Basic()
|
||||
};
|
||||
}
|
||||
|
||||
public static CourseStep Basic(
|
||||
float yPosition = GroundY,
|
||||
float spawnInterval = BasicSpacing,
|
||||
Platform.MileagePattern mileagePattern = Platform.MileagePattern.SafeLine,
|
||||
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.None,
|
||||
string title = "",
|
||||
string message = "",
|
||||
Platform.ItemPattern itemPattern = Platform.ItemPattern.None) {
|
||||
return Step(
|
||||
Platform.PlatformPattern.Empty,
|
||||
mileagePattern,
|
||||
SlideObstaclePattern.SlideLayout.Random,
|
||||
guideType,
|
||||
GroundY,
|
||||
spawnInterval,
|
||||
title,
|
||||
message,
|
||||
itemPattern,
|
||||
CoursePlatformType.Basic);
|
||||
}
|
||||
|
||||
public static CourseStep Jump(
|
||||
Platform.PlatformPattern platformPattern = Platform.PlatformPattern.LowMid,
|
||||
float spawnInterval = ActionSpacing,
|
||||
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.None,
|
||||
string title = "",
|
||||
string message = "") {
|
||||
return Step(
|
||||
platformPattern,
|
||||
Platform.MileagePattern.JumpArc,
|
||||
SlideObstaclePattern.SlideLayout.Random,
|
||||
guideType,
|
||||
GroundY,
|
||||
spawnInterval,
|
||||
title,
|
||||
message,
|
||||
Platform.ItemPattern.None,
|
||||
CoursePlatformType.Jump);
|
||||
}
|
||||
|
||||
public static CourseStep Jump(
|
||||
GameManager.TutorialGuideType guideType,
|
||||
string title,
|
||||
string message) {
|
||||
return Jump(Platform.PlatformPattern.LowMid, ActionSpacing, guideType, title, message);
|
||||
}
|
||||
|
||||
public static CourseStep Aerial(
|
||||
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.None,
|
||||
string title = "",
|
||||
string message = "") {
|
||||
return Aerial(AerialY, AerialSpacing, guideType, title, message);
|
||||
}
|
||||
|
||||
public static CourseStep Aerial(
|
||||
float yPosition,
|
||||
float spawnInterval,
|
||||
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.None,
|
||||
string title = "",
|
||||
string message = "") {
|
||||
return Step(
|
||||
Platform.PlatformPattern.Empty,
|
||||
Platform.MileagePattern.SafeLine,
|
||||
SlideObstaclePattern.SlideLayout.Random,
|
||||
guideType,
|
||||
yPosition,
|
||||
spawnInterval,
|
||||
title,
|
||||
message,
|
||||
Platform.ItemPattern.None,
|
||||
CoursePlatformType.Basic);
|
||||
}
|
||||
|
||||
public static CourseStep Slide(
|
||||
SlideObstaclePattern.SlideLayout slideLayout = SlideObstaclePattern.SlideLayout.CenterPair,
|
||||
float spawnInterval = ActionSpacing,
|
||||
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.None,
|
||||
string title = "",
|
||||
string message = "") {
|
||||
return Step(
|
||||
Platform.PlatformPattern.Slide,
|
||||
Platform.MileagePattern.SlideLine,
|
||||
slideLayout,
|
||||
guideType,
|
||||
GroundY,
|
||||
spawnInterval,
|
||||
title,
|
||||
message,
|
||||
Platform.ItemPattern.None,
|
||||
CoursePlatformType.Slide);
|
||||
}
|
||||
|
||||
public static CourseStep Slide(
|
||||
GameManager.TutorialGuideType guideType,
|
||||
string title,
|
||||
string message) {
|
||||
return Slide(SlideObstaclePattern.SlideLayout.CenterPair, ActionSpacing, guideType, title, message);
|
||||
}
|
||||
|
||||
public static CourseStep ForceHit(
|
||||
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.Damage,
|
||||
string title = "",
|
||||
string message = "",
|
||||
float spawnInterval = ActionSpacing) {
|
||||
return Step(
|
||||
Platform.PlatformPattern.ForceHit,
|
||||
Platform.MileagePattern.None,
|
||||
SlideObstaclePattern.SlideLayout.WidePair,
|
||||
guideType,
|
||||
GroundY,
|
||||
spawnInterval,
|
||||
title,
|
||||
message,
|
||||
Platform.ItemPattern.None,
|
||||
CoursePlatformType.ForceHit);
|
||||
}
|
||||
|
||||
public static CourseStep Step(
|
||||
Platform.PlatformPattern platformPattern,
|
||||
Platform.MileagePattern mileagePattern,
|
||||
SlideObstaclePattern.SlideLayout slideLayout,
|
||||
GameManager.TutorialGuideType guideType,
|
||||
float yPosition,
|
||||
float spawnInterval,
|
||||
string title = "",
|
||||
string message = "",
|
||||
Platform.ItemPattern itemPattern = Platform.ItemPattern.None,
|
||||
CoursePlatformType coursePlatformType = CoursePlatformType.Basic) {
|
||||
return new CourseStep {
|
||||
coursePlatformType = coursePlatformType,
|
||||
platformPattern = platformPattern,
|
||||
mileagePattern = mileagePattern,
|
||||
slideLayout = slideLayout,
|
||||
itemPattern = itemPattern,
|
||||
guideType = guideType,
|
||||
yPosition = yPosition,
|
||||
spawnInterval = spawnInterval,
|
||||
title = title,
|
||||
message = message
|
||||
};
|
||||
}
|
||||
|
||||
public static CourseStep[] CloneSteps(CourseStep[] source) {
|
||||
if(source == null)
|
||||
{
|
||||
return new CourseStep[0];
|
||||
}
|
||||
|
||||
CourseStep[] steps = new CourseStep[source.Length];
|
||||
|
||||
for(int i = 0; i < source.Length; i++)
|
||||
{
|
||||
CourseStep sourceStep = source[i];
|
||||
steps[i] = Step(
|
||||
sourceStep.platformPattern,
|
||||
sourceStep.mileagePattern,
|
||||
sourceStep.slideLayout,
|
||||
sourceStep.guideType,
|
||||
sourceStep.yPosition,
|
||||
sourceStep.spawnInterval,
|
||||
sourceStep.title,
|
||||
sourceStep.message,
|
||||
sourceStep.itemPattern,
|
||||
sourceStep.coursePlatformType);
|
||||
}
|
||||
|
||||
return steps;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b8e2ef0ff2346e8ab5e6d6557e41b10
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
public enum CourseStepKind {
|
||||
None,
|
||||
Jump,
|
||||
DoubleJumpTakeoff,
|
||||
Slide,
|
||||
ForceHit,
|
||||
HealthItem,
|
||||
InvincibleItem,
|
||||
ShieldItem,
|
||||
SpeedItem,
|
||||
MileageCardItem
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e543ce69f5964c1195ce10e5fe7e2a7e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -15,7 +15,8 @@ public class GameFlowManager : MonoBehaviour {
|
||||
Game,
|
||||
Result,
|
||||
DutyFreeShop,
|
||||
MapPreview
|
||||
MapPreview,
|
||||
DebugMenu
|
||||
}
|
||||
|
||||
public static GameFlowManager Instance { get; private set; }
|
||||
@@ -39,6 +40,27 @@ public class GameFlowManager : MonoBehaviour {
|
||||
private const string ResultSceneName = "Result";
|
||||
private const string DutyFreeShopSceneName = "DutyFreeShop";
|
||||
private const string MapPreviewSceneName = "MapPreview";
|
||||
private const string DepartureStampResourcePath = "UI_DepartureStamp_Red";
|
||||
private const string ResultPassportPanelResourcePath = "UI_LeftHudPassportHorizontalGridPanel";
|
||||
private const string ResultAirportBackgroundResourcePath = "Map_Tutorial_Incheon_Airport";
|
||||
private const string ResultButtonResourcePath = "UI_TutorialNextButton";
|
||||
private const string ResultButtonAssetPath = "Assets/Resources/UI_TutorialNextButton.png";
|
||||
private const string MileageIconAssetPath = "Assets/Sprites/UIIcons/UI_Mileage.png";
|
||||
private const string TimerIconAssetPath = "Assets/Sprites/UIIcons/UI_Timer.png";
|
||||
private const string CheckpointIconAssetPath = "Assets/Sprites/UIIcons/UI_Checkpoint.png";
|
||||
private const string ClearRankIconAssetPath = "Assets/Sprites/UIIcons/UI_ClearRank.png";
|
||||
private const string DutyFreeIconAssetPath = "Assets/Sprites/UIIcons/UI_DutyFreeShop.png";
|
||||
private const string AirplaneTravelIconAssetPath = "Assets/Sprites/UIIcons/UI_AirplaneTravel.png";
|
||||
private const string DutyFreeBackgroundAssetPath = "Assets/ConceptArt/duty_free_shop_screen_concept_01.png";
|
||||
private const string DutyFreeLunchboxAssetPath = "Assets/Sprites/DutyFree/DutyFree_Normal_Lunchbox.png";
|
||||
private const string DutyFreeShieldAssetPath = "Assets/Sprites/DutyFree/DutyFree_Normal_ShieldCharm.png";
|
||||
private const string DutyFreeShoesAssetPath = "Assets/Sprites/DutyFree/DutyFree_Normal_Shoes.png";
|
||||
private const string DutyFreeMileageCardAssetPath = "Assets/Sprites/DutyFree/DutyFree_Normal_MileageCard.png";
|
||||
private const string SouvenirCollectionIconAssetPath = "Assets/Sprites/UIIcons/UI_SouvenirCollection.png";
|
||||
private const string AirportSouvenirAssetPath = "Assets/Sprites/Souvenirs/Souvenir_AirportMagnet.png";
|
||||
private const string JapanSouvenirAssetPath = "Assets/Sprites/Souvenirs/Souvenir_Japan_Magnet.png";
|
||||
private const string ChinaSouvenirAssetPath = "Assets/Sprites/Souvenirs/Souvenir_TempleCharm.png";
|
||||
private const string AmericaSouvenirAssetPath = "Assets/Sprites/Souvenirs/Souvenir_SkylineMagnet.png";
|
||||
private const int ShieldCost = 120;
|
||||
private const int LunchboxCost = 80;
|
||||
private const int SpeedShoesCost = 140;
|
||||
@@ -98,6 +120,50 @@ public class GameFlowManager : MonoBehaviour {
|
||||
ShowIntro();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR || DEVELOPMENT_BUILD
|
||||
private void Update() {
|
||||
if(Input.GetKeyDown(KeyCode.Escape))
|
||||
{
|
||||
ShowDebugMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
HandleDebugMenuShortcutInput();
|
||||
}
|
||||
|
||||
private void HandleDebugMenuShortcutInput() {
|
||||
if(currentScreen != FlowScreen.DebugMenu)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(Input.GetKeyDown(KeyCode.Alpha1) || Input.GetKeyDown(KeyCode.Keypad1))
|
||||
{
|
||||
ShowDebugIntroPreview();
|
||||
}
|
||||
else if(Input.GetKeyDown(KeyCode.Alpha2) || Input.GetKeyDown(KeyCode.Keypad2))
|
||||
{
|
||||
ShowDebugGameStartPreview();
|
||||
}
|
||||
else if(Input.GetKeyDown(KeyCode.Alpha3) || Input.GetKeyDown(KeyCode.Keypad3))
|
||||
{
|
||||
ShowDebugResultPreview(false);
|
||||
}
|
||||
else if(Input.GetKeyDown(KeyCode.Alpha4) || Input.GetKeyDown(KeyCode.Keypad4))
|
||||
{
|
||||
ShowDebugResultPreview(true);
|
||||
}
|
||||
else if(Input.GetKeyDown(KeyCode.Alpha5) || Input.GetKeyDown(KeyCode.Keypad5))
|
||||
{
|
||||
ShowDebugDutyFreeShopPreview();
|
||||
}
|
||||
else if(Input.GetKeyDown(KeyCode.Alpha6) || Input.GetKeyDown(KeyCode.Keypad6))
|
||||
{
|
||||
ShowDebugMapPreview();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private void OnDestroy() {
|
||||
if(Instance == this)
|
||||
{
|
||||
@@ -173,6 +239,95 @@ public class GameFlowManager : MonoBehaviour {
|
||||
ShowResult();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR || DEVELOPMENT_BUILD
|
||||
private void ShowDebugMenu() {
|
||||
EnsureDebugPreviewData();
|
||||
|
||||
gameplayActive = false;
|
||||
pendingStartGameplay = false;
|
||||
currentScreen = FlowScreen.DebugMenu;
|
||||
|
||||
EnsureOverlay();
|
||||
ClearOverlay();
|
||||
SetOverlayVisible(true);
|
||||
SetDefaultOverlayBackground();
|
||||
|
||||
AddTitle("디버그 메뉴");
|
||||
AddBody("화면 조정용 바로 이동\n숫자키 1~6도 사용할 수 있습니다.");
|
||||
AddButton("1. 인트로", ShowDebugIntroPreview);
|
||||
AddButton("2. 게임 시작", ShowDebugGameStartPreview);
|
||||
AddButton("3. 출국 실패", delegate { ShowDebugResultPreview(false); });
|
||||
AddButton("4. 출국 성공", delegate { ShowDebugResultPreview(true); });
|
||||
AddButton("5. 면세점", ShowDebugDutyFreeShopPreview);
|
||||
AddButton("6. 지도", ShowDebugMapPreview);
|
||||
}
|
||||
|
||||
private void ShowDebugIntroPreview() {
|
||||
ShowIntro();
|
||||
}
|
||||
|
||||
private void ShowDebugGameStartPreview() {
|
||||
EnsureDebugPreviewData();
|
||||
LoadGameSceneForCurrentMap();
|
||||
}
|
||||
|
||||
private void ShowDebugResultPreview(bool cleared) {
|
||||
EnsureDebugPreviewData();
|
||||
|
||||
gameplayActive = false;
|
||||
pendingStartGameplay = false;
|
||||
currentScreen = FlowScreen.Result;
|
||||
completedMap = currentMap;
|
||||
lastResultCleared = cleared;
|
||||
lastResultScore = cleared ? 12800 : 7200;
|
||||
lastResultMileage = cleared ? 263 : 84;
|
||||
lastResultTime = cleared ? 23.9f : 38.4f;
|
||||
lastResultDistance = completedMap != null
|
||||
? (cleared ? completedMap.targetDistance : completedMap.targetDistance * 0.62f)
|
||||
: 380f;
|
||||
|
||||
if(saveData != null)
|
||||
{
|
||||
saveData.totalMileage = Mathf.Max(saveData.totalMileage, 4120);
|
||||
}
|
||||
|
||||
ShowResult();
|
||||
}
|
||||
|
||||
private void ShowDebugDutyFreeShopPreview() {
|
||||
EnsureDebugPreviewData();
|
||||
|
||||
if(saveData != null)
|
||||
{
|
||||
saveData.totalMileage = Mathf.Max(saveData.totalMileage, 4120);
|
||||
}
|
||||
|
||||
ShowDutyFreeShop();
|
||||
}
|
||||
|
||||
private void ShowDebugMapPreview() {
|
||||
EnsureDebugPreviewData();
|
||||
ShowMapPreview();
|
||||
}
|
||||
|
||||
private void EnsureDebugPreviewData() {
|
||||
if(saveData == null)
|
||||
{
|
||||
saveData = GameSaveManager.Load();
|
||||
}
|
||||
|
||||
if(currentMap == null)
|
||||
{
|
||||
currentMap = MapDatabase.GetMapByIndex(saveData != null ? saveData.currentMapIndex : 0);
|
||||
}
|
||||
|
||||
if(currentMap == null)
|
||||
{
|
||||
currentMap = MapDatabase.GetMapByIndex(0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private void StartNewJourney() {
|
||||
saveData = GameSaveManager.ResetSave();
|
||||
currentMap = MapDatabase.GetMapByIndex(saveData.currentMapIndex);
|
||||
@@ -271,33 +426,298 @@ public class GameFlowManager : MonoBehaviour {
|
||||
EnsureOverlay();
|
||||
ClearOverlay();
|
||||
SetOverlayVisible(true);
|
||||
SetDefaultOverlayBackground();
|
||||
BuildResultScreen();
|
||||
}
|
||||
|
||||
string title = lastResultCleared ? "맵 클리어" : "일정 실패";
|
||||
string body = completedMap.displayName
|
||||
+ "\n점수: " + lastResultScore
|
||||
+ "\n획득 마일리지: " + lastResultMileage
|
||||
+ "\n거리: " + Mathf.FloorToInt(lastResultDistance) + "m / " + Mathf.FloorToInt(completedMap.targetDistance) + "m"
|
||||
+ "\n시간: " + lastResultTime.ToString("0.0") + "s";
|
||||
private void BuildResultScreen() {
|
||||
ApplyResultAirportBackground();
|
||||
|
||||
MapDefinition resultMap = completedMap != null ? completedMap : currentMap;
|
||||
int rewardMileage = lastResultCleared && resultMap != null ? resultMap.clearMileageReward : 0;
|
||||
int gainedMileage = Mathf.Max(0, lastResultMileage) + rewardMileage;
|
||||
int targetDistance = resultMap != null ? Mathf.FloorToInt(resultMap.targetDistance) : 0;
|
||||
int shownDistance = targetDistance > 0
|
||||
? Mathf.Clamp(Mathf.FloorToInt(lastResultDistance), 0, targetDistance)
|
||||
: Mathf.Max(0, Mathf.FloorToInt(lastResultDistance));
|
||||
|
||||
RectTransform passportRect = AddResultPassportPanel();
|
||||
AddResultHeader(passportRect, resultMap);
|
||||
AddResultStats(passportRect, gainedMileage, shownDistance, targetDistance);
|
||||
AddResultTickets(passportRect, resultMap, rewardMileage);
|
||||
|
||||
if(lastResultCleared)
|
||||
{
|
||||
body += "\n클리어 보상: " + completedMap.clearMileageReward + " 마일리지";
|
||||
}
|
||||
|
||||
AddTitle(title);
|
||||
AddBody(body);
|
||||
|
||||
if(lastResultCleared)
|
||||
{
|
||||
AddButton("면세점으로", ShowDutyFreeShop);
|
||||
AddResultActionButton("면세점으로", ShowDutyFreeShop, new Vector2(-166f, -282f), new Vector2(250f, 48f), true, LoadUiSprite("", DutyFreeIconAssetPath));
|
||||
AddResultActionButton("다음 여행지 가기", ShowMapPreview, new Vector2(160f, -282f), new Vector2(292f, 48f), false, LoadUiSprite("", AirplaneTravelIconAssetPath));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddButton("다시 도전", RetryCurrentMap);
|
||||
AddResultActionButton("다시 도전", RetryCurrentMap, new Vector2(-166f, -282f), new Vector2(250f, 48f), true, LoadUiSprite("", CheckpointIconAssetPath));
|
||||
AddResultActionButton("다음 여행지 가기", ShowMapPreview, new Vector2(160f, -282f), new Vector2(292f, 48f), false, LoadUiSprite("", AirplaneTravelIconAssetPath));
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyResultAirportBackground() {
|
||||
if(overlayBackground != null)
|
||||
{
|
||||
overlayBackground.sprite = LoadUiSprite(ResultAirportBackgroundResourcePath, "Assets/Resources/Map_Tutorial_Incheon_Airport.png");
|
||||
overlayBackground.preserveAspect = false;
|
||||
overlayBackground.color = overlayBackground.sprite != null
|
||||
? Color.white
|
||||
: new Color(0.008f, 0.024f, 0.034f, 0.96f);
|
||||
}
|
||||
|
||||
AddButton("인트로", ShowIntro);
|
||||
if(flowCamera != null)
|
||||
{
|
||||
flowCamera.backgroundColor = new Color(0.006f, 0.022f, 0.035f, 1f);
|
||||
}
|
||||
|
||||
GameObject scrimObject = CreateUiObject("Result Airport Background Scrim", overlayRoot, typeof(Image));
|
||||
RectTransform scrimRect = scrimObject.GetComponent<RectTransform>();
|
||||
scrimRect.anchorMin = Vector2.zero;
|
||||
scrimRect.anchorMax = Vector2.one;
|
||||
scrimRect.offsetMin = Vector2.zero;
|
||||
scrimRect.offsetMax = Vector2.zero;
|
||||
|
||||
Image scrimImage = scrimObject.GetComponent<Image>();
|
||||
scrimImage.color = new Color(0.005f, 0.015f, 0.020f, 0.30f);
|
||||
scrimImage.raycastTarget = false;
|
||||
}
|
||||
|
||||
private RectTransform AddResultPassportPanel() {
|
||||
GameObject panelObject = CreateUiObject("Result Passport Page", overlayRoot, typeof(Image));
|
||||
RectTransform panelRect = panelObject.GetComponent<RectTransform>();
|
||||
panelRect.anchorMin = new Vector2(0.5f, 0.5f);
|
||||
panelRect.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
panelRect.pivot = new Vector2(0.5f, 0.5f);
|
||||
panelRect.anchoredPosition = new Vector2(0f, 38f);
|
||||
panelRect.sizeDelta = new Vector2(1092f, 330f);
|
||||
|
||||
Image panelImage = panelObject.GetComponent<Image>();
|
||||
panelImage.sprite = LoadUiSprite(ResultPassportPanelResourcePath, "Assets/Resources/UI_LeftHudPassportHorizontalGridPanel.png");
|
||||
panelImage.color = panelImage.sprite != null
|
||||
? Color.white
|
||||
: new Color(0.95f, 0.91f, 0.80f, 0.98f);
|
||||
panelImage.preserveAspect = true;
|
||||
panelImage.raycastTarget = false;
|
||||
|
||||
return panelRect;
|
||||
}
|
||||
|
||||
private void AddResultHeader(RectTransform parent, MapDefinition resultMap) {
|
||||
Sprite rankSprite = LoadUiSprite("", ClearRankIconAssetPath);
|
||||
Sprite stampSprite = LoadUiSprite(DepartureStampResourcePath, "Assets/Resources/UI_DepartureStamp_Red.png");
|
||||
|
||||
AddResultImage(parent, "Result Rank Badge", rankSprite, new Vector2(170f, -106f), new Vector2(50f, 50f), true, Color.white);
|
||||
|
||||
string title = lastResultCleared ? "출국 성공!" : "일정 실패";
|
||||
Color titleColor = lastResultCleared
|
||||
? new Color(0.05f, 0.17f, 0.27f, 1f)
|
||||
: new Color(0.52f, 0.08f, 0.07f, 1f);
|
||||
AddResultText(parent, "Result Title", title, new Vector2(194f, -88f), new Vector2(210f, 50f), 28f, FontStyles.Bold, titleColor, TextAlignmentOptions.MidlineLeft);
|
||||
|
||||
string destination = GetResultDestinationName(resultMap);
|
||||
AddResultText(parent, "Result Route", destination, new Vector2(260f, -140f), new Vector2(210f, 22f), 13f, FontStyles.Bold, new Color(0.25f, 0.42f, 0.50f, 0.96f), TextAlignmentOptions.MidlineLeft);
|
||||
|
||||
if(lastResultCleared)
|
||||
{
|
||||
AddResultImage(parent, "Result Departure Stamp", stampSprite, new Vector2(250f, -232f), new Vector2(108f, 108f), true, new Color(1f, 1f, 1f, 0.92f));
|
||||
TextMeshProUGUI stampText = AddResultText(parent, "Result Stamp Text", "출국\n성공", new Vector2(228f, -218f), new Vector2(92f, 48f), 21f, FontStyles.Bold, new Color(0.70f, 0.04f, 0.03f, 0.96f), TextAlignmentOptions.Center);
|
||||
stampText.lineSpacing = -16f;
|
||||
}
|
||||
else
|
||||
{
|
||||
AddResultText(parent, "Result Retry Note", "다시 준비해서\n출국 게이트까지", new Vector2(178f, -216f), new Vector2(200f, 56f), 17f, FontStyles.Bold, new Color(0.32f, 0.46f, 0.54f, 0.96f), TextAlignmentOptions.Center);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddResultStats(RectTransform parent, int gainedMileage, int shownDistance, int targetDistance) {
|
||||
AddResultStat(parent, "Mileage", LoadUiSprite("", MileageIconAssetPath), "마일리지", "+" + gainedMileage, new Vector2(478f, -90f));
|
||||
AddResultStat(parent, "Time", LoadUiSprite("", TimerIconAssetPath), "도착 시간", lastResultTime.ToString("0.0") + "s", new Vector2(626f, -90f));
|
||||
|
||||
string distance = targetDistance > 0
|
||||
? shownDistance + "/" + targetDistance + "m"
|
||||
: shownDistance + "m";
|
||||
AddResultStat(parent, "Distance", LoadUiSprite("", CheckpointIconAssetPath), "이동 거리", distance, new Vector2(770f, -90f));
|
||||
}
|
||||
|
||||
private void AddResultTickets(RectTransform parent, MapDefinition resultMap, int rewardMileage) {
|
||||
AddResultTicket(
|
||||
parent,
|
||||
"Destination",
|
||||
LoadUiSprite("", CheckpointIconAssetPath),
|
||||
"목적지",
|
||||
GetResultDestinationName(resultMap),
|
||||
new Vector2(410f, -200f));
|
||||
|
||||
AddResultTicket(
|
||||
parent,
|
||||
"Souvenir",
|
||||
lastResultCleared ? GetResultSouvenirSprite(resultMap) : LoadUiSprite("", SouvenirCollectionIconAssetPath),
|
||||
"보상",
|
||||
lastResultCleared ? GetResultSouvenirName(resultMap) : "다음 도전",
|
||||
new Vector2(560f, -200f));
|
||||
|
||||
AddResultTicket(
|
||||
parent,
|
||||
"Total Mileage",
|
||||
LoadUiSprite("", MileageIconAssetPath),
|
||||
"보유",
|
||||
saveData.totalMileage + " M",
|
||||
new Vector2(710f, -200f));
|
||||
}
|
||||
|
||||
private void AddResultStat(RectTransform parent, string objectName, Sprite iconSprite, string label, string value, Vector2 centerPosition) {
|
||||
AddResultImage(parent, "Result " + objectName + " Icon", iconSprite, centerPosition + new Vector2(0f, -4f), new Vector2(42f, 42f), true, Color.white);
|
||||
AddResultText(parent, "Result " + objectName + " Value", value, centerPosition + new Vector2(-70f, -25f), new Vector2(140f, 24f), 15f, FontStyles.Bold, new Color(0.05f, 0.17f, 0.25f, 1f), TextAlignmentOptions.Center);
|
||||
AddResultText(parent, "Result " + objectName + " Label", label, centerPosition + new Vector2(-70f, -48f), new Vector2(140f, 18f), 8f, FontStyles.Bold, new Color(0.42f, 0.58f, 0.64f, 0.92f), TextAlignmentOptions.Center);
|
||||
}
|
||||
|
||||
private void AddResultTicket(RectTransform parent, string objectName, Sprite iconSprite, string label, string value, Vector2 topLeftPosition) {
|
||||
AddResultImage(parent, "Result " + objectName + " Icon", iconSprite, topLeftPosition + new Vector2(28f, -40f), new Vector2(40f, 40f), true, Color.white);
|
||||
AddResultText(parent, "Result " + objectName + " Label", label, topLeftPosition + new Vector2(56f, -19f), new Vector2(94f, 18f), 13f, FontStyles.Bold, new Color(0.43f, 0.58f, 0.64f, 0.96f), TextAlignmentOptions.MidlineLeft);
|
||||
AddResultText(parent, "Result " + objectName + " Value", value, topLeftPosition + new Vector2(56f, -42f), new Vector2(112f, 26f), 12f, FontStyles.Bold, new Color(0.05f, 0.18f, 0.27f, 1f), TextAlignmentOptions.MidlineLeft);
|
||||
}
|
||||
|
||||
private void AddResultActionButton(string label, UnityEngine.Events.UnityAction action, Vector2 position, Vector2 size, bool primary, Sprite iconSprite) {
|
||||
GameObject buttonObject = CreateUiObject("Result Button " + label, overlayRoot, typeof(Image), typeof(Button));
|
||||
RectTransform buttonRect = buttonObject.GetComponent<RectTransform>();
|
||||
buttonRect.anchorMin = new Vector2(0.5f, 0.5f);
|
||||
buttonRect.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
buttonRect.pivot = new Vector2(0.5f, 0.5f);
|
||||
buttonRect.anchoredPosition = position;
|
||||
buttonRect.sizeDelta = size;
|
||||
|
||||
Image buttonImage = buttonObject.GetComponent<Image>();
|
||||
buttonImage.sprite = LoadUiSprite(ResultButtonResourcePath, ResultButtonAssetPath);
|
||||
buttonImage.color = buttonImage.sprite != null
|
||||
? (primary ? Color.white : new Color(0.86f, 0.94f, 1f, 0.94f))
|
||||
: primary
|
||||
? new Color(1f, 0.82f, 0.28f, 0.98f)
|
||||
: new Color(0.82f, 0.91f, 0.96f, 0.90f);
|
||||
buttonImage.preserveAspect = false;
|
||||
buttonImage.raycastTarget = true;
|
||||
|
||||
Button button = buttonObject.GetComponent<Button>();
|
||||
button.onClick.AddListener(action);
|
||||
|
||||
if(iconSprite != null)
|
||||
{
|
||||
AddResultImage(buttonRect, "Result Button Icon", iconSprite, new Vector2(34f, -(size.y * 0.5f)), new Vector2(24f, 24f), true, Color.white);
|
||||
}
|
||||
|
||||
TextMeshProUGUI buttonText = AddResultText(buttonRect, "Result Button Label", label, new Vector2(iconSprite != null ? 54f : 0f, -1f), new Vector2(iconSprite != null ? size.x - 70f : size.x, size.y), 16f, FontStyles.Bold, new Color(0.94f, 0.99f, 1f, 1f), TextAlignmentOptions.Center);
|
||||
RectTransform textRect = buttonText.rectTransform;
|
||||
textRect.anchorMin = new Vector2(0f, 0.5f);
|
||||
textRect.anchorMax = new Vector2(0f, 0.5f);
|
||||
textRect.pivot = new Vector2(0f, 0.5f);
|
||||
buttonText.outlineColor = new Color(0f, 0.04f, 0.07f, 0.98f);
|
||||
buttonText.outlineWidth = 0.12f;
|
||||
}
|
||||
|
||||
private Image AddResultImage(RectTransform parent, string objectName, Sprite sprite, Vector2 position, Vector2 size, bool preserveAspect, Color color) {
|
||||
GameObject imageObject = CreateUiObject(objectName, parent, typeof(Image));
|
||||
RectTransform imageRect = imageObject.GetComponent<RectTransform>();
|
||||
imageRect.anchorMin = new Vector2(0f, 1f);
|
||||
imageRect.anchorMax = new Vector2(0f, 1f);
|
||||
imageRect.pivot = new Vector2(0.5f, 0.5f);
|
||||
imageRect.anchoredPosition = position;
|
||||
imageRect.sizeDelta = size;
|
||||
|
||||
Image image = imageObject.GetComponent<Image>();
|
||||
image.sprite = sprite;
|
||||
image.color = sprite != null ? color : new Color(0.30f, 0.46f, 0.54f, 0.28f);
|
||||
image.preserveAspect = preserveAspect;
|
||||
image.raycastTarget = false;
|
||||
return image;
|
||||
}
|
||||
|
||||
private TextMeshProUGUI AddResultText(RectTransform parent, string objectName, string text, Vector2 position, Vector2 size, float fontSize, FontStyles fontStyle, Color color, TextAlignmentOptions alignment) {
|
||||
GameObject textObject = CreateUiObject(objectName, parent);
|
||||
RectTransform textRect = textObject.GetComponent<RectTransform>();
|
||||
textRect.anchorMin = new Vector2(0f, 1f);
|
||||
textRect.anchorMax = new Vector2(0f, 1f);
|
||||
textRect.pivot = new Vector2(0f, 1f);
|
||||
textRect.anchoredPosition = position;
|
||||
textRect.sizeDelta = size;
|
||||
|
||||
TextMeshProUGUI textComponent = textObject.AddComponent<TextMeshProUGUI>();
|
||||
textComponent.text = text;
|
||||
textComponent.font = runtimeFont != null ? runtimeFont : textComponent.font;
|
||||
textComponent.fontSize = fontSize;
|
||||
textComponent.fontStyle = fontStyle;
|
||||
textComponent.alignment = alignment;
|
||||
textComponent.color = color;
|
||||
textComponent.raycastTarget = false;
|
||||
textComponent.textWrappingMode = TextWrappingModes.Normal;
|
||||
textComponent.overflowMode = TextOverflowModes.Ellipsis;
|
||||
textComponent.enableAutoSizing = true;
|
||||
textComponent.fontSizeMin = Mathf.Max(8f, fontSize * 0.66f);
|
||||
textComponent.fontSizeMax = fontSize;
|
||||
return textComponent;
|
||||
}
|
||||
|
||||
private string GetResultDestinationName(MapDefinition resultMap) {
|
||||
if(resultMap == null)
|
||||
{
|
||||
return "여행지";
|
||||
}
|
||||
|
||||
switch(resultMap.mapId)
|
||||
{
|
||||
case MapId.TutorialIncheon:
|
||||
return "인천공항";
|
||||
case MapId.Japan:
|
||||
return "일본";
|
||||
case MapId.China:
|
||||
return "중국";
|
||||
case MapId.America:
|
||||
return "미국";
|
||||
default:
|
||||
return resultMap.displayName;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetResultSouvenirName(MapDefinition resultMap) {
|
||||
if(resultMap == null)
|
||||
{
|
||||
return "여행 도장";
|
||||
}
|
||||
|
||||
switch(resultMap.mapId)
|
||||
{
|
||||
case MapId.TutorialIncheon:
|
||||
return "공항 마그넷";
|
||||
case MapId.Japan:
|
||||
return "일본 마그넷";
|
||||
case MapId.China:
|
||||
return "여행 부적";
|
||||
case MapId.America:
|
||||
return "스카이라인";
|
||||
default:
|
||||
return "여행 도장";
|
||||
}
|
||||
}
|
||||
|
||||
private Sprite GetResultSouvenirSprite(MapDefinition resultMap) {
|
||||
if(resultMap == null)
|
||||
{
|
||||
return LoadUiSprite("", SouvenirCollectionIconAssetPath);
|
||||
}
|
||||
|
||||
switch(resultMap.mapId)
|
||||
{
|
||||
case MapId.TutorialIncheon:
|
||||
return LoadUiSprite("", AirportSouvenirAssetPath);
|
||||
case MapId.Japan:
|
||||
return LoadUiSprite("", JapanSouvenirAssetPath);
|
||||
case MapId.China:
|
||||
return LoadUiSprite("", ChinaSouvenirAssetPath);
|
||||
case MapId.America:
|
||||
return LoadUiSprite("", AmericaSouvenirAssetPath);
|
||||
default:
|
||||
return LoadUiSprite("", SouvenirCollectionIconAssetPath);
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowDutyFreeShop() {
|
||||
@@ -313,20 +733,166 @@ public class GameFlowManager : MonoBehaviour {
|
||||
EnsureOverlay();
|
||||
ClearOverlay();
|
||||
SetOverlayVisible(true);
|
||||
SetDefaultOverlayBackground();
|
||||
|
||||
AddTitle("면세점");
|
||||
AddBody("보유 마일리지: " + saveData.totalMileage
|
||||
+ "\n도시락: " + saveData.lunchboxStock
|
||||
+ " / 방어막: " + saveData.shieldStock
|
||||
+ "\n운동화: " + saveData.speedShoesStock
|
||||
+ " / 마일리지 카드: " + saveData.mileageCardStock);
|
||||
BuildDutyFreeShopScreen();
|
||||
}
|
||||
|
||||
AddButton("도시락 구매 " + LunchboxCost, BuyLunchbox);
|
||||
AddButton("방어막 구매 " + ShieldCost, BuyShield);
|
||||
AddButton("운동화 구매 " + SpeedShoesCost, BuySpeedShoes);
|
||||
AddButton("마일리지 카드 구매 " + MileageCardCost, BuyMileageCard);
|
||||
AddButton("다음 맵 보기", ShowMapPreview);
|
||||
private void BuildDutyFreeShopScreen() {
|
||||
ApplyDutyFreeShopBackground();
|
||||
|
||||
RectTransform boardRect = AddDutyFreeBoard();
|
||||
AddDutyFreeHeader(boardRect);
|
||||
|
||||
AddDutyFreeItemCard(
|
||||
boardRect,
|
||||
"도시락",
|
||||
"HP 회복",
|
||||
LunchboxCost,
|
||||
saveData.lunchboxStock,
|
||||
LoadUiSprite("", DutyFreeLunchboxAssetPath),
|
||||
BuyLunchbox,
|
||||
new Vector2(58f, -130f));
|
||||
|
||||
AddDutyFreeItemCard(
|
||||
boardRect,
|
||||
"방어막",
|
||||
"1회 방어",
|
||||
ShieldCost,
|
||||
saveData.shieldStock,
|
||||
LoadUiSprite("", DutyFreeShieldAssetPath),
|
||||
BuyShield,
|
||||
new Vector2(296f, -130f));
|
||||
|
||||
AddDutyFreeItemCard(
|
||||
boardRect,
|
||||
"운동화",
|
||||
"속도 회복",
|
||||
SpeedShoesCost,
|
||||
saveData.speedShoesStock,
|
||||
LoadUiSprite("", DutyFreeShoesAssetPath),
|
||||
BuySpeedShoes,
|
||||
new Vector2(534f, -130f));
|
||||
|
||||
AddDutyFreeItemCard(
|
||||
boardRect,
|
||||
"마일리지 카드",
|
||||
"획득량 증가",
|
||||
MileageCardCost,
|
||||
saveData.mileageCardStock,
|
||||
LoadUiSprite("", DutyFreeMileageCardAssetPath),
|
||||
BuyMileageCard,
|
||||
new Vector2(772f, -130f));
|
||||
|
||||
AddResultActionButton("다음 여행지 가기", ShowMapPreview, new Vector2(0f, -292f), new Vector2(292f, 48f), false, LoadUiSprite("", AirplaneTravelIconAssetPath));
|
||||
}
|
||||
|
||||
private void ApplyDutyFreeShopBackground() {
|
||||
if(overlayBackground != null)
|
||||
{
|
||||
overlayBackground.sprite = LoadUiSprite("", DutyFreeBackgroundAssetPath);
|
||||
overlayBackground.preserveAspect = false;
|
||||
overlayBackground.color = overlayBackground.sprite != null
|
||||
? Color.white
|
||||
: new Color(0.03f, 0.035f, 0.038f, 0.96f);
|
||||
}
|
||||
|
||||
if(flowCamera != null)
|
||||
{
|
||||
flowCamera.backgroundColor = new Color(0.03f, 0.035f, 0.038f, 1f);
|
||||
}
|
||||
|
||||
GameObject scrimObject = CreateUiObject("Duty Free Background Scrim", overlayRoot, typeof(Image));
|
||||
RectTransform scrimRect = scrimObject.GetComponent<RectTransform>();
|
||||
scrimRect.anchorMin = Vector2.zero;
|
||||
scrimRect.anchorMax = Vector2.one;
|
||||
scrimRect.offsetMin = Vector2.zero;
|
||||
scrimRect.offsetMax = Vector2.zero;
|
||||
|
||||
Image scrimImage = scrimObject.GetComponent<Image>();
|
||||
scrimImage.color = new Color(0.01f, 0.012f, 0.014f, 0.34f);
|
||||
scrimImage.raycastTarget = false;
|
||||
}
|
||||
|
||||
private RectTransform AddDutyFreeBoard() {
|
||||
GameObject boardObject = CreateUiObject("Duty Free Product Board", overlayRoot, typeof(Image));
|
||||
RectTransform boardRect = boardObject.GetComponent<RectTransform>();
|
||||
boardRect.anchorMin = new Vector2(0.5f, 0.5f);
|
||||
boardRect.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
boardRect.pivot = new Vector2(0.5f, 0.5f);
|
||||
boardRect.anchoredPosition = new Vector2(0f, 28f);
|
||||
boardRect.sizeDelta = new Vector2(1038f, 462f);
|
||||
|
||||
Image boardImage = boardObject.GetComponent<Image>();
|
||||
boardImage.color = new Color(0.015f, 0.055f, 0.085f, 0.84f);
|
||||
boardImage.raycastTarget = false;
|
||||
|
||||
return boardRect;
|
||||
}
|
||||
|
||||
private void AddDutyFreeHeader(RectTransform parent) {
|
||||
AddResultImage(parent, "Duty Free Header Icon", LoadUiSprite("", DutyFreeIconAssetPath), new Vector2(84f, -60f), new Vector2(48f, 48f), true, Color.white);
|
||||
AddResultText(parent, "Duty Free Title", "면세점", new Vector2(120f, -38f), new Vector2(180f, 46f), 32f, FontStyles.Bold, new Color(0.96f, 0.99f, 1f, 1f), TextAlignmentOptions.MidlineLeft);
|
||||
AddResultText(parent, "Duty Free Subtitle", "다음 여행 준비", new Vector2(122f, -82f), new Vector2(220f, 24f), 15f, FontStyles.Bold, new Color(0.64f, 0.82f, 0.92f, 0.96f), TextAlignmentOptions.MidlineLeft);
|
||||
|
||||
AddResultImage(parent, "Duty Free Mileage Icon", LoadUiSprite("", MileageIconAssetPath), new Vector2(760f, -61f), new Vector2(42f, 42f), true, Color.white);
|
||||
AddResultText(parent, "Duty Free Mileage Label", "보유 마일리지", new Vector2(794f, -43f), new Vector2(140f, 22f), 13f, FontStyles.Bold, new Color(0.64f, 0.82f, 0.92f, 0.96f), TextAlignmentOptions.MidlineLeft);
|
||||
AddResultText(parent, "Duty Free Mileage Value", saveData.totalMileage + " M", new Vector2(794f, -66f), new Vector2(160f, 32f), 24f, FontStyles.Bold, new Color(1f, 0.90f, 0.38f, 1f), TextAlignmentOptions.MidlineLeft);
|
||||
}
|
||||
|
||||
private void AddDutyFreeItemCard(RectTransform parent, string itemName, string effectText, int cost, int stock, Sprite itemSprite, UnityEngine.Events.UnityAction buyAction, Vector2 topLeftPosition) {
|
||||
bool canBuy = saveData.totalMileage >= cost;
|
||||
GameObject cardObject = CreateUiObject("Duty Free Item " + itemName, parent, typeof(Image), typeof(Button));
|
||||
RectTransform cardRect = cardObject.GetComponent<RectTransform>();
|
||||
cardRect.anchorMin = new Vector2(0f, 1f);
|
||||
cardRect.anchorMax = new Vector2(0f, 1f);
|
||||
cardRect.pivot = new Vector2(0f, 1f);
|
||||
cardRect.anchoredPosition = topLeftPosition;
|
||||
cardRect.sizeDelta = new Vector2(206f, 242f);
|
||||
|
||||
Image cardImage = cardObject.GetComponent<Image>();
|
||||
cardImage.color = canBuy
|
||||
? new Color(0.97f, 0.91f, 0.78f, 0.96f)
|
||||
: new Color(0.40f, 0.45f, 0.48f, 0.88f);
|
||||
cardImage.raycastTarget = true;
|
||||
|
||||
Button button = cardObject.GetComponent<Button>();
|
||||
button.targetGraphic = cardImage;
|
||||
button.interactable = canBuy;
|
||||
button.onClick.AddListener(buyAction);
|
||||
button.navigation = new Navigation {
|
||||
mode = Navigation.Mode.None
|
||||
};
|
||||
|
||||
Color textColor = canBuy
|
||||
? new Color(0.06f, 0.16f, 0.22f, 1f)
|
||||
: new Color(0.78f, 0.84f, 0.86f, 1f);
|
||||
Color subColor = canBuy
|
||||
? new Color(0.34f, 0.49f, 0.54f, 0.98f)
|
||||
: new Color(0.66f, 0.72f, 0.74f, 0.98f);
|
||||
|
||||
AddResultImage(cardRect, "Duty Free " + itemName + " Image", itemSprite, new Vector2(103f, -70f), new Vector2(100f, 88f), true, canBuy ? Color.white : new Color(1f, 1f, 1f, 0.54f));
|
||||
AddResultText(cardRect, "Duty Free " + itemName + " Name", itemName, new Vector2(16f, -116f), new Vector2(174f, 28f), 20f, FontStyles.Bold, textColor, TextAlignmentOptions.Center);
|
||||
AddResultText(cardRect, "Duty Free " + itemName + " Effect", effectText, new Vector2(16f, -146f), new Vector2(174f, 22f), 13f, FontStyles.Bold, subColor, TextAlignmentOptions.Center);
|
||||
AddResultText(cardRect, "Duty Free " + itemName + " Stock", "보유 " + stock, new Vector2(20f, -174f), new Vector2(72f, 22f), 13f, FontStyles.Bold, subColor, TextAlignmentOptions.MidlineLeft);
|
||||
AddResultText(cardRect, "Duty Free " + itemName + " Cost", cost + " M", new Vector2(102f, -174f), new Vector2(84f, 22f), 15f, FontStyles.Bold, new Color(0.87f, 0.55f, 0.08f, 1f), TextAlignmentOptions.MidlineRight);
|
||||
|
||||
GameObject stripObject = CreateUiObject("Duty Free " + itemName + " Buy Strip", cardRect, typeof(Image));
|
||||
RectTransform stripRect = stripObject.GetComponent<RectTransform>();
|
||||
stripRect.anchorMin = new Vector2(0.5f, 0f);
|
||||
stripRect.anchorMax = new Vector2(0.5f, 0f);
|
||||
stripRect.pivot = new Vector2(0.5f, 0f);
|
||||
stripRect.anchoredPosition = new Vector2(0f, 14f);
|
||||
stripRect.sizeDelta = new Vector2(160f, 34f);
|
||||
|
||||
Image stripImage = stripObject.GetComponent<Image>();
|
||||
stripImage.sprite = LoadUiSprite(ResultButtonResourcePath, ResultButtonAssetPath);
|
||||
stripImage.color = canBuy ? Color.white : new Color(0.60f, 0.65f, 0.68f, 0.88f);
|
||||
stripImage.preserveAspect = false;
|
||||
stripImage.raycastTarget = false;
|
||||
|
||||
TextMeshProUGUI stripText = AddResultText(cardRect, "Duty Free " + itemName + " Buy Label", canBuy ? "구매" : "마일리지 부족", new Vector2(23f, -200f), new Vector2(160f, 32f), 14f, FontStyles.Bold, new Color(0.94f, 0.99f, 1f, 1f), TextAlignmentOptions.Center);
|
||||
stripText.outlineColor = new Color(0f, 0.04f, 0.07f, 0.98f);
|
||||
stripText.outlineWidth = 0.12f;
|
||||
}
|
||||
|
||||
private void ShowMapPreview() {
|
||||
@@ -384,6 +950,11 @@ public class GameFlowManager : MonoBehaviour {
|
||||
case FlowScreen.OpeningStory:
|
||||
ShowOpeningStory();
|
||||
break;
|
||||
#if UNITY_EDITOR || DEVELOPMENT_BUILD
|
||||
case FlowScreen.DebugMenu:
|
||||
ShowDebugMenu();
|
||||
break;
|
||||
#endif
|
||||
case FlowScreen.Intro:
|
||||
default:
|
||||
ShowIntro();
|
||||
@@ -474,6 +1045,7 @@ public class GameFlowManager : MonoBehaviour {
|
||||
|
||||
private void EnsureOverlay() {
|
||||
EnsureEventSystem();
|
||||
EnsureFlowCamera();
|
||||
|
||||
if(overlayCanvas != null)
|
||||
{
|
||||
@@ -487,6 +1059,7 @@ public class GameFlowManager : MonoBehaviour {
|
||||
overlayCanvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
overlayCanvas.worldCamera = null;
|
||||
overlayCanvas.sortingOrder = 100;
|
||||
overlayCanvas.targetDisplay = 0;
|
||||
SetUiLayer(canvasObject);
|
||||
|
||||
CanvasScaler scaler = canvasObject.GetComponent<CanvasScaler>();
|
||||
@@ -515,6 +1088,8 @@ public class GameFlowManager : MonoBehaviour {
|
||||
private void SetDefaultOverlayBackground() {
|
||||
if(overlayBackground != null)
|
||||
{
|
||||
overlayBackground.sprite = null;
|
||||
overlayBackground.preserveAspect = false;
|
||||
overlayBackground.color = new Color(0.02f, 0.035f, 0.045f, 0.92f);
|
||||
}
|
||||
|
||||
@@ -527,6 +1102,8 @@ public class GameFlowManager : MonoBehaviour {
|
||||
private void BuildIntroScreen() {
|
||||
if(overlayBackground != null)
|
||||
{
|
||||
overlayBackground.sprite = null;
|
||||
overlayBackground.preserveAspect = false;
|
||||
overlayBackground.color = Color.clear;
|
||||
}
|
||||
|
||||
@@ -547,6 +1124,8 @@ public class GameFlowManager : MonoBehaviour {
|
||||
private void BuildOpeningStoryScreen() {
|
||||
if(overlayBackground != null)
|
||||
{
|
||||
overlayBackground.sprite = null;
|
||||
overlayBackground.preserveAspect = false;
|
||||
overlayBackground.color = new Color(0.012f, 0.018f, 0.024f, 0.96f);
|
||||
}
|
||||
|
||||
@@ -976,9 +1555,9 @@ public class GameFlowManager : MonoBehaviour {
|
||||
stampRect.localRotation = Quaternion.Euler(0f, 0f, -12f);
|
||||
|
||||
Image stampImage = stampObject.GetComponent<Image>();
|
||||
stampImage.sprite = LoadUiSpriteRegion("Assets/ConceptArt/Intro/intro_stamps_01.png", new Rect(54f, 48f, 790f, 790f));
|
||||
stampImage.sprite = LoadUiSprite(DepartureStampResourcePath, "Assets/Resources/UI_DepartureStamp_Red.png");
|
||||
stampImage.color = stampImage.sprite != null
|
||||
? new Color(1f, 1f, 1f, 0.94f)
|
||||
? new Color(1f, 1f, 1f, 0.96f)
|
||||
: new Color(0.76f, 0.08f, 0.06f, 0.96f);
|
||||
stampImage.preserveAspect = true;
|
||||
stampImage.raycastTarget = false;
|
||||
@@ -1274,6 +1853,8 @@ public class GameFlowManager : MonoBehaviour {
|
||||
private void EnsureFlowCamera() {
|
||||
if(flowCamera != null)
|
||||
{
|
||||
flowCamera.enabled = true;
|
||||
flowCamera.targetDisplay = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1288,6 +1869,7 @@ public class GameFlowManager : MonoBehaviour {
|
||||
flowCamera.depth = 100f;
|
||||
flowCamera.orthographic = true;
|
||||
flowCamera.orthographicSize = 360f;
|
||||
flowCamera.targetDisplay = 0;
|
||||
}
|
||||
|
||||
private void ClearOverlay() {
|
||||
@@ -1303,6 +1885,11 @@ public class GameFlowManager : MonoBehaviour {
|
||||
}
|
||||
|
||||
private void SetOverlayVisible(bool visible) {
|
||||
if(visible)
|
||||
{
|
||||
EnsureFlowCamera();
|
||||
}
|
||||
|
||||
if(overlayCanvas != null)
|
||||
{
|
||||
overlayCanvas.gameObject.SetActive(visible);
|
||||
|
||||
@@ -86,7 +86,7 @@ public class GameManager : MonoBehaviour {
|
||||
private const string TotalMileageKey = "UniRun.TotalMileage";
|
||||
private const string InitialMileageGrantedKey = "UniRun.InitialMileageGranted";
|
||||
private const string CharacterFaceResourcePath = "UI_JJ_PassportPhoto";
|
||||
private const string PassportPanelResourcePath = "UI_LeftHudPassportHorizontalGridPanel";
|
||||
private const string PassportPanelResourcePath = "UI_LeftHudPassportCompactPanel";
|
||||
private const string LifeStampResourcePath = "UI_LifeStamp";
|
||||
private const string PassportItemSlotResourcePath = "UI_PassportItemSlot";
|
||||
private const string TutorialGuideFrameResourcePath = "UI_TutorialAirportMonitorFrame";
|
||||
@@ -95,7 +95,7 @@ public class GameManager : MonoBehaviour {
|
||||
private const string RightHudLuggageLabelJapanResourcePath = "UI_RightHudLuggageLabel_Japan";
|
||||
private const string RightHudLuggageLabelChinaResourcePath = "UI_RightHudLuggageLabel_China";
|
||||
private const string RightHudLuggageLabelAmericaResourcePath = "UI_RightHudLuggageLabel_America";
|
||||
private const float PassportHudWidth = 320f;
|
||||
private const float PassportHudWidth = 261f;
|
||||
private const float PassportHudHeight = 102f;
|
||||
private const float PassportHudScale = 0.5f;
|
||||
private const float RightInfoHudWidth = 260f;
|
||||
@@ -383,7 +383,7 @@ public class GameManager : MonoBehaviour {
|
||||
|
||||
for(int i = 0; i < currentMapDefinition.openingSteps.Length; i++)
|
||||
{
|
||||
PlatformSpawner.TutorialStep step = currentMapDefinition.openingSteps[i];
|
||||
CourseStep step = currentMapDefinition.openingSteps[i];
|
||||
if(step != null
|
||||
&& (step.guideType != TutorialGuideType.None
|
||||
|| !string.IsNullOrEmpty(step.title)
|
||||
@@ -436,7 +436,7 @@ public class GameManager : MonoBehaviour {
|
||||
SetTutorialGuide(TutorialGuideType.Slide, "슬라이드", "오른쪽 클릭을 누르고 있으면 낮게 지나갑니다.");
|
||||
break;
|
||||
case 3:
|
||||
SetTutorialGuide(TutorialGuideType.Items, "아이템", "초밥 -> 라멘 -> 방어막 -> 운동화 -> 마일리지 카드 순서입니다.");
|
||||
SetTutorialGuide(TutorialGuideType.Items, "아이템", "초밥 -> 라멘 -> 방어막 -> 마일리지 카드 -> 운동화 순서입니다.");
|
||||
break;
|
||||
default:
|
||||
tutorialGuideSequenceComplete = true;
|
||||
@@ -795,24 +795,24 @@ public class GameManager : MonoBehaviour {
|
||||
}
|
||||
|
||||
private void UpdateTutorialTextLayout(bool showItemRow, bool showFullText) {
|
||||
Vector2 textPosition = new Vector2(104f, -38f);
|
||||
Vector2 textSize = new Vector2(250f, 20f);
|
||||
Vector2 bodyPosition = new Vector2(104f, -60f);
|
||||
Vector2 bodySize = new Vector2(250f, 38f);
|
||||
Vector2 textPosition = new Vector2(118f, -38f);
|
||||
Vector2 textSize = new Vector2(236f, 20f);
|
||||
Vector2 bodyPosition = new Vector2(118f, -60f);
|
||||
Vector2 bodySize = new Vector2(236f, 38f);
|
||||
|
||||
if(showItemRow)
|
||||
{
|
||||
textPosition = new Vector2(110f, -38f);
|
||||
textSize = new Vector2(242f, 20f);
|
||||
bodyPosition = new Vector2(110f, -60f);
|
||||
bodySize = new Vector2(242f, 38f);
|
||||
textPosition = new Vector2(124f, -38f);
|
||||
textSize = new Vector2(228f, 20f);
|
||||
bodyPosition = new Vector2(124f, -60f);
|
||||
bodySize = new Vector2(228f, 38f);
|
||||
}
|
||||
else if(showFullText)
|
||||
{
|
||||
textPosition = new Vector2(54f, -39f);
|
||||
textSize = new Vector2(284f, 20f);
|
||||
bodyPosition = new Vector2(54f, -61f);
|
||||
bodySize = new Vector2(284f, 39f);
|
||||
textPosition = new Vector2(68f, -39f);
|
||||
textSize = new Vector2(270f, 20f);
|
||||
bodyPosition = new Vector2(68f, -61f);
|
||||
bodySize = new Vector2(270f, 39f);
|
||||
}
|
||||
|
||||
if(tutorialTitleText != null)
|
||||
@@ -1006,7 +1006,7 @@ public class GameManager : MonoBehaviour {
|
||||
frameRect.anchorMin = new Vector2(0f, 1f);
|
||||
frameRect.anchorMax = new Vector2(0f, 1f);
|
||||
frameRect.pivot = new Vector2(0f, 1f);
|
||||
frameRect.anchoredPosition = new Vector2(30f, -20f);
|
||||
frameRect.anchoredPosition = new Vector2(32f, -20f);
|
||||
frameRect.sizeDelta = new Vector2(72f, 68f);
|
||||
|
||||
Image frameImage = faceFrame.GetComponent<Image>();
|
||||
@@ -1045,8 +1045,8 @@ public class GameManager : MonoBehaviour {
|
||||
lifeRect.anchorMin = new Vector2(0f, 1f);
|
||||
lifeRect.anchorMax = new Vector2(0f, 1f);
|
||||
lifeRect.pivot = new Vector2(0f, 1f);
|
||||
lifeRect.anchoredPosition = new Vector2(124f + (i * 44f), -20f);
|
||||
lifeRect.sizeDelta = new Vector2(30f, 30f);
|
||||
lifeRect.anchoredPosition = new Vector2(125f + (i * 45f), -23f);
|
||||
lifeRect.sizeDelta = new Vector2(28f, 28f);
|
||||
|
||||
Image lifeImage = lifeObject.GetComponent<Image>();
|
||||
lifeImage.sprite = lifeSprite;
|
||||
@@ -1071,15 +1071,15 @@ public class GameManager : MonoBehaviour {
|
||||
slotRect.anchorMin = new Vector2(0f, 1f);
|
||||
slotRect.anchorMax = new Vector2(0f, 1f);
|
||||
slotRect.pivot = new Vector2(0f, 1f);
|
||||
slotRect.anchoredPosition = new Vector2(118f + (i * 46f), -66f);
|
||||
slotRect.sizeDelta = new Vector2(40f, 24f);
|
||||
slotRect.anchoredPosition = new Vector2(125f + (i * 45f), -62f);
|
||||
slotRect.sizeDelta = new Vector2(30f, 30f);
|
||||
|
||||
Image slotImage = slotObject.GetComponent<Image>();
|
||||
slotImage.sprite = slotSprite;
|
||||
slotImage.color = slotSprite != null
|
||||
? new Color(1f, 1f, 1f, 0.62f)
|
||||
: new Color(0.92f, 0.97f, 1f, 0.22f);
|
||||
slotImage.preserveAspect = false;
|
||||
slotImage.preserveAspect = true;
|
||||
slotImage.raycastTarget = false;
|
||||
}
|
||||
}
|
||||
@@ -1140,8 +1140,8 @@ public class GameManager : MonoBehaviour {
|
||||
|
||||
CreateTutorialMainImage(tutorialGuideObject.transform);
|
||||
CreateTutorialItemRow(tutorialGuideObject.transform);
|
||||
tutorialTitleText = CreateTutorialText(tutorialGuideObject.transform, "Tutorial Title", new Vector2(104f, -38f), new Vector2(250f, 20f), 12f, FontStyles.Bold);
|
||||
tutorialBodyText = CreateTutorialText(tutorialGuideObject.transform, "Tutorial Body", new Vector2(104f, -60f), new Vector2(250f, 38f), 9f, FontStyles.Normal);
|
||||
tutorialTitleText = CreateTutorialText(tutorialGuideObject.transform, "Tutorial Title", new Vector2(118f, -38f), new Vector2(236f, 20f), 12f, FontStyles.Bold);
|
||||
tutorialBodyText = CreateTutorialText(tutorialGuideObject.transform, "Tutorial Body", new Vector2(118f, -60f), new Vector2(236f, 38f), 9f, FontStyles.Normal);
|
||||
tutorialTitleText.color = new Color(0.06f, 0.13f, 0.19f, 0.98f);
|
||||
tutorialBodyText.color = new Color(0.10f, 0.18f, 0.23f, 0.95f);
|
||||
CreateTutorialNextButton(tutorialGuideObject.transform);
|
||||
@@ -1170,16 +1170,18 @@ public class GameManager : MonoBehaviour {
|
||||
multiplierRect.anchorMin = new Vector2(1f, 0f);
|
||||
multiplierRect.anchorMax = new Vector2(1f, 0f);
|
||||
multiplierRect.pivot = new Vector2(1f, 0f);
|
||||
multiplierRect.anchoredPosition = new Vector2(-2f, 1f);
|
||||
multiplierRect.sizeDelta = new Vector2(22f, 15f);
|
||||
multiplierRect.anchoredPosition = new Vector2(8f, -4f);
|
||||
multiplierRect.sizeDelta = new Vector2(42f, 28f);
|
||||
|
||||
tutorialMultiplierText = multiplierObject.AddComponent<TextMeshProUGUI>();
|
||||
tutorialMultiplierText.font = scoreText.font;
|
||||
tutorialMultiplierText.text = "x2";
|
||||
tutorialMultiplierText.text = "X2";
|
||||
tutorialMultiplierText.alignment = TextAlignmentOptions.Center;
|
||||
tutorialMultiplierText.fontSize = 9f;
|
||||
tutorialMultiplierText.fontSize = 17f;
|
||||
tutorialMultiplierText.fontStyle = FontStyles.Bold;
|
||||
tutorialMultiplierText.color = new Color(1f, 0.91f, 0.33f, 1f);
|
||||
tutorialMultiplierText.outlineColor = new Color(0.05f, 0.05f, 0.06f, 0.95f);
|
||||
tutorialMultiplierText.outlineWidth = 0.18f;
|
||||
tutorialMultiplierText.raycastTarget = false;
|
||||
tutorialMultiplierText.textWrappingMode = TextWrappingModes.NoWrap;
|
||||
tutorialMultiplierText.gameObject.SetActive(false);
|
||||
@@ -1326,7 +1328,7 @@ public class GameManager : MonoBehaviour {
|
||||
|
||||
if(guideType == TutorialGuideType.Slide)
|
||||
{
|
||||
return LoadTutorialSprite("Assets/Sprites/JJ_Slide.png", "JJ_Slide_0");
|
||||
return LoadTutorialSprite("Assets/Sprites/JJ_Slide.png", "JJ_Slide_2");
|
||||
}
|
||||
|
||||
if(guideType == TutorialGuideType.Damage)
|
||||
@@ -1519,7 +1521,7 @@ public class GameManager : MonoBehaviour {
|
||||
float cursor = 0f;
|
||||
AddStepMarkers(mapDefinition.openingSteps, ref cursor, targetDistance);
|
||||
|
||||
PlatformSpawner.TutorialStep[] loopSteps = mapDefinition.loopSteps;
|
||||
CourseStep[] loopSteps = mapDefinition.loopSteps;
|
||||
int loopGuard = 0;
|
||||
while(cursor < targetDistance
|
||||
&& loopSteps != null
|
||||
@@ -1532,7 +1534,7 @@ public class GameManager : MonoBehaviour {
|
||||
}
|
||||
}
|
||||
|
||||
private void AddStepMarkers(PlatformSpawner.TutorialStep[] steps, ref float cursor, float targetDistance) {
|
||||
private void AddStepMarkers(CourseStep[] steps, ref float cursor, float targetDistance) {
|
||||
if(steps == null)
|
||||
{
|
||||
return;
|
||||
@@ -1540,7 +1542,7 @@ public class GameManager : MonoBehaviour {
|
||||
|
||||
for(int i = 0; i < steps.Length; i++)
|
||||
{
|
||||
PlatformSpawner.TutorialStep step = steps[i];
|
||||
CourseStep step = steps[i];
|
||||
float stepDistance = GetStepDistance(step);
|
||||
|
||||
if(markerObjects.Count < MaxCourseObjectCount)
|
||||
@@ -1564,7 +1566,7 @@ public class GameManager : MonoBehaviour {
|
||||
}
|
||||
}
|
||||
|
||||
private float GetStepDistance(PlatformSpawner.TutorialStep step) {
|
||||
private float GetStepDistance(CourseStep step) {
|
||||
if(step == null)
|
||||
{
|
||||
return CourseDistancePerInterval;
|
||||
@@ -1573,7 +1575,7 @@ public class GameManager : MonoBehaviour {
|
||||
return Mathf.Max(0.3f, step.spawnInterval) * CourseDistancePerInterval;
|
||||
}
|
||||
|
||||
private bool TryGetMarkerInfo(PlatformSpawner.TutorialStep step, out MarkerInfo markerInfo) {
|
||||
private bool TryGetMarkerInfo(CourseStep step, out MarkerInfo markerInfo) {
|
||||
markerInfo = new MarkerInfo();
|
||||
|
||||
if(step == null)
|
||||
@@ -1589,7 +1591,7 @@ public class GameManager : MonoBehaviour {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(step.coursePlatformType == PlatformSpawner.CoursePlatformType.ForceHit
|
||||
if(step.coursePlatformType == CoursePlatformType.ForceHit
|
||||
|| step.platformPattern == Platform.PlatformPattern.ForceHit)
|
||||
{
|
||||
markerInfo.label = "!";
|
||||
@@ -1606,7 +1608,7 @@ public class GameManager : MonoBehaviour {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(step.coursePlatformType == PlatformSpawner.CoursePlatformType.Slide
|
||||
if(step.coursePlatformType == CoursePlatformType.Slide
|
||||
|| step.platformPattern == Platform.PlatformPattern.Slide)
|
||||
{
|
||||
markerInfo.label = "S";
|
||||
@@ -1615,7 +1617,7 @@ public class GameManager : MonoBehaviour {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(step.coursePlatformType == PlatformSpawner.CoursePlatformType.Jump
|
||||
if(step.coursePlatformType == CoursePlatformType.Jump
|
||||
|| step.platformPattern == Platform.PlatformPattern.LowLeft
|
||||
|| step.platformPattern == Platform.PlatformPattern.LowMid
|
||||
|| step.platformPattern == Platform.PlatformPattern.LowRight)
|
||||
@@ -1652,7 +1654,7 @@ public class GameManager : MonoBehaviour {
|
||||
markerObjects.Add(platformImage.gameObject);
|
||||
}
|
||||
|
||||
private Color GetPlatformColor(PlatformSpawner.TutorialStep step) {
|
||||
private Color GetPlatformColor(CourseStep step) {
|
||||
if(step != null && step.spawnInterval >= 1.4f)
|
||||
{
|
||||
return new Color(0.28f, 0.50f, 0.57f, 0.96f);
|
||||
@@ -1671,7 +1673,6 @@ public class GameManager : MonoBehaviour {
|
||||
if(markerInfo.kind == "ForceHit")
|
||||
{
|
||||
CreateJumpFeature(progress, markerInfo);
|
||||
CreateSlideFeature(progress, markerInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b33ec3906e4a4b9d90e671da7a8a31a3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,38 @@
|
||||
using static CourseStepFactory;
|
||||
|
||||
public static class AmericaMap {
|
||||
public static MapDefinition Create() {
|
||||
return new MapDefinition {
|
||||
mapId = MapId.America,
|
||||
displayName = "America",
|
||||
routeName = "뉴욕 자유의 여신상",
|
||||
isTutorial = false,
|
||||
platformSkin = Platform.PlatformSkin.USA,
|
||||
backgroundResourcePath = "Map_America_NewYork",
|
||||
finishGateStyle = FinishGateStyle.AmericaLiberty,
|
||||
targetDistance = 1700f,
|
||||
timeLimit = 125f,
|
||||
clearMileageReward = 500,
|
||||
hasNextMap = false,
|
||||
nextMapId = MapId.America,
|
||||
openingSteps = new CourseStep[] {
|
||||
Basic(),
|
||||
Basic()
|
||||
},
|
||||
loopSteps = new CourseStep[] {
|
||||
Basic(),
|
||||
Jump(Platform.PlatformPattern.LowMid),
|
||||
Basic(GroundY, 0.86f),
|
||||
Slide(SlideObstaclePattern.SlideLayout.WidePair),
|
||||
Basic(),
|
||||
Aerial(AerialY + 0.2f, 1.0f),
|
||||
Basic(GroundY, 0.86f),
|
||||
Jump(Platform.PlatformPattern.LowLeft),
|
||||
Basic(),
|
||||
Slide(SlideObstaclePattern.SlideLayout.CenterPair),
|
||||
Basic(),
|
||||
Jump(Platform.PlatformPattern.LowRight)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4aebf219fb334943a89524de85c8977f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
using static CourseStepFactory;
|
||||
|
||||
public static class ChinaMap {
|
||||
public static MapDefinition Create() {
|
||||
return new MapDefinition {
|
||||
mapId = MapId.China,
|
||||
displayName = "China",
|
||||
routeName = "베이징 시장길",
|
||||
isTutorial = false,
|
||||
platformSkin = Platform.PlatformSkin.China,
|
||||
backgroundResourcePath = "",
|
||||
finishGateStyle = FinishGateStyle.ChinaPaifang,
|
||||
targetDistance = 1450f,
|
||||
timeLimit = 115f,
|
||||
clearMileageReward = 350,
|
||||
hasNextMap = true,
|
||||
nextMapId = MapId.America,
|
||||
openingSteps = new CourseStep[] {
|
||||
Basic(),
|
||||
Basic()
|
||||
},
|
||||
loopSteps = new CourseStep[] {
|
||||
Basic(),
|
||||
Jump(Platform.PlatformPattern.LowRight),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Slide(SlideObstaclePattern.SlideLayout.LeftPair),
|
||||
Basic(),
|
||||
Aerial(AerialY + 0.15f, 1.08f),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Jump(),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Slide(SlideObstaclePattern.SlideLayout.RightPair)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5fa98f4232774d458c65e430f1bd1f99
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,35 @@
|
||||
using static CourseStepFactory;
|
||||
|
||||
public static class JapanMap {
|
||||
public static MapDefinition Create() {
|
||||
return new MapDefinition {
|
||||
mapId = MapId.Japan,
|
||||
displayName = "Japan",
|
||||
routeName = "후쿠오카 라멘 투어",
|
||||
isTutorial = false,
|
||||
platformSkin = Platform.PlatformSkin.Japan,
|
||||
backgroundResourcePath = "",
|
||||
finishGateStyle = FinishGateStyle.JapanTorii,
|
||||
targetDistance = 1200f,
|
||||
timeLimit = 105f,
|
||||
clearMileageReward = 250,
|
||||
hasNextMap = true,
|
||||
nextMapId = MapId.China,
|
||||
openingSteps = new CourseStep[] {
|
||||
Basic(),
|
||||
Basic()
|
||||
},
|
||||
loopSteps = new CourseStep[] {
|
||||
Basic(),
|
||||
Jump(),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Aerial(),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Slide(SlideObstaclePattern.SlideLayout.CenterPair),
|
||||
Basic(),
|
||||
Jump(Platform.PlatformPattern.LowLeft),
|
||||
Basic()
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8fb126c4369f4ff7a83eaad31e6e581e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,56 @@
|
||||
using static CourseStepFactory;
|
||||
|
||||
public static class TutorialIncheonMap {
|
||||
public static MapDefinition Create() {
|
||||
return new MapDefinition {
|
||||
mapId = MapId.TutorialIncheon,
|
||||
displayName = "Tutorial / Incheon",
|
||||
routeName = "인천공항 출발 준비",
|
||||
isTutorial = true,
|
||||
platformSkin = Platform.PlatformSkin.Airport,
|
||||
backgroundResourcePath = "Map_Tutorial_Incheon_Airport",
|
||||
finishGateStyle = FinishGateStyle.AirportDeparture,
|
||||
targetDistance = 380f,
|
||||
timeLimit = 85f,
|
||||
clearMileageReward = 150,
|
||||
hasNextMap = true,
|
||||
nextMapId = MapId.Japan,
|
||||
openingSteps = new CourseStep[] {
|
||||
Basic(),
|
||||
Basic(),
|
||||
Basic(GroundY, BasicSpacing),
|
||||
Jump(GameManager.TutorialGuideType.Jump, "점프 구간", "가방 장애물이 오면 왼쪽 클릭으로 뛰어넘습니다."),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Basic(GroundY, BasicSpacing),
|
||||
Aerial(GameManager.TutorialGuideType.DoubleJump, "2단 점프 구간", "다음 발판이 멀리 떨어져 있습니다.\n공중에서 왼쪽 클릭을 한 번 더 누릅니다."),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Basic(GroundY, BasicSpacing),
|
||||
Slide(GameManager.TutorialGuideType.Slide, "슬라이드 구간", "천장 장애물이 오면 오른쪽 클릭을 누르고 지나갑니다."),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Basic(GroundY, BasicSpacing),
|
||||
ForceHit(GameManager.TutorialGuideType.None, "", ""),
|
||||
Basic(GroundY, LandingSpacing, Platform.MileagePattern.None, GameManager.TutorialGuideType.Items, "초밥", "잃은 목숨을 1 회복합니다.\n방금 줄어든 목숨을 채워 봅니다.", Platform.ItemPattern.HealthSushi),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Basic(GroundY, BasicSpacing, Platform.MileagePattern.None, GameManager.TutorialGuideType.Items, "라멘", "잠깐 무적이 됩니다.\n먹은 뒤 다음 장애물에 일부러 부딪혀 봅니다.", Platform.ItemPattern.InvincibleRamen),
|
||||
ForceHit(GameManager.TutorialGuideType.None, "", ""),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Basic(GroundY, BasicSpacing),
|
||||
Basic(GroundY, BasicSpacing),
|
||||
Basic(GroundY, BasicSpacing, Platform.MileagePattern.None, GameManager.TutorialGuideType.Items, "방어막", "다음 충돌 1회를 막습니다.\n먹은 뒤 바로 충돌을 막아 봅니다.", Platform.ItemPattern.Shield),
|
||||
ForceHit(GameManager.TutorialGuideType.None, "", ""),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Basic(GroundY, BasicSpacing, Platform.MileagePattern.None, GameManager.TutorialGuideType.Items, "마일리지 카드", "잠깐 마일리지가 2배가 됩니다.\n먹고 바로 마일리지를 모아 봅니다.", Platform.ItemPattern.MileageCard),
|
||||
Basic(GroundY, BasicSpacing, Platform.MileagePattern.SafeLine),
|
||||
ForceHit(GameManager.TutorialGuideType.None, "", ""),
|
||||
Basic(GroundY, BasicSpacing, Platform.MileagePattern.None, GameManager.TutorialGuideType.Items, "운동화", "느려진 속도를 회복합니다.\n방금 떨어진 속도를 되돌려 봅니다.", Platform.ItemPattern.SpeedShoes),
|
||||
Basic(GroundY, LandingSpacing, Platform.MileagePattern.None, GameManager.TutorialGuideType.Items, "실전 연습", "시간이 지나면 달리기 속도는 조금씩 빨라지고, 장애물에 맞으면 느려집니다.\n방금 먹은 신발 아이템으로 회복한 뒤 출국 게이트까지 달려보세요."),
|
||||
Basic(GroundY, BasicSpacing, Platform.MileagePattern.SafeLine),
|
||||
Basic(),
|
||||
Basic(),
|
||||
Basic(),
|
||||
Basic(GroundY, LandingSpacing)
|
||||
},
|
||||
loopSteps = CreateEasyLoop()
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c16e17831dc94b26a6cfa4c6bbf17130
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -2,12 +2,6 @@ using UnityEngine;
|
||||
|
||||
public static class MapDatabase {
|
||||
private static MapDefinition[] maps;
|
||||
private const float GroundY = -2.4f;
|
||||
private const float AerialY = -0.85f;
|
||||
private const float BasicSpacing = 0.58f;
|
||||
private const float ActionSpacing = 0.72f;
|
||||
private const float LandingSpacing = 0.64f;
|
||||
private const float AerialSpacing = 2.05f;
|
||||
|
||||
public static MapDefinition[] AllMaps {
|
||||
get {
|
||||
@@ -64,313 +58,10 @@ public static class MapDatabase {
|
||||
}
|
||||
|
||||
maps = new MapDefinition[] {
|
||||
CreateTutorialIncheon(),
|
||||
CreateJapan(),
|
||||
CreateChina(),
|
||||
CreateAmerica()
|
||||
};
|
||||
}
|
||||
|
||||
private static MapDefinition CreateTutorialIncheon() {
|
||||
return new MapDefinition {
|
||||
mapId = MapId.TutorialIncheon,
|
||||
displayName = "Tutorial / Incheon",
|
||||
routeName = "인천공항 출발 준비",
|
||||
isTutorial = true,
|
||||
platformSkin = Platform.PlatformSkin.Airport,
|
||||
backgroundResourcePath = "Map_Tutorial_Incheon_Airport",
|
||||
finishGateStyle = FinishGateStyle.AirportDeparture,
|
||||
targetDistance = 320f,
|
||||
timeLimit = 75f,
|
||||
clearMileageReward = 150,
|
||||
hasNextMap = true,
|
||||
nextMapId = MapId.Japan,
|
||||
openingSteps = new PlatformSpawner.TutorialStep[] {
|
||||
Basic(),
|
||||
Basic(),
|
||||
Basic(GroundY, BasicSpacing),
|
||||
Jump(GameManager.TutorialGuideType.Jump, "점프 구간", "가방 장애물이 오면 왼쪽 클릭으로 뛰어넘습니다."),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Basic(GroundY, BasicSpacing),
|
||||
Aerial(GameManager.TutorialGuideType.DoubleJump, "2단 점프 구간", "다음 발판이 멀리 떨어져 있습니다.\n공중에서 왼쪽 클릭을 한 번 더 누릅니다."),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Basic(GroundY, BasicSpacing),
|
||||
Slide(GameManager.TutorialGuideType.Slide, "슬라이드 구간", "천장 장애물이 오면 오른쪽 클릭을 누르고 지나갑니다."),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Basic(GroundY, BasicSpacing),
|
||||
ForceHit(GameManager.TutorialGuideType.None, "", ""),
|
||||
Basic(GroundY, LandingSpacing, Platform.MileagePattern.None, GameManager.TutorialGuideType.Items, "초밥", "잃은 목숨을 1 회복합니다.\n방금 줄어든 목숨을 채워 봅니다.", Platform.ItemPattern.HealthSushi),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Basic(GroundY, BasicSpacing, Platform.MileagePattern.None, GameManager.TutorialGuideType.Items, "라멘", "잠깐 무적이 됩니다.\n먹은 뒤 다음 장애물에 일부러 부딪혀 봅니다.", Platform.ItemPattern.InvincibleRamen),
|
||||
ForceHit(GameManager.TutorialGuideType.None, "", ""),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Basic(GroundY, BasicSpacing, Platform.MileagePattern.None, GameManager.TutorialGuideType.Items, "방어막", "다음 충돌 1회를 막습니다.\n먹은 뒤 바로 충돌을 막아 봅니다.", Platform.ItemPattern.Shield),
|
||||
ForceHit(GameManager.TutorialGuideType.None, "", ""),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
ForceHit(GameManager.TutorialGuideType.None, "", ""),
|
||||
Basic(GroundY, BasicSpacing, Platform.MileagePattern.None, GameManager.TutorialGuideType.Items, "운동화", "느려진 속도를 회복합니다.\n방금 떨어진 속도를 되돌려 봅니다.", Platform.ItemPattern.SpeedShoes),
|
||||
Basic(GroundY, BasicSpacing, Platform.MileagePattern.None, GameManager.TutorialGuideType.Items, "마일리지 카드", "잠깐 마일리지가 2배가 됩니다.\n먹고 바로 마일리지를 모아 봅니다.", Platform.ItemPattern.MileageCard),
|
||||
Basic(GroundY, BasicSpacing, Platform.MileagePattern.SafeLine),
|
||||
Basic(),
|
||||
Basic(),
|
||||
Basic(),
|
||||
Basic(GroundY, LandingSpacing)
|
||||
},
|
||||
loopSteps = CreateEasyLoop()
|
||||
};
|
||||
}
|
||||
|
||||
private static MapDefinition CreateJapan() {
|
||||
return new MapDefinition {
|
||||
mapId = MapId.Japan,
|
||||
displayName = "Japan",
|
||||
routeName = "후쿠오카 라멘 투어",
|
||||
isTutorial = false,
|
||||
platformSkin = Platform.PlatformSkin.Japan,
|
||||
backgroundResourcePath = "",
|
||||
finishGateStyle = FinishGateStyle.JapanTorii,
|
||||
targetDistance = 1200f,
|
||||
timeLimit = 105f,
|
||||
clearMileageReward = 250,
|
||||
hasNextMap = true,
|
||||
nextMapId = MapId.China,
|
||||
openingSteps = new PlatformSpawner.TutorialStep[] {
|
||||
Basic(),
|
||||
Basic()
|
||||
},
|
||||
loopSteps = new PlatformSpawner.TutorialStep[] {
|
||||
Basic(),
|
||||
Jump(),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Aerial(),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Slide(SlideObstaclePattern.SlideLayout.CenterPair),
|
||||
Basic(),
|
||||
Jump(Platform.PlatformPattern.LowLeft),
|
||||
Basic()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static MapDefinition CreateChina() {
|
||||
return new MapDefinition {
|
||||
mapId = MapId.China,
|
||||
displayName = "China",
|
||||
routeName = "베이징 시장길",
|
||||
isTutorial = false,
|
||||
platformSkin = Platform.PlatformSkin.China,
|
||||
backgroundResourcePath = "",
|
||||
finishGateStyle = FinishGateStyle.ChinaPaifang,
|
||||
targetDistance = 1450f,
|
||||
timeLimit = 115f,
|
||||
clearMileageReward = 350,
|
||||
hasNextMap = true,
|
||||
nextMapId = MapId.America,
|
||||
openingSteps = new PlatformSpawner.TutorialStep[] {
|
||||
Basic(),
|
||||
Basic()
|
||||
},
|
||||
loopSteps = new PlatformSpawner.TutorialStep[] {
|
||||
Basic(),
|
||||
Jump(Platform.PlatformPattern.LowRight),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Slide(SlideObstaclePattern.SlideLayout.LeftPair),
|
||||
Basic(),
|
||||
Aerial(AerialY + 0.15f, 1.08f),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Jump(),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Slide(SlideObstaclePattern.SlideLayout.RightPair)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static MapDefinition CreateAmerica() {
|
||||
return new MapDefinition {
|
||||
mapId = MapId.America,
|
||||
displayName = "America",
|
||||
routeName = "뉴욕 자유의 여신상",
|
||||
isTutorial = false,
|
||||
platformSkin = Platform.PlatformSkin.USA,
|
||||
backgroundResourcePath = "Map_America_NewYork",
|
||||
finishGateStyle = FinishGateStyle.AmericaLiberty,
|
||||
targetDistance = 1700f,
|
||||
timeLimit = 125f,
|
||||
clearMileageReward = 500,
|
||||
hasNextMap = false,
|
||||
nextMapId = MapId.America,
|
||||
openingSteps = new PlatformSpawner.TutorialStep[] {
|
||||
Basic(),
|
||||
Basic()
|
||||
},
|
||||
loopSteps = new PlatformSpawner.TutorialStep[] {
|
||||
Basic(),
|
||||
Jump(Platform.PlatformPattern.LowMid),
|
||||
Basic(GroundY, 0.86f),
|
||||
Slide(SlideObstaclePattern.SlideLayout.WidePair),
|
||||
Basic(),
|
||||
Aerial(AerialY + 0.2f, 1.0f),
|
||||
Basic(GroundY, 0.86f),
|
||||
Jump(Platform.PlatformPattern.LowLeft),
|
||||
Basic(),
|
||||
Slide(SlideObstaclePattern.SlideLayout.CenterPair),
|
||||
Basic(),
|
||||
Jump(Platform.PlatformPattern.LowRight)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static PlatformSpawner.TutorialStep[] CreateEasyLoop() {
|
||||
return new PlatformSpawner.TutorialStep[] {
|
||||
Basic(),
|
||||
Jump(),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Aerial(),
|
||||
Basic(GroundY, LandingSpacing),
|
||||
Slide(SlideObstaclePattern.SlideLayout.CenterPair),
|
||||
Basic()
|
||||
};
|
||||
}
|
||||
|
||||
private static PlatformSpawner.TutorialStep Basic(
|
||||
float yPosition = GroundY,
|
||||
float spawnInterval = BasicSpacing,
|
||||
Platform.MileagePattern mileagePattern = Platform.MileagePattern.SafeLine,
|
||||
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.None,
|
||||
string title = "",
|
||||
string message = "",
|
||||
Platform.ItemPattern itemPattern = Platform.ItemPattern.None) {
|
||||
return Step(
|
||||
Platform.PlatformPattern.Empty,
|
||||
mileagePattern,
|
||||
SlideObstaclePattern.SlideLayout.Random,
|
||||
guideType,
|
||||
yPosition,
|
||||
spawnInterval,
|
||||
title,
|
||||
message,
|
||||
itemPattern,
|
||||
PlatformSpawner.CoursePlatformType.Basic);
|
||||
}
|
||||
|
||||
private static PlatformSpawner.TutorialStep Jump(
|
||||
Platform.PlatformPattern platformPattern = Platform.PlatformPattern.LowMid,
|
||||
float spawnInterval = ActionSpacing,
|
||||
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.None,
|
||||
string title = "",
|
||||
string message = "") {
|
||||
return Step(
|
||||
platformPattern,
|
||||
Platform.MileagePattern.JumpArc,
|
||||
SlideObstaclePattern.SlideLayout.Random,
|
||||
guideType,
|
||||
GroundY,
|
||||
spawnInterval,
|
||||
title,
|
||||
message,
|
||||
Platform.ItemPattern.None,
|
||||
PlatformSpawner.CoursePlatformType.Jump);
|
||||
}
|
||||
|
||||
private static PlatformSpawner.TutorialStep Jump(
|
||||
GameManager.TutorialGuideType guideType,
|
||||
string title,
|
||||
string message) {
|
||||
return Jump(Platform.PlatformPattern.LowMid, ActionSpacing, guideType, title, message);
|
||||
}
|
||||
|
||||
private static PlatformSpawner.TutorialStep Aerial(
|
||||
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.None,
|
||||
string title = "",
|
||||
string message = "") {
|
||||
return Aerial(AerialY, AerialSpacing, guideType, title, message);
|
||||
}
|
||||
|
||||
private static PlatformSpawner.TutorialStep Aerial(
|
||||
float yPosition,
|
||||
float spawnInterval,
|
||||
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.None,
|
||||
string title = "",
|
||||
string message = "") {
|
||||
return Step(
|
||||
Platform.PlatformPattern.Empty,
|
||||
Platform.MileagePattern.SafeLine,
|
||||
SlideObstaclePattern.SlideLayout.Random,
|
||||
guideType,
|
||||
GroundY,
|
||||
spawnInterval,
|
||||
title,
|
||||
message,
|
||||
Platform.ItemPattern.None,
|
||||
PlatformSpawner.CoursePlatformType.Basic);
|
||||
}
|
||||
|
||||
private static PlatformSpawner.TutorialStep Slide(
|
||||
SlideObstaclePattern.SlideLayout slideLayout = SlideObstaclePattern.SlideLayout.CenterPair,
|
||||
float spawnInterval = ActionSpacing,
|
||||
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.None,
|
||||
string title = "",
|
||||
string message = "") {
|
||||
return Step(
|
||||
Platform.PlatformPattern.Slide,
|
||||
Platform.MileagePattern.SlideLine,
|
||||
slideLayout,
|
||||
guideType,
|
||||
GroundY,
|
||||
spawnInterval,
|
||||
title,
|
||||
message,
|
||||
Platform.ItemPattern.None,
|
||||
PlatformSpawner.CoursePlatformType.Slide);
|
||||
}
|
||||
|
||||
private static PlatformSpawner.TutorialStep Slide(
|
||||
GameManager.TutorialGuideType guideType,
|
||||
string title,
|
||||
string message) {
|
||||
return Slide(SlideObstaclePattern.SlideLayout.CenterPair, ActionSpacing, guideType, title, message);
|
||||
}
|
||||
|
||||
private static PlatformSpawner.TutorialStep ForceHit(
|
||||
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.Damage,
|
||||
string title = "",
|
||||
string message = "",
|
||||
float spawnInterval = ActionSpacing) {
|
||||
return Step(
|
||||
Platform.PlatformPattern.ForceHit,
|
||||
Platform.MileagePattern.None,
|
||||
SlideObstaclePattern.SlideLayout.WidePair,
|
||||
guideType,
|
||||
GroundY,
|
||||
spawnInterval,
|
||||
title,
|
||||
message,
|
||||
Platform.ItemPattern.None,
|
||||
PlatformSpawner.CoursePlatformType.ForceHit);
|
||||
}
|
||||
|
||||
private static PlatformSpawner.TutorialStep Step(
|
||||
Platform.PlatformPattern platformPattern,
|
||||
Platform.MileagePattern mileagePattern,
|
||||
SlideObstaclePattern.SlideLayout slideLayout,
|
||||
GameManager.TutorialGuideType guideType,
|
||||
float yPosition,
|
||||
float spawnInterval,
|
||||
string title = "",
|
||||
string message = "",
|
||||
Platform.ItemPattern itemPattern = Platform.ItemPattern.None,
|
||||
PlatformSpawner.CoursePlatformType coursePlatformType = PlatformSpawner.CoursePlatformType.Basic) {
|
||||
return new PlatformSpawner.TutorialStep {
|
||||
coursePlatformType = coursePlatformType,
|
||||
platformPattern = platformPattern,
|
||||
mileagePattern = mileagePattern,
|
||||
slideLayout = slideLayout,
|
||||
itemPattern = itemPattern,
|
||||
guideType = guideType,
|
||||
yPosition = yPosition,
|
||||
spawnInterval = spawnInterval,
|
||||
title = title,
|
||||
message = message
|
||||
TutorialIncheonMap.Create(),
|
||||
JapanMap.Create(),
|
||||
ChinaMap.Create(),
|
||||
AmericaMap.Create()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -388,35 +79,8 @@ public static class MapDatabase {
|
||||
clearMileageReward = source.clearMileageReward,
|
||||
hasNextMap = source.hasNextMap,
|
||||
nextMapId = source.nextMapId,
|
||||
openingSteps = CloneSteps(source.openingSteps),
|
||||
loopSteps = CloneSteps(source.loopSteps)
|
||||
openingSteps = CourseStepFactory.CloneSteps(source.openingSteps),
|
||||
loopSteps = CourseStepFactory.CloneSteps(source.loopSteps)
|
||||
};
|
||||
}
|
||||
|
||||
public static PlatformSpawner.TutorialStep[] CloneSteps(PlatformSpawner.TutorialStep[] source) {
|
||||
if(source == null)
|
||||
{
|
||||
return new PlatformSpawner.TutorialStep[0];
|
||||
}
|
||||
|
||||
PlatformSpawner.TutorialStep[] steps = new PlatformSpawner.TutorialStep[source.Length];
|
||||
|
||||
for(int i = 0; i < source.Length; i++)
|
||||
{
|
||||
PlatformSpawner.TutorialStep sourceStep = source[i];
|
||||
steps[i] = Step(
|
||||
sourceStep.platformPattern,
|
||||
sourceStep.mileagePattern,
|
||||
sourceStep.slideLayout,
|
||||
sourceStep.guideType,
|
||||
sourceStep.yPosition,
|
||||
sourceStep.spawnInterval,
|
||||
sourceStep.title,
|
||||
sourceStep.message,
|
||||
sourceStep.itemPattern,
|
||||
sourceStep.coursePlatformType);
|
||||
}
|
||||
|
||||
return steps;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,6 @@ public class MapDefinition {
|
||||
public int clearMileageReward;
|
||||
public bool hasNextMap;
|
||||
public MapId nextMapId;
|
||||
public PlatformSpawner.TutorialStep[] openingSteps;
|
||||
public PlatformSpawner.TutorialStep[] loopSteps;
|
||||
public CourseStep[] openingSteps;
|
||||
public CourseStep[] loopSteps;
|
||||
}
|
||||
|
||||
+8
-260
@@ -39,8 +39,6 @@ public class Platform : MonoBehaviour {
|
||||
USA
|
||||
}
|
||||
|
||||
public GameObject[] obstacles; // 장애물 오브젝트들
|
||||
public int emptyPatternWeight = 2; // 장애물이 없는 패턴이 선택될 가중치
|
||||
public Sprite mileageSprite; // 이 발판에서 사용할 마일리지 토큰 스프라이트
|
||||
public int mileagePatternChance = 50; // 마일리지 패턴 등장 확률
|
||||
public int smallMileageValue = 10; // 일반 토큰 가치
|
||||
@@ -49,9 +47,7 @@ public class Platform : MonoBehaviour {
|
||||
private bool stepped = false; // 플레이어 캐릭터가 밟았었는가
|
||||
private MileagePickup[] mileagePickups; // 런타임에 생성하는 마일리지 토큰 풀
|
||||
private ItemPickup[] itemPickups; // 런타임에 생성하는 튜토리얼 아이템 풀
|
||||
private PlatformPattern reservedPattern = PlatformPattern.Random; // 다음 활성화 때 사용할 수동 패턴
|
||||
private MileagePattern reservedMileagePattern = MileagePattern.Random; // 다음 활성화 때 사용할 마일리지 패턴
|
||||
private SlideObstaclePattern.SlideLayout reservedSlideLayout = SlideObstaclePattern.SlideLayout.Random; // 다음 슬라이딩 장애물 배치
|
||||
private ItemPattern reservedItemPattern = ItemPattern.None; // 다음 활성화 때 사용할 아이템 배치
|
||||
private PlatformSkin reservedSkin = PlatformSkin.Airport; // 현재 맵에서 사용할 발판/장애물 스킨
|
||||
private const int MileagePoolSize = 5;
|
||||
@@ -63,23 +59,14 @@ public class Platform : MonoBehaviour {
|
||||
private const float JumpMileageMinWidthScale = 1.8f;
|
||||
private const float JumpMileageMaxWidthScale = 2.5f;
|
||||
|
||||
public void ConfigureForTutorial(
|
||||
PlatformPattern pattern,
|
||||
MileagePattern mileagePattern,
|
||||
SlideObstaclePattern.SlideLayout slideLayout = SlideObstaclePattern.SlideLayout.Random,
|
||||
ItemPattern itemPattern = ItemPattern.None,
|
||||
PlatformSkin platformSkin = PlatformSkin.Airport) {
|
||||
reservedPattern = pattern;
|
||||
public void ConfigureForTutorial(MileagePattern mileagePattern, ItemPattern itemPattern = ItemPattern.None, PlatformSkin platformSkin = PlatformSkin.Airport) {
|
||||
reservedMileagePattern = mileagePattern;
|
||||
reservedSlideLayout = slideLayout;
|
||||
reservedItemPattern = itemPattern;
|
||||
reservedSkin = platformSkin;
|
||||
}
|
||||
|
||||
public void ConfigureForRandom(PlatformSkin platformSkin = PlatformSkin.Airport) {
|
||||
reservedPattern = PlatformPattern.Random;
|
||||
reservedMileagePattern = MileagePattern.Random;
|
||||
reservedSlideLayout = SlideObstaclePattern.SlideLayout.Random;
|
||||
reservedItemPattern = ItemPattern.None;
|
||||
reservedSkin = platformSkin;
|
||||
}
|
||||
@@ -93,38 +80,10 @@ public class Platform : MonoBehaviour {
|
||||
EnsureMileagePickups();
|
||||
EnsureItemPickups();
|
||||
|
||||
for(int i = 0; i < obstacles.Length; i++)
|
||||
{
|
||||
obstacles[i].SetActive(false);
|
||||
}
|
||||
|
||||
HideMileagePickups();
|
||||
HideItemPickups();
|
||||
|
||||
if(reservedPattern != PlatformPattern.Random)
|
||||
{
|
||||
ApplyReservedPattern();
|
||||
return;
|
||||
}
|
||||
|
||||
if(obstacles.Length == 0)
|
||||
{
|
||||
TryPlaceMileagePattern(null);
|
||||
return;
|
||||
}
|
||||
|
||||
// 낮은 장애물과 높은 장애물이 동시에 켜져 불가능한 배치가 되지 않도록 하나만 선택한다.
|
||||
int patternIndex = Random.Range(0, obstacles.Length + emptyPatternWeight);
|
||||
GameObject activeObstacle = null;
|
||||
|
||||
if(patternIndex < obstacles.Length)
|
||||
{
|
||||
activeObstacle = obstacles[patternIndex];
|
||||
ConfigureSlideObstacle(activeObstacle);
|
||||
activeObstacle.SetActive(true);
|
||||
}
|
||||
|
||||
TryPlaceMileagePattern(activeObstacle);
|
||||
PlaceReservedMileagePattern();
|
||||
PlaceReservedItemPattern();
|
||||
}
|
||||
|
||||
void OnCollisionEnter2D(Collision2D collision) {
|
||||
@@ -223,100 +182,16 @@ public class Platform : MonoBehaviour {
|
||||
}
|
||||
}
|
||||
|
||||
private void TryPlaceMileagePattern(GameObject activeObstacle) {
|
||||
private void TryPlaceMileagePattern() {
|
||||
if(mileageSprite == null || mileagePickups == null || Random.Range(0, 100) >= mileagePatternChance)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(activeObstacle == null)
|
||||
{
|
||||
PlaceSafeMileageLine();
|
||||
return;
|
||||
}
|
||||
|
||||
if(activeObstacle.name.Contains("Slide"))
|
||||
{
|
||||
PlaceSlideMileageLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
PlaceJumpMileageArc(GetWorldRelativeX(activeObstacle.transform));
|
||||
}
|
||||
PlaceSafeMileageLine();
|
||||
}
|
||||
|
||||
private void ApplyReservedPattern() {
|
||||
GameObject activeObstacle = null;
|
||||
|
||||
switch(reservedPattern)
|
||||
{
|
||||
case PlatformPattern.LowLeft:
|
||||
activeObstacle = FindObstacle("Obstacle Left");
|
||||
break;
|
||||
case PlatformPattern.LowMid:
|
||||
activeObstacle = FindObstacle("Obstacle Mid");
|
||||
break;
|
||||
case PlatformPattern.LowRight:
|
||||
activeObstacle = FindObstacle("Obstacle Right");
|
||||
break;
|
||||
case PlatformPattern.Slide:
|
||||
activeObstacle = FindObstacle("Slide Obstacle Pattern");
|
||||
break;
|
||||
case PlatformPattern.ForceHit:
|
||||
activeObstacle = FindObstacle("Obstacle Mid");
|
||||
ActivateObstacle(activeObstacle);
|
||||
|
||||
GameObject slideObstacle = FindObstacle("Slide Obstacle Pattern");
|
||||
reservedSlideLayout = SlideObstaclePattern.SlideLayout.WidePair;
|
||||
ActivateObstacle(slideObstacle);
|
||||
break;
|
||||
}
|
||||
|
||||
if(reservedPattern != PlatformPattern.ForceHit && activeObstacle != null)
|
||||
{
|
||||
ActivateObstacle(activeObstacle);
|
||||
}
|
||||
|
||||
PlaceReservedMileagePattern(activeObstacle);
|
||||
PlaceReservedItemPattern();
|
||||
}
|
||||
|
||||
private void ActivateObstacle(GameObject obstacle) {
|
||||
if(obstacle == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigureSlideObstacle(obstacle);
|
||||
obstacle.SetActive(true);
|
||||
}
|
||||
|
||||
private void ConfigureSlideObstacle(GameObject activeObstacle) {
|
||||
if(activeObstacle == null || !activeObstacle.name.Contains("Slide"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SlideObstaclePattern slideObstaclePattern = activeObstacle.GetComponent<SlideObstaclePattern>();
|
||||
if(slideObstaclePattern != null)
|
||||
{
|
||||
slideObstaclePattern.ConfigureLayout(reservedSlideLayout);
|
||||
}
|
||||
}
|
||||
|
||||
private GameObject FindObstacle(string obstacleName) {
|
||||
for(int i = 0; i < obstacles.Length; i++)
|
||||
{
|
||||
if(obstacles[i] != null && obstacles[i].name == obstacleName)
|
||||
{
|
||||
return obstacles[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void PlaceReservedMileagePattern(GameObject activeObstacle) {
|
||||
private void PlaceReservedMileagePattern() {
|
||||
if(mileageSprite == null || mileagePickups == null || reservedMileagePattern == MileagePattern.None)
|
||||
{
|
||||
return;
|
||||
@@ -330,8 +205,7 @@ public class Platform : MonoBehaviour {
|
||||
|
||||
if(reservedMileagePattern == MileagePattern.JumpArc)
|
||||
{
|
||||
float obstacleX = activeObstacle != null ? GetWorldRelativeX(activeObstacle.transform) : 0f;
|
||||
PlaceJumpMileageArc(obstacleX);
|
||||
PlaceJumpMileageArc(0f);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -341,7 +215,7 @@ public class Platform : MonoBehaviour {
|
||||
return;
|
||||
}
|
||||
|
||||
TryPlaceMileagePattern(activeObstacle);
|
||||
TryPlaceMileagePattern();
|
||||
}
|
||||
|
||||
private void PlaceReservedItemPattern() {
|
||||
@@ -397,22 +271,10 @@ public class Platform : MonoBehaviour {
|
||||
private void ApplyVisualSkin() {
|
||||
#if UNITY_EDITOR
|
||||
Sprite platformSprite = LoadSpriteAtPath(GetPlatformSkinPath(reservedSkin));
|
||||
Sprite ceilingSprite = LoadSpriteAtPath(GetCeilingSkinPath(reservedSkin));
|
||||
Sprite lowObstacleSprite = LoadSpriteAtPath(GetLowObstacleSkinPath(reservedSkin));
|
||||
Sprite hangingObstacleSprite = LoadSpriteAtPath(GetHangingObstacleSkinPath(reservedSkin));
|
||||
Sprite mileageSkinSprite = LoadSpriteAtPath(GetMileageSkinPath(reservedSkin));
|
||||
|
||||
ApplySprite(GetComponent<SpriteRenderer>(), platformSprite);
|
||||
|
||||
Transform ceilingPlatform = FindChildRecursive(transform, "Ceiling Platform");
|
||||
if(ceilingPlatform != null)
|
||||
{
|
||||
ApplySprite(ceilingPlatform.GetComponent<SpriteRenderer>(), ceilingSprite != null ? ceilingSprite : platformSprite);
|
||||
}
|
||||
|
||||
ApplyLowObstacleSkin(lowObstacleSprite);
|
||||
ApplyHangingObstacleSkin(hangingObstacleSprite);
|
||||
|
||||
if(mileageSkinSprite != null)
|
||||
{
|
||||
mileageSprite = mileageSkinSprite;
|
||||
@@ -421,52 +283,6 @@ public class Platform : MonoBehaviour {
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void ApplyLowObstacleSkin(Sprite obstacleSprite) {
|
||||
if(obstacleSprite == null || obstacles == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < obstacles.Length; i++)
|
||||
{
|
||||
GameObject obstacle = obstacles[i];
|
||||
if(obstacle == null || obstacle.name.Contains("Slide"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ApplySprite(obstacle.GetComponent<SpriteRenderer>(), obstacleSprite);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyHangingObstacleSkin(Sprite obstacleSprite) {
|
||||
if(obstacleSprite == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject slideObstacle = FindObstacle("Slide Obstacle Pattern");
|
||||
if(slideObstacle == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SlideObstaclePattern slideObstaclePattern = slideObstacle.GetComponent<SlideObstaclePattern>();
|
||||
if(slideObstaclePattern == null || slideObstaclePattern.obstacles == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < slideObstaclePattern.obstacles.Length; i++)
|
||||
{
|
||||
Transform hangingObstacle = slideObstaclePattern.obstacles[i];
|
||||
if(hangingObstacle != null)
|
||||
{
|
||||
ApplySprite(hangingObstacle.GetComponent<SpriteRenderer>(), obstacleSprite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplySprite(SpriteRenderer spriteRenderer, Sprite sprite) {
|
||||
if(spriteRenderer != null && sprite != null)
|
||||
{
|
||||
@@ -483,31 +299,6 @@ public class Platform : MonoBehaviour {
|
||||
return AssetDatabase.LoadAssetAtPath<Sprite>(assetPath);
|
||||
}
|
||||
|
||||
private Transform FindChildRecursive(Transform parent, string childName) {
|
||||
if(parent == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for(int i = 0; i < parent.childCount; i++)
|
||||
{
|
||||
Transform child = parent.GetChild(i);
|
||||
|
||||
if(child.name == childName)
|
||||
{
|
||||
return child;
|
||||
}
|
||||
|
||||
Transform match = FindChildRecursive(child, childName);
|
||||
if(match != null)
|
||||
{
|
||||
return match;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private string GetPlatformSkinPath(PlatformSkin platformSkin) {
|
||||
switch(platformSkin)
|
||||
{
|
||||
@@ -523,45 +314,6 @@ public class Platform : MonoBehaviour {
|
||||
}
|
||||
}
|
||||
|
||||
private string GetCeilingSkinPath(PlatformSkin platformSkin) {
|
||||
if(platformSkin == PlatformSkin.Airport)
|
||||
{
|
||||
return "Assets/Sprites/ObstacleSkins/Skin_Platform_AirportCeiling.png";
|
||||
}
|
||||
|
||||
return GetPlatformSkinPath(platformSkin);
|
||||
}
|
||||
|
||||
private string GetLowObstacleSkinPath(PlatformSkin platformSkin) {
|
||||
switch(platformSkin)
|
||||
{
|
||||
case PlatformSkin.Japan:
|
||||
return "Assets/Sprites/ObstacleSkins/Skin_Obstacle_StoneLantern.png";
|
||||
case PlatformSkin.China:
|
||||
return "Assets/Sprites/ObstacleSkins/Skin_Obstacle_MarketCrate.png";
|
||||
case PlatformSkin.USA:
|
||||
return "Assets/Sprites/ObstacleSkins/Skin_Obstacle_Cone.png";
|
||||
case PlatformSkin.Airport:
|
||||
default:
|
||||
return "Assets/Sprites/ObstacleSkins/Skin_Obstacle_Suitcases.png";
|
||||
}
|
||||
}
|
||||
|
||||
private string GetHangingObstacleSkinPath(PlatformSkin platformSkin) {
|
||||
switch(platformSkin)
|
||||
{
|
||||
case PlatformSkin.Japan:
|
||||
return "Assets/Sprites/ObstacleSkins/Skin_Hanging_RoadSign.png";
|
||||
case PlatformSkin.China:
|
||||
return "Assets/Sprites/ObstacleSkins/Skin_Hanging_RedLanterns.png";
|
||||
case PlatformSkin.USA:
|
||||
return "Assets/Sprites/ObstacleSkins/Skin_Hanging_Banner.png";
|
||||
case PlatformSkin.Airport:
|
||||
default:
|
||||
return "Assets/Sprites/ObstacleSkins/Skin_Hanging_AirportSign.png";
|
||||
}
|
||||
}
|
||||
|
||||
private string GetMileageSkinPath(PlatformSkin platformSkin) {
|
||||
switch(platformSkin)
|
||||
{
|
||||
@@ -681,10 +433,6 @@ public class Platform : MonoBehaviour {
|
||||
return new Vector3(position.x / parentScaleX, position.y / parentScaleY, 0f);
|
||||
}
|
||||
|
||||
private float GetWorldRelativeX(Transform child) {
|
||||
return child.localPosition.x * transform.localScale.x;
|
||||
}
|
||||
|
||||
private void SetPickupValue(int index, int value) {
|
||||
if(index < 0 || index >= mileagePickups.Length || !mileagePickups[index].gameObject.activeSelf)
|
||||
{
|
||||
|
||||
@@ -1,44 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
// 발판을 생성하고 주기적으로 재배치하는 스크립트
|
||||
public class PlatformSpawner : MonoBehaviour {
|
||||
public enum CoursePlatformType {
|
||||
Basic,
|
||||
Jump,
|
||||
Slide,
|
||||
ForceHit
|
||||
}
|
||||
|
||||
private enum TutorialStepKind {
|
||||
None,
|
||||
Jump,
|
||||
DoubleJumpTakeoff,
|
||||
Slide,
|
||||
ForceHit,
|
||||
HealthItem,
|
||||
InvincibleItem,
|
||||
ShieldItem,
|
||||
SpeedItem,
|
||||
MileageCardItem
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class TutorialStep {
|
||||
public CoursePlatformType coursePlatformType;
|
||||
public Platform.PlatformPattern platformPattern;
|
||||
public Platform.MileagePattern mileagePattern;
|
||||
public SlideObstaclePattern.SlideLayout slideLayout;
|
||||
public Platform.ItemPattern itemPattern;
|
||||
public GameManager.TutorialGuideType guideType;
|
||||
public float yPosition;
|
||||
public float spawnInterval;
|
||||
public string title;
|
||||
public string message;
|
||||
}
|
||||
|
||||
private class PendingTutorialGuide {
|
||||
public Transform target;
|
||||
public GameManager.TutorialGuideType guideType;
|
||||
@@ -53,8 +18,8 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
public int count = 12; // 기본 발판 풀 개수
|
||||
public bool usePatternCourse = true; // 검증된 발판 패턴 코스를 사용
|
||||
public bool tutorialMode = true; // 처음에는 튜토리얼 패턴을 먼저 배치
|
||||
public TutorialStep[] tutorialSteps; // 튜토리얼 발판 순서
|
||||
public TutorialStep[] stagePatternSteps; // 튜토리얼 이후 반복할 검증된 발판 순서
|
||||
public CourseStep[] tutorialSteps; // 튜토리얼 발판 순서
|
||||
public CourseStep[] stagePatternSteps; // 튜토리얼 이후 반복할 검증된 발판 순서
|
||||
|
||||
public bool keepWorldSpacingBySpeed = true; // 게임 속도가 빨라져도 발판 사이 실제 거리를 유지
|
||||
public int continuousCoursePoolCount = 12; // 기본 발판을 촘촘히 깔 때 필요한 최소 풀 크기
|
||||
@@ -99,8 +64,8 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
usePatternCourse = true;
|
||||
tutorialMode = mapDefinition.isTutorial;
|
||||
mapPlatformSkin = mapDefinition.platformSkin;
|
||||
tutorialSteps = MapDatabase.CloneSteps(mapDefinition.openingSteps);
|
||||
stagePatternSteps = MapDatabase.CloneSteps(mapDefinition.loopSteps);
|
||||
tutorialSteps = CourseStepFactory.CloneSteps(mapDefinition.openingSteps);
|
||||
stagePatternSteps = CourseStepFactory.CloneSteps(mapDefinition.loopSteps);
|
||||
courseStepIndex = 0;
|
||||
courseSpawningStopped = false;
|
||||
pendingTutorialGuides.Clear();
|
||||
@@ -123,7 +88,7 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
activeFinishLandingPlatform = Instantiate(platformPrefab, poolPosition, Quaternion.identity);
|
||||
activeFinishLandingPlatform.SetActive(false);
|
||||
|
||||
TutorialStep landingStep = CreateStep(
|
||||
CourseStep landingStep = CreateStep(
|
||||
Platform.PlatformPattern.Empty,
|
||||
Platform.MileagePattern.None,
|
||||
SlideObstaclePattern.SlideLayout.Random,
|
||||
@@ -266,7 +231,7 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
{
|
||||
lastSpawnTime = Time.time;
|
||||
|
||||
TutorialStep step = usePatternCourse ? GetCurrentCourseStep() : null;
|
||||
CourseStep step = usePatternCourse ? GetCurrentCourseStep() : null;
|
||||
timeBetSpawn = step != null ? GetStepSpawnInterval(step) : Random.Range(timeBetSpawnMin, timeBetSpawnMax);
|
||||
|
||||
float yPos = step != null
|
||||
@@ -319,7 +284,7 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterTutorialGuide(Transform target, TutorialStep step) {
|
||||
private void RegisterTutorialGuide(Transform target, CourseStep step) {
|
||||
if(target == null
|
||||
|| step == null
|
||||
|| step.guideType == GameManager.TutorialGuideType.None
|
||||
@@ -337,7 +302,7 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
});
|
||||
}
|
||||
|
||||
private float GetTutorialGuideTriggerX(TutorialStep step) {
|
||||
private float GetTutorialGuideTriggerX(CourseStep step) {
|
||||
if(step != null && step.guideType == GameManager.TutorialGuideType.DoubleJump)
|
||||
{
|
||||
return -2f;
|
||||
@@ -346,7 +311,7 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
return tutorialGuideTriggerX;
|
||||
}
|
||||
|
||||
private void SpawnCourseObstacles(TutorialStep step, float yPos) {
|
||||
private void SpawnCourseObstacles(CourseStep step, float yPos) {
|
||||
if(step == null)
|
||||
{
|
||||
return;
|
||||
@@ -355,7 +320,6 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
if(step.coursePlatformType == CoursePlatformType.ForceHit || step.platformPattern == Platform.PlatformPattern.ForceHit)
|
||||
{
|
||||
SpawnJumpObstacle(Platform.PlatformPattern.LowMid, yPos);
|
||||
SpawnSlideObstacle(SlideObstaclePattern.SlideLayout.WidePair, yPos);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -440,7 +404,7 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
return platformObject;
|
||||
}
|
||||
|
||||
private void ConfigurePlatform(GameObject platformObject, TutorialStep step) {
|
||||
private void ConfigurePlatform(GameObject platformObject, CourseStep step) {
|
||||
Platform platform = platformObject.GetComponent<Platform>();
|
||||
|
||||
if(platform == null)
|
||||
@@ -454,12 +418,12 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
return;
|
||||
}
|
||||
|
||||
platform.ConfigureForTutorial(Platform.PlatformPattern.Empty, step.mileagePattern, step.slideLayout, step.itemPattern, mapPlatformSkin);
|
||||
platform.ConfigureForTutorial(step.mileagePattern, step.itemPattern, mapPlatformSkin);
|
||||
|
||||
// 설명은 발판 생성 시점이 아니라 실제 체험 직전에 RegisterTutorialGuide가 띄운다.
|
||||
}
|
||||
|
||||
private float GetStepSpawnInterval(TutorialStep step) {
|
||||
private float GetStepSpawnInterval(CourseStep step) {
|
||||
float spawnInterval;
|
||||
|
||||
if(step != null && step.spawnInterval > 0f)
|
||||
@@ -479,7 +443,7 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
return Mathf.Max(0.05f, spawnInterval);
|
||||
}
|
||||
|
||||
private TutorialStep GetCurrentCourseStep() {
|
||||
private CourseStep GetCurrentCourseStep() {
|
||||
EnsurePatternSteps();
|
||||
|
||||
if(tutorialMode && courseStepIndex < tutorialSteps.Length)
|
||||
@@ -525,23 +489,28 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
return;
|
||||
}
|
||||
|
||||
tutorialSteps = new TutorialStep[] {
|
||||
CreateTutorialStep(TutorialStepKind.Jump, Platform.PlatformPattern.LowMid, Platform.MileagePattern.JumpArc, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackActionSpacing),
|
||||
CreateTutorialStep(TutorialStepKind.None, Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackLandingSpacing),
|
||||
CreateTutorialStep(TutorialStepKind.DoubleJumpTakeoff, Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackAerialSpacing),
|
||||
CreateTutorialStep(TutorialStepKind.None, Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackLandingSpacing),
|
||||
CreateTutorialStep(TutorialStepKind.Slide, Platform.PlatformPattern.Slide, Platform.MileagePattern.SlideLine, SlideObstaclePattern.SlideLayout.CenterPair, FallbackGroundY, FallbackActionSpacing),
|
||||
CreateTutorialStep(TutorialStepKind.None, Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackLandingSpacing),
|
||||
CreateTutorialStep(TutorialStepKind.ForceHit, Platform.PlatformPattern.ForceHit, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.WidePair, FallbackGroundY, FallbackActionSpacing),
|
||||
CreateTutorialStep(TutorialStepKind.HealthItem, Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackLandingSpacing, Platform.ItemPattern.HealthSushi),
|
||||
CreateTutorialStep(TutorialStepKind.InvincibleItem, Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackBasicSpacing, Platform.ItemPattern.InvincibleRamen),
|
||||
CreateTutorialStep(TutorialStepKind.None, Platform.PlatformPattern.ForceHit, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.WidePair, FallbackGroundY, FallbackActionSpacing),
|
||||
CreateTutorialStep(TutorialStepKind.ShieldItem, Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackBasicSpacing, Platform.ItemPattern.Shield),
|
||||
CreateTutorialStep(TutorialStepKind.None, Platform.PlatformPattern.ForceHit, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.WidePair, FallbackGroundY, FallbackActionSpacing),
|
||||
CreateTutorialStep(TutorialStepKind.SpeedItem, Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackBasicSpacing, Platform.ItemPattern.SpeedShoes),
|
||||
CreateTutorialStep(TutorialStepKind.MileageCardItem, Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackBasicSpacing, Platform.ItemPattern.MileageCard),
|
||||
CreateTutorialStep(TutorialStepKind.None, Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackBasicSpacing),
|
||||
CreateTutorialStep(TutorialStepKind.None, Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackBasicSpacing),
|
||||
tutorialSteps = new CourseStep[] {
|
||||
CreateTutorialStep(CourseStepKind.Jump, Platform.PlatformPattern.LowMid, Platform.MileagePattern.JumpArc, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackActionSpacing),
|
||||
CreateTutorialStep(CourseStepKind.None, Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackLandingSpacing),
|
||||
CreateTutorialStep(CourseStepKind.DoubleJumpTakeoff, Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackAerialSpacing),
|
||||
CreateTutorialStep(CourseStepKind.None, Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackLandingSpacing),
|
||||
CreateTutorialStep(CourseStepKind.Slide, Platform.PlatformPattern.Slide, Platform.MileagePattern.SlideLine, SlideObstaclePattern.SlideLayout.CenterPair, FallbackGroundY, FallbackActionSpacing),
|
||||
CreateTutorialStep(CourseStepKind.None, Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackLandingSpacing),
|
||||
CreateTutorialStep(CourseStepKind.ForceHit, Platform.PlatformPattern.ForceHit, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.WidePair, FallbackGroundY, FallbackActionSpacing),
|
||||
CreateTutorialStep(CourseStepKind.HealthItem, Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackLandingSpacing, Platform.ItemPattern.HealthSushi),
|
||||
CreateTutorialStep(CourseStepKind.InvincibleItem, Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackBasicSpacing, Platform.ItemPattern.InvincibleRamen),
|
||||
CreateTutorialStep(CourseStepKind.None, Platform.PlatformPattern.ForceHit, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.WidePair, FallbackGroundY, FallbackActionSpacing),
|
||||
CreateTutorialStep(CourseStepKind.None, Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackLandingSpacing),
|
||||
CreateTutorialStep(CourseStepKind.None, Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackBasicSpacing),
|
||||
CreateTutorialStep(CourseStepKind.None, Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackBasicSpacing),
|
||||
CreateTutorialStep(CourseStepKind.ShieldItem, Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackBasicSpacing, Platform.ItemPattern.Shield),
|
||||
CreateTutorialStep(CourseStepKind.None, Platform.PlatformPattern.ForceHit, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.WidePair, FallbackGroundY, FallbackActionSpacing),
|
||||
CreateTutorialStep(CourseStepKind.MileageCardItem, Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackBasicSpacing, Platform.ItemPattern.MileageCard),
|
||||
CreateTutorialStep(CourseStepKind.None, Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackBasicSpacing),
|
||||
CreateTutorialStep(CourseStepKind.None, Platform.PlatformPattern.ForceHit, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.WidePair, FallbackGroundY, FallbackActionSpacing),
|
||||
CreateTutorialStep(CourseStepKind.SpeedItem, Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackBasicSpacing, Platform.ItemPattern.SpeedShoes),
|
||||
CreateTutorialStep(CourseStepKind.None, Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackBasicSpacing),
|
||||
CreateTutorialStep(CourseStepKind.None, Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, FallbackGroundY, FallbackBasicSpacing),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -551,7 +520,7 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
return;
|
||||
}
|
||||
|
||||
stagePatternSteps = new TutorialStep[] {
|
||||
stagePatternSteps = new CourseStep[] {
|
||||
CreateStep(Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, FallbackGroundY, FallbackBasicSpacing, "", ""),
|
||||
CreateStep(Platform.PlatformPattern.LowMid, Platform.MileagePattern.JumpArc, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, FallbackGroundY, FallbackActionSpacing, "", "", Platform.ItemPattern.None, CoursePlatformType.Jump),
|
||||
CreateStep(Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, FallbackGroundY, FallbackLandingSpacing, "", ""),
|
||||
@@ -569,7 +538,7 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
};
|
||||
}
|
||||
|
||||
private TutorialStep CreateStep(
|
||||
private CourseStep CreateStep(
|
||||
Platform.PlatformPattern platformPattern,
|
||||
Platform.MileagePattern mileagePattern,
|
||||
SlideObstaclePattern.SlideLayout slideLayout,
|
||||
@@ -580,7 +549,7 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
string message,
|
||||
Platform.ItemPattern itemPattern = Platform.ItemPattern.None,
|
||||
CoursePlatformType coursePlatformType = CoursePlatformType.Basic) {
|
||||
TutorialStep step = new TutorialStep();
|
||||
CourseStep step = new CourseStep();
|
||||
step.coursePlatformType = coursePlatformType;
|
||||
step.platformPattern = platformPattern;
|
||||
step.mileagePattern = mileagePattern;
|
||||
@@ -594,8 +563,8 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
return step;
|
||||
}
|
||||
|
||||
private TutorialStep CreateTutorialStep(
|
||||
TutorialStepKind stepKind,
|
||||
private CourseStep CreateTutorialStep(
|
||||
CourseStepKind stepKind,
|
||||
Platform.PlatformPattern platformPattern,
|
||||
Platform.MileagePattern mileagePattern,
|
||||
SlideObstaclePattern.SlideLayout slideLayout,
|
||||
@@ -608,47 +577,47 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
|
||||
switch(stepKind)
|
||||
{
|
||||
case TutorialStepKind.Jump:
|
||||
case CourseStepKind.Jump:
|
||||
guideType = GameManager.TutorialGuideType.Jump;
|
||||
title = "점프";
|
||||
message = "가방 장애물이 보이면 왼쪽 클릭으로 뛰어넘습니다.";
|
||||
break;
|
||||
case TutorialStepKind.DoubleJumpTakeoff:
|
||||
case CourseStepKind.DoubleJumpTakeoff:
|
||||
guideType = GameManager.TutorialGuideType.DoubleJump;
|
||||
title = "2단 점프";
|
||||
message = "다음 발판이 멀리 있으면 공중에서 한 번 더 왼쪽 클릭합니다.";
|
||||
break;
|
||||
case TutorialStepKind.Slide:
|
||||
case CourseStepKind.Slide:
|
||||
guideType = GameManager.TutorialGuideType.Slide;
|
||||
title = "슬라이드";
|
||||
message = "천장 표지판이 보이면 오른쪽 클릭을 누르고 지나갑니다.";
|
||||
break;
|
||||
case TutorialStepKind.ForceHit:
|
||||
case CourseStepKind.ForceHit:
|
||||
guideType = GameManager.TutorialGuideType.Damage;
|
||||
title = "피격";
|
||||
message = "이번 구간은 일부러 맞아 목숨과 속도 감소를 확인합니다.";
|
||||
break;
|
||||
case TutorialStepKind.HealthItem:
|
||||
case CourseStepKind.HealthItem:
|
||||
guideType = GameManager.TutorialGuideType.Items;
|
||||
title = "초밥";
|
||||
message = "초밥을 먹으면 잃은 목숨을 1 회복합니다.";
|
||||
break;
|
||||
case TutorialStepKind.InvincibleItem:
|
||||
case CourseStepKind.InvincibleItem:
|
||||
guideType = GameManager.TutorialGuideType.Items;
|
||||
title = "라멘";
|
||||
message = "라멘을 먹고 다음 충돌을 피해 없이 지나가 봅니다.";
|
||||
break;
|
||||
case TutorialStepKind.ShieldItem:
|
||||
case CourseStepKind.ShieldItem:
|
||||
guideType = GameManager.TutorialGuideType.Items;
|
||||
title = "방어막";
|
||||
message = "방어막을 먹고 다음 충돌 1회를 막아 봅니다.";
|
||||
break;
|
||||
case TutorialStepKind.SpeedItem:
|
||||
case CourseStepKind.SpeedItem:
|
||||
guideType = GameManager.TutorialGuideType.Items;
|
||||
title = "운동화";
|
||||
message = "운동화는 속도를 회복해 일정이 늦어지는 것을 줄입니다.";
|
||||
break;
|
||||
case TutorialStepKind.MileageCardItem:
|
||||
case CourseStepKind.MileageCardItem:
|
||||
guideType = GameManager.TutorialGuideType.Items;
|
||||
title = "마일리지 카드";
|
||||
message = "카드를 먹은 뒤 마일리지를 모으면 획득량이 늘어납니다.";
|
||||
@@ -668,18 +637,18 @@ public class PlatformSpawner : MonoBehaviour {
|
||||
GetCoursePlatformType(stepKind, platformPattern, yPosition));
|
||||
}
|
||||
|
||||
private CoursePlatformType GetCoursePlatformType(TutorialStepKind stepKind, Platform.PlatformPattern platformPattern, float yPosition) {
|
||||
if(stepKind == TutorialStepKind.ForceHit || platformPattern == Platform.PlatformPattern.ForceHit)
|
||||
private CoursePlatformType GetCoursePlatformType(CourseStepKind stepKind, Platform.PlatformPattern platformPattern, float yPosition) {
|
||||
if(stepKind == CourseStepKind.ForceHit || platformPattern == Platform.PlatformPattern.ForceHit)
|
||||
{
|
||||
return CoursePlatformType.ForceHit;
|
||||
}
|
||||
|
||||
if(stepKind == TutorialStepKind.Slide || platformPattern == Platform.PlatformPattern.Slide)
|
||||
if(stepKind == CourseStepKind.Slide || platformPattern == Platform.PlatformPattern.Slide)
|
||||
{
|
||||
return CoursePlatformType.Slide;
|
||||
}
|
||||
|
||||
if(stepKind == TutorialStepKind.Jump
|
||||
if(stepKind == CourseStepKind.Jump
|
||||
|| platformPattern == Platform.PlatformPattern.LowLeft
|
||||
|| platformPattern == Platform.PlatformPattern.LowMid
|
||||
|| platformPattern == Platform.PlatformPattern.LowRight)
|
||||
|
||||
+22
-1
@@ -9,11 +9,13 @@
|
||||
| 파일 | 용도 |
|
||||
| --- | --- |
|
||||
| `Assets/Resources/UI_LeftHudPassportHorizontalGridPanel.png` | 현재 적용 중인 가로형 왼쪽 여권 HUD 배경 |
|
||||
| `Assets/Resources/UI_LeftHudPassportCompactPanel.png` | 오른쪽 빈 장식 영역을 줄인 왼쪽 HUD 전용 컴팩트 여권 배경 |
|
||||
| `Assets/Resources/UI_LeftHudPassportPanel.png` | 이전 큰 세로형 왼쪽 여권 HUD 배경 |
|
||||
| `Assets/Resources/UI_PassportPanel.png` | 기존 작은 왼쪽 여권 HUD 배경 |
|
||||
| `Assets/Resources/UI_JJ_PassportPhoto.png` | 현재 적용 중인 JJ 여권사진 UI |
|
||||
| `Assets/Resources/UI_JJ_Face.png` | 플레이어 얼굴 UI |
|
||||
| `Assets/Resources/UI_LifeStamp.png` | 목숨 도장 |
|
||||
| `Assets/Resources/UI_DepartureStamp_Red.png` | 배경 없는 출국 도장 |
|
||||
| `Assets/Resources/UI_PassportItemSlot.png` | 아이템 슬롯 |
|
||||
| `Assets/Resources/Map_Tutorial_Incheon_Airport.png` | 튜토리얼 인천공항 배경 |
|
||||
| `Assets/Resources/Map_America_NewYork.png` | 미국 뉴욕 배경 |
|
||||
@@ -57,7 +59,8 @@
|
||||
|
||||
| 파일 | 용도 |
|
||||
| --- | --- |
|
||||
| `Assets/Resources/UI_LeftHudPassportHorizontalGridPanel.png` | 실제 적용하는 가로형 여권 2줄 그리드 HUD 런타임 PNG |
|
||||
| `Assets/Resources/UI_LeftHudPassportCompactPanel.png` | 실제 적용하는 컴팩트 가로형 여권 2줄 그리드 HUD 런타임 PNG |
|
||||
| `Assets/Resources/UI_LeftHudPassportHorizontalGridPanel.png` | 결과 화면과 원본 보관용 가로형 여권 2줄 그리드 HUD PNG |
|
||||
| `Assets/ConceptArt/left_hud_passport_horizontal_grid_panel_concept_01.png` | 가로형 여권 2줄 그리드 HUD 컨셉 원본 |
|
||||
| `Assets/Resources/UI_JJ_PassportPhoto.png` | 오프닝 만화의 JJ를 바탕으로 만든 현재 여권사진 런타임 PNG |
|
||||
| `Assets/ConceptArt/jj_passport_photo_concept_01.png` | JJ 여권사진 컨셉 원본 |
|
||||
@@ -96,6 +99,24 @@
|
||||
| `Assets/ConceptArt/right_hud_luggage_label_china_concept_01.png` | 가로형 중국 버전 컨셉 원본 |
|
||||
| `Assets/ConceptArt/right_hud_luggage_label_america_concept_01.png` | 가로형 미국 버전 컨셉 원본 |
|
||||
|
||||
## Result UI Assets
|
||||
|
||||
결과 화면은 여권 정산표처럼 필요한 정보만 간추려 보여줍니다.
|
||||
|
||||
| 파일 | 용도 |
|
||||
| --- | --- |
|
||||
| `Assets/Resources/UI_LeftHudPassportHorizontalGridPanel.png` | 결과 화면 여권 정산표 배경 |
|
||||
| `Assets/Resources/UI_DepartureStamp_Red.png` | `출국 성공!` 클리어 도장 |
|
||||
| `Assets/Sprites/UIIcons/UI_ClearRank.png` | 클리어 배지 |
|
||||
| `Assets/Sprites/UIIcons/UI_Mileage.png` | 마일리지 스탯 |
|
||||
| `Assets/Sprites/UIIcons/UI_Timer.png` | 도착 시간 스탯 |
|
||||
| `Assets/Sprites/UIIcons/UI_Checkpoint.png` | 이동 거리/목적지 스탯 |
|
||||
| `Assets/Sprites/UIIcons/UI_DutyFreeShop.png` | `면세점으로` 버튼 아이콘 |
|
||||
| `Assets/Sprites/UIIcons/UI_AirplaneTravel.png` | `다음 여행지 가기` 버튼 아이콘 |
|
||||
| `Assets/Resources/UI_TutorialNextButton.png` | 결과 화면 버튼 배경 |
|
||||
| `Assets/Resources/Map_Tutorial_Incheon_Airport.png` | 결과 화면 뒤 인천공항 배경 |
|
||||
| `Assets/Sprites/Souvenirs/` | 맵별 보상 기념품 표시 |
|
||||
|
||||
## Opening Story Assets
|
||||
|
||||
| 파일/폴더 | 용도 |
|
||||
|
||||
+23
-3
@@ -19,6 +19,7 @@ README.md
|
||||
| [gameplay.md](gameplay.md) | 조작, 장애물, 아이템, 클리어 조건 |
|
||||
| [maps.md](maps.md) | 맵별 배경, 도착 지점, 패턴 방향 |
|
||||
| [systems.md](systems.md) | 씬 흐름, 저장/로드, 면세점, 맵 해금 |
|
||||
| [refactor-plan.md](refactor-plan.md) | 스크립트 책임 분리와 리팩터링 순서 |
|
||||
| [feedback.md](feedback.md) | 날짜별 수정 기록과 다음 할 일 |
|
||||
|
||||
## 게임 핵심
|
||||
@@ -73,6 +74,9 @@ Intro
|
||||
|
||||
랜덤 배치가 아니라 검증된 패턴을 이어붙이는 방식으로 갑니다.
|
||||
|
||||
튜토리얼 코스와 일반 여행 맵 코스는 분리합니다.
|
||||
튜토리얼은 조작 학습과 아이템 체험을 담당하고, 일본/중국/미국은 일반 반복 패턴과 맵별 난이도 차이를 담당합니다.
|
||||
|
||||
```text
|
||||
기본 발판
|
||||
-> 점프 장애물
|
||||
@@ -85,6 +89,21 @@ Intro
|
||||
|
||||
이 방식은 플레이어가 왜 그 조작을 해야 하는지 실제로 체험하게 만듭니다.
|
||||
|
||||
## 현재 구조 정리 방향
|
||||
|
||||
현재 `GameFlowManager`, `GameManager`, `MapDatabase`, `PlatformSpawner`에 책임이 크게 모여 있습니다.
|
||||
동작을 바꾸기보다 책임을 분리하는 방향으로 정리합니다.
|
||||
|
||||
우선순위:
|
||||
|
||||
1. 완료: `PlatformSpawner.TutorialStep`을 `CourseStep`으로 독립
|
||||
2. 완료: 맵별 정의를 `Maps/Definitions`로 분리
|
||||
3. 튜토리얼/일본/중국/미국 코스를 `CourseProfile`로 분리
|
||||
4. 결과 화면, 면세점, 디버그 메뉴를 화면 View로 분리
|
||||
5. 게임 HUD와 튜토리얼 안내창을 `GameManager`에서 분리
|
||||
|
||||
자세한 기준은 [refactor-plan.md](refactor-plan.md)를 봅니다.
|
||||
|
||||
## 문서 운영 규칙
|
||||
|
||||
- `README.md`는 짧은 입구로 유지합니다.
|
||||
@@ -96,6 +115,7 @@ Intro
|
||||
|
||||
## 다음 작업 우선순위
|
||||
|
||||
1. 면세점 구매 아이템을 장착 슬롯과 연결
|
||||
2. 일본, 중국, 미국 맵의 실제 반복 패턴과 난이도 차별화
|
||||
3. 도착 지점 이미지의 실제 화면 크기를 플레이하면서 세부 조정
|
||||
1. 튜토리얼 코스와 일반 맵 코스를 `CourseProfile`로 분리
|
||||
2. `PlatformSpawner`의 fallback 코스 생성 책임 이동
|
||||
3. `GameFlowManager`의 화면 UI를 View 클래스로 분리
|
||||
4. 면세점 구매 아이템을 장착 슬롯과 연결
|
||||
|
||||
+13
-4
@@ -97,10 +97,17 @@ HUD:
|
||||
방향:
|
||||
|
||||
- 여행 정산표 느낌
|
||||
- 클리어/실패
|
||||
- 획득 마일리지
|
||||
- 보상 기념품
|
||||
- 면세점/다음 맵/재도전 버튼
|
||||
- 클리어 문구는 `출국 성공!`
|
||||
- 필요한 정보만 표시
|
||||
- 목적지
|
||||
- 획득 마일리지
|
||||
- 도착 시간
|
||||
- 이동 거리
|
||||
- 보상 기념품
|
||||
- 버튼은 클리어 시 `면세점으로`, 실패 시 `다시 도전`
|
||||
- 보조 버튼은 `인트로` 대신 `다음 여행지 가기`
|
||||
- 배경은 인천공항 배경을 사용
|
||||
- 여권 페이지, 출국 도장, 마일리지/시간/체크포인트/기념품 아이콘, 공항 안내 패널 버튼을 사용
|
||||
|
||||
## DutyFreeShop
|
||||
|
||||
@@ -110,6 +117,8 @@ HUD:
|
||||
- 상품 진열 중심
|
||||
- 보유 마일리지 표시
|
||||
- 다음 맵 이동은 오른쪽 방향성으로 안내
|
||||
- 면세점 내부 컨셉 배경 위에 도시락, 방어막, 운동화, 마일리지 카드 상품 카드를 배치
|
||||
- 상품 카드는 아이템 이미지, 효과, 보유 수량, 가격, 구매 상태를 함께 표시
|
||||
- 구매 아이템은 실제 장착 슬롯과 연결 예정
|
||||
|
||||
## MapPreview
|
||||
|
||||
+31
-3
@@ -19,18 +19,46 @@
|
||||
- 오른쪽 HUD에는 거리와 이번 판 적립 마일리지만 표시
|
||||
- 오른쪽 HUD는 맵에 따라 한국/일본/중국/미국 라벨을 자동으로 바꾸고, 원본 기준 약 60% 크기로 표시
|
||||
- 오른쪽 HUD 글자는 부모 스케일 축소 대신 실제 크기로 배치해 회색 번짐을 줄임
|
||||
- 튜토리얼 설명창 글자 위치를 오른쪽으로 조정
|
||||
- 슬라이드 안내 이미지를 더 낮게 숙인 프레임으로 교체
|
||||
- 라멘 무적 체험 뒤 방어막이 바로 나오지 않도록 안전 발판 간격 추가
|
||||
- 튜토리얼 아이템 순서를 `초밥 -> 라멘 -> 방어막 -> 마일리지 카드 -> 운동화`로 조정
|
||||
- 운동화 뒤에 속도 변화 설명과 출국 게이트까지 실전 연습 안내를 추가
|
||||
- `Platform.prefab`에서 내장 장애물을 제거하고 발판 전용 프리팹으로 정리
|
||||
- 출국 버튼 도장은 종이 배경이 같이 찍히지 않도록 투명 배경의 빨간 잉크 리소스로 교체
|
||||
- 2단 점프 설명 이미지의 `X2` 표시를 더 크게 조정하고 외곽선을 추가
|
||||
- 강제 피격 구간에서 점프 장애물과 슬라이드 장애물이 같은 위치에 겹치지 않도록 슬라이드 장애물 생성을 제거
|
||||
- 결과 화면을 `출국 성공!` 여권 정산표 형태로 변경하고, 마일리지/시간/거리/보상만 간추려 표시
|
||||
- 결과 화면 배경을 인천공항으로 바꾸고, 아이콘/글자/도장 위치를 여권 슬롯에 맞춰 재배치
|
||||
- 결과 화면의 `인트로` 버튼을 `다음 여행지 가기`로 바꾸고 기존 공항 안내 버튼 에셋을 적용
|
||||
- 결과 화면에서 `No cameras rendering` 경고가 뜨지 않도록 플로우 카메라를 보장하고, 버튼 글자를 밝은 색/외곽선으로 보정
|
||||
- 왼쪽 HUD는 오른쪽 빈 장식 영역을 줄인 컴팩트 여권 배경으로 교체하고, HP/아이템 슬롯 비율과 간격을 재조정
|
||||
- 면세점 화면을 내부 배경과 상품 카드형 UI로 교체하고, 도시락/방어막/운동화/마일리지 카드 구매 상태를 표시
|
||||
- `Esc` 디버그 메뉴로 인트로, 게임 시작, 출국 실패, 출국 성공, 면세점, 지도 화면을 바로 확인할 수 있게 수정
|
||||
- 스크립트 책임 분리 방향을 `Docs/refactor-plan.md`에 정리
|
||||
- 맵별 정의와 코스 패턴을 `CourseStep` / `CourseProfile` 중심으로 나누는 리팩터링 방향을 문서화
|
||||
- `PlatformSpawner.TutorialStep`을 독립 `CourseStep`, `CourseStepKind`, `CoursePlatformType` 파일로 분리
|
||||
- `MapDefinition`, `MapDatabase`, `GameManager`가 새 `CourseStep` 타입을 참조하도록 정리
|
||||
- `MapDatabase`의 맵별 생성 코드를 `Maps/Definitions/*Map.cs` 파일로 분리
|
||||
- 공통 코스 조각 생성과 복제 로직을 `CourseStepFactory`로 이동
|
||||
|
||||
### 현재 문제
|
||||
|
||||
- `GameFlowManager`에 화면 흐름과 UI 생성 코드가 함께 몰려 있음
|
||||
- `GameManager`에 플레이 진행, HUD, 튜토리얼, 도착 처리 코드가 함께 몰려 있음
|
||||
- 코스 배열은 아직 `CourseProfile`로 묶이지 않고 `openingSteps`, `loopSteps`로 직접 연결됨
|
||||
- `PlatformSpawner`에 fallback 코스 생성 코드가 아직 남아 있음
|
||||
- 면세점 구매 아이템이 아직 장착 슬롯과 연결되지 않음
|
||||
- 일본, 중국, 미국 맵의 실제 패턴과 난이도 차별화가 더 필요함
|
||||
- 새 HUD 이미지들은 실제 플레이 화면에서 위치와 글자 크기를 한 번 더 미세 조정할 수 있음
|
||||
|
||||
### 다음 할 일
|
||||
|
||||
1. 면세점 구매 아이템을 장착 슬롯과 연결
|
||||
2. 일본, 중국, 미국 맵의 실제 패턴과 난이도 차별화
|
||||
3. 새 HUD와 튜토리얼 안내창의 실제 플레이 화면 가독성 최종 확인
|
||||
1. 튜토리얼 코스와 일본/중국/미국 일반 코스를 `CourseProfile`로 분리
|
||||
2. `PlatformSpawner`의 fallback 코스 생성 책임을 `Course` 쪽으로 이동
|
||||
3. `GameFlowManager`의 결과 화면, 면세점, 디버그 메뉴 UI를 View 클래스로 분리
|
||||
4. `GameManager`의 HUD와 튜토리얼 안내창을 별도 스크립트로 분리
|
||||
5. 면세점 구매 아이템을 장착 슬롯과 연결
|
||||
|
||||
## 2026-07-06
|
||||
|
||||
|
||||
+35
-4
@@ -40,8 +40,9 @@
|
||||
1. 점프: 낮은 장애물 1개
|
||||
2. 2단 점프: 멀리 떨어진 발판
|
||||
3. 슬라이드: 천장 장애물
|
||||
4. 강제 피격: 일부러 맞아 목숨/속도 감소 체험
|
||||
5. 아이템: 각 아이템을 먹고 효과 체험
|
||||
4. 강제 피격: 낮은 장애물에 일부러 맞아 목숨/속도 감소 체험
|
||||
5. 아이템: 초밥, 라멘, 방어막, 마일리지 카드, 운동화 순서로 효과 체험
|
||||
6. 실전 연습: 속도 변화 설명 후 출국 게이트까지 주행
|
||||
|
||||
## 아이템
|
||||
|
||||
@@ -50,11 +51,11 @@
|
||||
| 초밥 | 목숨 1 회복 | 강제 피격 후 회복 |
|
||||
| 라멘 | 잠깐 무적 | 먹은 뒤 장애물 통과 |
|
||||
| 방어막 | 충돌 1회 방어 | 먹은 뒤 다음 충돌 방어 |
|
||||
| 운동화 | 속도 회복 | 피격 후 느려진 속도 회복 |
|
||||
| 마일리지 카드 | 마일리지 획득량 증가 | 먹은 뒤 마일리지 수집 |
|
||||
| 운동화 | 속도 회복 | 피격 후 느려진 속도 회복 |
|
||||
|
||||
아이템을 먹으면 짧은 링, 반짝임, 문구 이펙트가 떠서 획득 여부를 확인할 수 있습니다.
|
||||
라멘 무적 아이템의 현재 지속 시간은 `2.2초`입니다.
|
||||
라멘 무적 아이템의 현재 지속 시간은 `2.2초`이며, 튜토리얼에서는 방어막이 바로 이어지지 않도록 안전 발판을 사이에 둡니다.
|
||||
|
||||
점프 구간의 마일리지 코인은 플레이어가 뛰는 높이에 맞춰 넓고 높은 포물선으로 배치합니다.
|
||||
게임 속도가 빨라지면 코인 포물선의 가로 폭도 함께 넓혀 점프 타이밍과 맞춥니다.
|
||||
@@ -63,6 +64,8 @@
|
||||
## 코스 생성
|
||||
|
||||
현재 방향은 개별 랜덤 생성이 아니라 검증된 코스 조각을 순서대로 배치하는 방식입니다.
|
||||
코스 조각은 `CourseStep`으로 분리했습니다.
|
||||
다음 리팩터링에서는 여러 조각의 묶음을 `CourseProfile`로 분리합니다.
|
||||
|
||||
패턴 예시:
|
||||
|
||||
@@ -75,3 +78,31 @@
|
||||
- Finish
|
||||
|
||||
이 방식은 쿠키런식으로 계속 이어지는 기본 발판을 유지하면서도, 장애물과 아이템은 상황에 맞게 배치할 수 있습니다.
|
||||
|
||||
## CourseProfile 방향
|
||||
|
||||
튜토리얼과 일반 맵의 코스 목적을 분리합니다.
|
||||
|
||||
| 프로필 | 목적 |
|
||||
| --- | --- |
|
||||
| `TutorialCourseProfile` | 조작 학습, 강제 피격, 아이템 체험, 실전 연습 |
|
||||
| `JapanCourseProfile` | 쉬운 일반 반복 패턴 |
|
||||
| `ChinaCourseProfile` | 간격 변화와 점프/슬라이드 전환 |
|
||||
| `AmericaCourseProfile` | 빠른 속도와 후반 난이도 |
|
||||
|
||||
현재 `PlatformSpawner`는 `CourseStep` 배열을 순서대로 실행합니다.
|
||||
다음 목표는 코스 내용을 `CourseProfile`로 묶어, 스포너가 맵별 코스 정의를 직접 만들지 않게 하는 것입니다.
|
||||
|
||||
튜토리얼 전용 요소:
|
||||
|
||||
- 조작 안내 문구
|
||||
- 강제 피격 체험
|
||||
- 아이템 설명 트리거
|
||||
- 출국 게이트 전 실전 연습 안내
|
||||
|
||||
일반 맵 전용 요소:
|
||||
|
||||
- 반복 가능한 점프/슬라이드 조합
|
||||
- 맵별 장애물 스킨
|
||||
- 맵별 속도와 간격 차이
|
||||
- 보상 마일리지와 도착 지점 연출
|
||||
|
||||
+64
-4
@@ -20,6 +20,42 @@
|
||||
- `openingSteps`
|
||||
- `loopSteps`
|
||||
|
||||
리팩터링 목표:
|
||||
|
||||
- `openingSteps`, `loopSteps`는 `CourseProfile` 기반 이름으로 정리합니다.
|
||||
- `PlatformSpawner.TutorialStep`은 `CourseStep`으로 독립시켰습니다.
|
||||
- `MapDatabase`는 맵 목록 관리만 담당하고, 실제 맵 정의는 맵별 파일로 나눴습니다.
|
||||
|
||||
현재 구조:
|
||||
|
||||
```text
|
||||
MapDatabase
|
||||
-> Definitions/TutorialIncheonMap.cs
|
||||
-> Definitions/JapanMap.cs
|
||||
-> Definitions/ChinaMap.cs
|
||||
-> Definitions/AmericaMap.cs
|
||||
|
||||
Course
|
||||
-> TutorialCourseProfile.cs
|
||||
-> JapanCourseProfile.cs
|
||||
-> ChinaCourseProfile.cs
|
||||
-> AmericaCourseProfile.cs
|
||||
```
|
||||
|
||||
## 코스 분리 기준
|
||||
|
||||
튜토리얼과 일반 맵은 같은 구조를 복사하지 않습니다.
|
||||
|
||||
| 코스 | 목적 |
|
||||
| --- | --- |
|
||||
| Tutorial / Incheon | 조작 학습, 강제 피격, 아이템 효과 체험, 출국 게이트 실전 연습 |
|
||||
| Japan | 첫 일반 맵, 쉬운 점프/슬라이드 반복 패턴 |
|
||||
| China | 간격 변화, 연속 슬라이드/점프 확장 |
|
||||
| America | 빠른 속도, 후반 난이도, 긴 주행 압박 |
|
||||
|
||||
현재 `PlatformSpawner`는 맵이 가진 `CourseStep` 배열을 실행합니다.
|
||||
다음 목표는 맵별 코스를 `CourseProfile`로 묶어, 스포너가 현재 맵의 프로필만 실행하게 만드는 것입니다.
|
||||
|
||||
## Tutorial / Incheon
|
||||
|
||||
역할:
|
||||
@@ -45,8 +81,9 @@
|
||||
5. 초밥
|
||||
6. 라멘
|
||||
7. 방어막
|
||||
8. 운동화
|
||||
9. 마일리지 카드
|
||||
8. 마일리지 카드
|
||||
9. 운동화
|
||||
10. 실전 연습 후 출국 게이트
|
||||
|
||||
## Japan
|
||||
|
||||
@@ -54,6 +91,7 @@
|
||||
|
||||
- 첫 일반 여행 맵
|
||||
- 튜토리얼에서 배운 조작을 반복 패턴으로 사용
|
||||
- 튜토리얼 설명, 강제 피격 체험, 아이템 설명 트리거는 사용하지 않음
|
||||
|
||||
도착 지점:
|
||||
|
||||
@@ -66,12 +104,20 @@
|
||||
- 석등 낮은 장애물
|
||||
- 배너/표지판 슬라이드 장애물
|
||||
|
||||
코스 방향:
|
||||
|
||||
- 안전 발판으로 시작
|
||||
- 낮은 점프 장애물과 짧은 슬라이드를 번갈아 배치
|
||||
- 마일리지 코인은 점프 아크와 안전 라인 중심
|
||||
- 튜토리얼보다 긴 반복 패턴을 사용하되 난이도는 낮게 유지
|
||||
|
||||
## China
|
||||
|
||||
역할:
|
||||
|
||||
- 붉은색/금색 지역감
|
||||
- 슬라이드와 점프 패턴 확장
|
||||
- 일본보다 장애물 간격 변화가 큼
|
||||
|
||||
도착 지점:
|
||||
|
||||
@@ -84,12 +130,19 @@
|
||||
- 시장 상자 낮은 장애물
|
||||
- 홍등 슬라이드 장애물
|
||||
|
||||
코스 방향:
|
||||
|
||||
- 점프 뒤 슬라이드, 슬라이드 뒤 점프처럼 전환 패턴을 늘림
|
||||
- 마일리지 라인은 안전 구간과 위험 보상 구간을 구분
|
||||
- 튜토리얼용 강제 피격 패턴은 사용하지 않음
|
||||
|
||||
## America
|
||||
|
||||
역할:
|
||||
|
||||
- 뉴욕 도착 맵
|
||||
- 자유의 여신상에 도착하면 클리어되는 느낌
|
||||
- 후반 맵답게 속도와 반응 시간을 더 강하게 사용
|
||||
|
||||
배경:
|
||||
|
||||
@@ -107,13 +160,20 @@
|
||||
- 콘/도로 장애물
|
||||
- 배너/표지판 슬라이드 장애물
|
||||
|
||||
코스 방향:
|
||||
|
||||
- 넓은 점프와 짧은 슬라이드가 빠르게 이어짐
|
||||
- 안전 발판 비중은 줄이고 패턴 반복 속도를 올림
|
||||
- 도착 지점 전 마지막 구간은 시야가 복잡하지 않게 정리
|
||||
|
||||
## 맵 추가 규칙
|
||||
|
||||
새 맵을 추가할 때:
|
||||
|
||||
1. `MapId` 추가
|
||||
2. `MapDatabase`에 `CreateMap()` 추가
|
||||
2. `Maps/Definitions`에 맵별 정의 파일 추가
|
||||
3. 배경 이미지를 `Assets/Resources/Map_*.png`로 저장
|
||||
4. 도착 지점 이미지를 `Assets/Resources/FinishGate_*.png`로 저장
|
||||
5. `backgroundResourcePath`, `finishGateStyle` 연결
|
||||
6. `openingSteps`, `loopSteps` 구성
|
||||
6. `Course` 폴더에 해당 맵의 `CourseProfile` 추가
|
||||
7. `MapDatabase` 목록에 새 맵 연결
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
# Refactor Plan
|
||||
|
||||
스크립트가 커진 이유와 앞으로 나눌 구조를 정리합니다.
|
||||
이 문서는 실제 리팩터링 기준과 진행 상태를 함께 정리합니다.
|
||||
|
||||
## 목표
|
||||
|
||||
현재 목표는 기능을 바꾸는 것이 아니라 책임을 분리하는 것입니다.
|
||||
|
||||
- `GameFlowManager`는 화면 흐름만 관리
|
||||
- `GameManager`는 플레이 세션의 큰 흐름만 관리
|
||||
- 화면 UI는 화면별 View 클래스로 분리
|
||||
- 맵 데이터는 맵별 파일로 분리
|
||||
- 코스 패턴은 튜토리얼 전용과 일반 맵 전용으로 분리
|
||||
- `PlatformSpawner`는 코스를 직접 정의하지 않고 받은 코스만 실행
|
||||
|
||||
## 현재 문제
|
||||
|
||||
### GameFlowManager
|
||||
|
||||
현재 `GameFlowManager`가 담당하는 일이 너무 많습니다.
|
||||
|
||||
- 씬 흐름
|
||||
- 저장 데이터 처리
|
||||
- 결과 화면 UI 생성
|
||||
- 면세점 UI 생성
|
||||
- 인트로 UI 생성
|
||||
- 맵 프리뷰 UI 생성
|
||||
- 디버그 메뉴
|
||||
- 공통 UI 오브젝트 생성
|
||||
- 이미지/스프라이트 로딩
|
||||
|
||||
최종적으로는 흐름 제어만 남기고 화면 생성 코드는 `Flow/Screens`로 옮깁니다.
|
||||
|
||||
### GameManager
|
||||
|
||||
현재 `GameManager`도 플레이와 UI가 섞여 있습니다.
|
||||
|
||||
- 게임 시작/종료
|
||||
- 거리/시간/점수 계산
|
||||
- 목숨/피격/무적
|
||||
- 아이템 효과
|
||||
- 튜토리얼 설명창
|
||||
- 왼쪽/오른쪽 HUD
|
||||
- 도착 게이트 생성
|
||||
- 코스 미니맵 내부 클래스
|
||||
|
||||
최종적으로는 플레이 세션 관리만 남기고 HUD, 튜토리얼, 도착 게이트, 아이템 효과를 분리합니다.
|
||||
|
||||
### Map / Course
|
||||
|
||||
`PlatformSpawner.TutorialStep`은 독립 `CourseStep` 타입으로 분리했습니다.
|
||||
맵별 생성 코드는 `Maps/Definitions/*Map.cs`로 분리했습니다.
|
||||
아직 코스 배열은 `CourseProfile`로 묶이지 않고 `openingSteps`, `loopSteps`로 직접 연결되어 있습니다.
|
||||
|
||||
최종적으로는 `CourseProfile`을 독립 타입으로 만들고, 맵은 코스 프로필만 참조하게 합니다.
|
||||
|
||||
## 목표 폴더 구조
|
||||
|
||||
```text
|
||||
Assets/Scripts
|
||||
├─ Flow
|
||||
│ ├─ GameFlowManager.cs
|
||||
│ ├─ FlowScreen.cs
|
||||
│ ├─ FlowScreenContext.cs
|
||||
│ ├─ Screens
|
||||
│ │ ├─ IntroScreenView.cs
|
||||
│ │ ├─ OpeningStoryScreenView.cs
|
||||
│ │ ├─ ResultScreenView.cs
|
||||
│ │ ├─ DutyFreeShopView.cs
|
||||
│ │ ├─ MapPreviewScreenView.cs
|
||||
│ │ └─ DebugMenuView.cs
|
||||
│ └─ UI
|
||||
│ ├─ FlowUiFactory.cs
|
||||
│ └─ FlowAssetLoader.cs
|
||||
│
|
||||
├─ Gameplay
|
||||
│ ├─ GameManager.cs
|
||||
│ ├─ GameplaySession.cs
|
||||
│ ├─ StageProgressTracker.cs
|
||||
│ ├─ FinishGateController.cs
|
||||
│ ├─ ItemEffectController.cs
|
||||
│ └─ DamageController.cs
|
||||
│
|
||||
├─ Gameplay/UI
|
||||
│ ├─ GameplayHudView.cs
|
||||
│ ├─ TutorialGuideController.cs
|
||||
│ ├─ TutorialGuideView.cs
|
||||
│ └─ CourseMinimapView.cs
|
||||
│
|
||||
├─ Maps
|
||||
│ ├─ MapId.cs
|
||||
│ ├─ MapDefinition.cs
|
||||
│ ├─ MapDatabase.cs
|
||||
│ └─ Definitions
|
||||
│ ├─ TutorialIncheonMap.cs
|
||||
│ ├─ JapanMap.cs
|
||||
│ ├─ ChinaMap.cs
|
||||
│ └─ AmericaMap.cs
|
||||
│
|
||||
└─ Course
|
||||
├─ CourseStep.cs
|
||||
├─ CourseStepKind.cs
|
||||
├─ CoursePlatformType.cs
|
||||
├─ CourseStepFactory.cs
|
||||
├─ CourseProfile.cs
|
||||
├─ TutorialCourseProfile.cs
|
||||
├─ JapanCourseProfile.cs
|
||||
├─ ChinaCourseProfile.cs
|
||||
└─ AmericaCourseProfile.cs
|
||||
```
|
||||
|
||||
## 책임 분리 기준
|
||||
|
||||
### Flow
|
||||
|
||||
`GameFlowManager`는 다음만 담당합니다.
|
||||
|
||||
- 현재 화면 상태
|
||||
- 씬 이동
|
||||
- 저장 데이터 로드/저장
|
||||
- 게임 시작 요청
|
||||
- 결과 화면으로 이동
|
||||
- 다음 맵 선택
|
||||
|
||||
화면 구성은 각 View가 담당합니다.
|
||||
|
||||
| 화면 | 분리 대상 |
|
||||
| --- | --- |
|
||||
| Intro | `IntroScreenView` |
|
||||
| Opening Story | `OpeningStoryScreenView` |
|
||||
| Result | `ResultScreenView` |
|
||||
| DutyFreeShop | `DutyFreeShopView` |
|
||||
| MapPreview | `MapPreviewScreenView` |
|
||||
| Debug Menu | `DebugMenuView` |
|
||||
|
||||
공통 UI 생성은 `FlowUiFactory`, 에셋 로딩은 `FlowAssetLoader`로 옮깁니다.
|
||||
|
||||
### Gameplay
|
||||
|
||||
`GameManager`는 플레이 세션의 큰 흐름만 담당합니다.
|
||||
|
||||
| 책임 | 분리 대상 |
|
||||
| --- | --- |
|
||||
| 거리/시간/클리어 판정 | `StageProgressTracker` |
|
||||
| 도착 게이트 생성/정리 | `FinishGateController` |
|
||||
| 목숨/피격/무적/방어막 | `DamageController` |
|
||||
| 아이템 효과 | `ItemEffectController` |
|
||||
| 왼쪽/오른쪽 HUD | `GameplayHudView` |
|
||||
| 튜토리얼 안내창 표시 | `TutorialGuideView` |
|
||||
| 튜토리얼 단계 제어 | `TutorialGuideController` |
|
||||
| 코스 미니맵 | `CourseMinimapView` |
|
||||
|
||||
### Maps / Course
|
||||
|
||||
맵 데이터와 코스 실행을 분리합니다.
|
||||
|
||||
현재:
|
||||
|
||||
```text
|
||||
MapDefinition
|
||||
-> CourseStep[]
|
||||
-> Maps/Definitions/*Map.cs가 맵별 코스 배열을 직접 생성
|
||||
-> PlatformSpawner가 fallback 패턴도 직접 생성
|
||||
```
|
||||
|
||||
목표:
|
||||
|
||||
```text
|
||||
MapDefinition
|
||||
-> CourseProfile
|
||||
-> CourseStep[]
|
||||
-> PlatformSpawner는 CourseStep을 실행만 함
|
||||
```
|
||||
|
||||
튜토리얼과 일반 맵은 역할이 다릅니다.
|
||||
|
||||
| 코스 | 역할 |
|
||||
| --- | --- |
|
||||
| `TutorialCourseProfile` | 조작 학습, 강제 피격, 아이템 체험, 실전 연습 |
|
||||
| `JapanCourseProfile` | 첫 일반 맵, 쉬운 반복 패턴 |
|
||||
| `ChinaCourseProfile` | 간격 변화와 슬라이드/점프 확장 |
|
||||
| `AmericaCourseProfile` | 빠른 속도와 후반 난이도 |
|
||||
|
||||
## 진행 순서
|
||||
|
||||
1. 완료: `CourseStep` 분리
|
||||
- `PlatformSpawner.TutorialStep`을 독립 파일로 이동
|
||||
- `TutorialStep` 이름을 `CourseStep`으로 변경
|
||||
- `CourseStepKind`, `CoursePlatformType`도 독립 파일로 이동
|
||||
- 남은 이름 정리는 `CourseProfile` 분리 때 함께 진행
|
||||
|
||||
2. 완료: 맵 정의 파일 분리
|
||||
- `MapDatabase.cs`는 목록 관리만 담당
|
||||
- `TutorialIncheonMap`, `JapanMap`, `ChinaMap`, `AmericaMap`으로 나눔
|
||||
|
||||
3. 다음: 코스 프로필 분리
|
||||
- 튜토리얼 코스와 일반 맵 코스를 각각 `CourseProfile`로 분리
|
||||
- 일본, 중국, 미국은 튜토리얼 패턴을 복붙하지 않음
|
||||
|
||||
4. `GameFlowManager` 화면 View 분리
|
||||
- 결과 화면, 면세점, 디버그 메뉴부터 분리
|
||||
- 위치 조정 중인 UI 값은 유지한 채 파일만 나눔
|
||||
|
||||
5. `GameManager` UI/진행 분리
|
||||
- HUD와 튜토리얼 안내창을 먼저 분리
|
||||
- 이후 도착 게이트, 아이템, 피격 처리 분리
|
||||
|
||||
6. 검증
|
||||
- 각 단계마다 `dotnet build Assembly-CSharp.csproj`
|
||||
- Unity Play 모드에서 `Esc` 디버그 메뉴로 화면 확인
|
||||
- 튜토리얼, 일본, 중국, 미국 맵 진입 확인
|
||||
|
||||
## 주의 사항
|
||||
|
||||
- 기능 변경과 파일 분리를 동시에 많이 하지 않습니다.
|
||||
- UI 위치 조정이 끝난 화면은 좌표를 유지한 채 View로 옮깁니다.
|
||||
- 맵별 난이도 조정은 코스 구조 분리 후 진행합니다.
|
||||
- 삭제보다 이동을 우선하고, 빌드가 깨지지 않는 작은 단위로 진행합니다.
|
||||
+68
-4
@@ -5,6 +5,7 @@
|
||||
## Scene Flow
|
||||
|
||||
`GameFlowManager`가 전체 흐름을 관리합니다.
|
||||
다음 리팩터링 이후에는 `GameFlowManager`가 화면을 직접 그리지 않고, 화면별 View를 호출하는 구조로 정리합니다.
|
||||
|
||||
```text
|
||||
Intro
|
||||
@@ -37,6 +38,8 @@ Intro
|
||||
- `Assets/Scripts/Maps/MapId.cs`
|
||||
- `Assets/Scripts/Maps/MapDefinition.cs`
|
||||
- `Assets/Scripts/Maps/MapDatabase.cs`
|
||||
- `Assets/Scripts/Maps/Definitions/*.cs`
|
||||
- `Assets/Scripts/Course/*.cs`
|
||||
|
||||
역할:
|
||||
|
||||
@@ -50,6 +53,27 @@ Intro
|
||||
- 다음 맵
|
||||
- 코스 패턴
|
||||
|
||||
현재는 `MapDefinition`이 독립 타입인 `CourseStep[]` 형태의 `openingSteps`, `loopSteps`를 들고 있습니다.
|
||||
맵 생성 코드는 `Maps/Definitions/*Map.cs`로 분리했습니다.
|
||||
다음 리팩터링에서는 `CourseProfile`을 만들고 맵별 파일에서 코스 프로필을 연결합니다.
|
||||
|
||||
목표 구조:
|
||||
|
||||
```text
|
||||
MapDatabase
|
||||
-> TutorialIncheonMap.Create()
|
||||
-> JapanMap.Create()
|
||||
-> ChinaMap.Create()
|
||||
-> AmericaMap.Create()
|
||||
|
||||
MapDefinition
|
||||
-> CourseProfile openingCourse
|
||||
-> CourseProfile loopCourse
|
||||
|
||||
PlatformSpawner
|
||||
-> CourseProfile 실행
|
||||
```
|
||||
|
||||
## Gameplay Runtime
|
||||
|
||||
관련 파일:
|
||||
@@ -73,20 +97,60 @@ Intro
|
||||
- 아이템 획득/방어 성공 이펙트
|
||||
- 도착 지점 통과 시 클리어
|
||||
|
||||
현재 `GameManager`는 플레이 진행과 UI를 함께 담당합니다.
|
||||
리팩터링 후에는 아래처럼 책임을 나눕니다.
|
||||
|
||||
| 책임 | 목표 스크립트 |
|
||||
| --- | --- |
|
||||
| 플레이 세션 총괄 | `GameManager` |
|
||||
| 거리/시간/클리어 판정 | `StageProgressTracker` |
|
||||
| 도착 게이트 생성/정리 | `FinishGateController` |
|
||||
| 목숨/피격/무적/방어막 | `DamageController` |
|
||||
| 아이템 효과 | `ItemEffectController` |
|
||||
| 왼쪽/오른쪽 HUD | `GameplayHudView` |
|
||||
| 튜토리얼 안내창 | `TutorialGuideView` |
|
||||
| 튜토리얼 단계 제어 | `TutorialGuideController` |
|
||||
|
||||
## Flow UI
|
||||
|
||||
현재 상태:
|
||||
|
||||
- `GameFlowManager` 안에 결과 화면, 면세점, 인트로, 맵 프리뷰, 디버그 메뉴 UI 생성 코드가 들어 있음
|
||||
- 공통 UI 오브젝트 생성과 에셋 로딩도 같은 파일에 있음
|
||||
|
||||
목표 구조:
|
||||
|
||||
| 책임 | 목표 스크립트 |
|
||||
| --- | --- |
|
||||
| 흐름 제어 | `GameFlowManager` |
|
||||
| 현재 화면 상태와 공통 데이터 | `FlowScreenContext` |
|
||||
| 인트로 화면 | `IntroScreenView` |
|
||||
| 오프닝 스토리 | `OpeningStoryScreenView` |
|
||||
| 결과 화면 | `ResultScreenView` |
|
||||
| 면세점 화면 | `DutyFreeShopView` |
|
||||
| 맵 프리뷰 | `MapPreviewScreenView` |
|
||||
| 디버그 메뉴 | `DebugMenuView` |
|
||||
| 공통 UI 생성 | `FlowUiFactory` |
|
||||
| UI 에셋 로딩 | `FlowAssetLoader` |
|
||||
|
||||
디버그 메뉴는 현재 `Esc`로 열며, 인트로/게임 시작/출국 실패/출국 성공/면세점/지도 화면으로 바로 이동합니다.
|
||||
리팩터링 후에도 개발 빌드 전용 기능으로 유지합니다.
|
||||
|
||||
## DutyFreeShop
|
||||
|
||||
현재 상태:
|
||||
|
||||
- 화면 흐름은 있음
|
||||
- 코드 오버레이 화면은 면세점 내부 배경과 상품 카드형 UI로 표시함
|
||||
- 도시락, 방어막, 운동화, 마일리지 카드의 보유 수량과 가격을 표시함
|
||||
- 구매 데이터 저장은 있음
|
||||
- 실제 장착 슬롯과 플레이 시작 전 준비 구조는 아직 미완성
|
||||
|
||||
다음 방향:
|
||||
|
||||
1. 면세점 구매 아이템을 보유 수량으로 표시
|
||||
2. 스테이지 시작 전 장착 슬롯에 넣기
|
||||
3. 가방 업그레이드로 슬롯 수 증가
|
||||
4. 스테이지 중 장착 아이템 사용/소모
|
||||
1. 스테이지 시작 전 장착 슬롯에 넣기
|
||||
2. 가방 업그레이드로 슬롯 수 증가
|
||||
3. 스테이지 중 장착 아이템 사용/소모
|
||||
|
||||
## Finish Gate
|
||||
|
||||
|
||||
Reference in New Issue
Block a user