feat(platforms): add new platform types and implement lever functionality
This commit is contained in:
parent
a4ebcd4d6f
commit
05a1469725
@ -128,7 +128,7 @@ AnimatorStateMachine:
|
||||
m_Position: {x: 520, y: -280, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: -7985827421827872045}
|
||||
m_Position: {x: 520, y: -160, z: 0}
|
||||
m_Position: {x: 520, y: -170, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: -234086058997577863}
|
||||
m_Position: {x: 520, y: -60, z: 0}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
311
Assets/Prefabs/Props/Lever.prefab
Normal file
311
Assets/Prefabs/Props/Lever.prefab
Normal file
@ -0,0 +1,311 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &609356841017142299
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2021945858374592067}
|
||||
- component: {fileID: 995760246805472318}
|
||||
m_Layer: 0
|
||||
m_Name: Lever_Base
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &2021945858374592067
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 609356841017142299}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0.5, y: 0.18, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 3607988290522455547}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!212 &995760246805472318
|
||||
SpriteRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 609356841017142299}
|
||||
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: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 0
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 1
|
||||
m_Sprite: {fileID: 742792760, guid: f8c847d5cac325b47a5a48506f30eff7, type: 3}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_FlipX: 0
|
||||
m_FlipY: 0
|
||||
m_DrawMode: 0
|
||||
m_Size: {x: 0.73, y: 0.36}
|
||||
m_AdaptiveModeThreshold: 0.5
|
||||
m_SpriteTileMode: 0
|
||||
m_WasSpriteAssigned: 1
|
||||
m_MaskInteraction: 0
|
||||
m_SpriteSortPoint: 0
|
||||
--- !u!1 &1436029135993153407
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1067377230144882428}
|
||||
m_Layer: 0
|
||||
m_Name: Stick
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1067377230144882428
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1436029135993153407}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0.38268343, w: 0.92387956}
|
||||
m_LocalPosition: {x: 0.5, y: 0.18, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 8317511111288633183}
|
||||
m_Father: {fileID: 3607988290522455547}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 45}
|
||||
--- !u!1 &2513619836281733522
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3607988290522455547}
|
||||
- component: {fileID: 914741219563962730}
|
||||
- component: {fileID: 6770219739503201904}
|
||||
m_Layer: 0
|
||||
m_Name: Lever
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &3607988290522455547
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2513619836281733522}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 1067377230144882428}
|
||||
- {fileID: 2021945858374592067}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!61 &914741219563962730
|
||||
BoxCollider2D:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2513619836281733522}
|
||||
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.5, y: 1}
|
||||
m_SpriteTilingProperty:
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
pivot: {x: 0, y: 0}
|
||||
oldSize: {x: 0, y: 0}
|
||||
newSize: {x: 0, y: 0}
|
||||
adaptiveTilingThreshold: 0
|
||||
drawMode: 0
|
||||
adaptiveTiling: 0
|
||||
m_AutoTiling: 0
|
||||
m_Size: {x: 3, y: 2}
|
||||
m_EdgeRadius: 0
|
||||
--- !u!114 &6770219739503201904
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2513619836281733522}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: ce80a76f2d1833941876252f2475b965, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Lever
|
||||
stick: {fileID: 1067377230144882428}
|
||||
leverBase: {fileID: 2021945858374592067}
|
||||
rotationAngle: 90
|
||||
rotationSpeed: 5
|
||||
--- !u!1 &4494697277844752984
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 8317511111288633183}
|
||||
- component: {fileID: 2278547409547904938}
|
||||
m_Layer: 0
|
||||
m_Name: Lever_Stick
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &8317511111288633183
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4494697277844752984}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0.001, y: 0.475, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1067377230144882428}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!212 &2278547409547904938
|
||||
SpriteRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4494697277844752984}
|
||||
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: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 0
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_Sprite: {fileID: 1927729786, guid: f8c847d5cac325b47a5a48506f30eff7, type: 3}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_FlipX: 0
|
||||
m_FlipY: 0
|
||||
m_DrawMode: 0
|
||||
m_Size: {x: 0.24, y: 0.59}
|
||||
m_AdaptiveModeThreshold: 0.5
|
||||
m_SpriteTileMode: 0
|
||||
m_WasSpriteAssigned: 1
|
||||
m_MaskInteraction: 0
|
||||
m_SpriteSortPoint: 0
|
||||
7
Assets/Prefabs/Props/Lever.prefab.meta
Normal file
7
Assets/Prefabs/Props/Lever.prefab.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc6d2a9c11b2eac42a960140407a33fb
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -100,7 +100,7 @@ CompositeCollider2D:
|
||||
m_CompositeOperation: 0
|
||||
m_CompositeOrder: 0
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_GeometryType: 0
|
||||
m_GeometryType: 1
|
||||
m_GenerationType: 0
|
||||
m_EdgeRadius: 0
|
||||
m_ColliderPaths:
|
||||
|
||||
@ -52,6 +52,10 @@ PrefabInstance:
|
||||
propertyPath: m_Name
|
||||
value: MovingPlatform
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8025066920931157874, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_GeometryType
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
|
||||
@ -52,6 +52,10 @@ PrefabInstance:
|
||||
propertyPath: m_Name
|
||||
value: ShiftingPlatform
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8025066920931157874, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_GeometryType
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
|
||||
83
Assets/Prefabs/Props/Platforms/TrajectoryPlatform.prefab
Normal file
83
Assets/Prefabs/Props/Platforms/TrajectoryPlatform.prefab
Normal file
@ -0,0 +1,83 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &3659765315877780117
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications:
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7368601649257520958, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: TrajectoryPlatform
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents:
|
||||
- targetCorrespondingSourceObject: {fileID: 7368601649257520958, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
insertIndex: -1
|
||||
addedObject: {fileID: -7142050134933705222}
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
--- !u!1 &6091277937240876459 stripped
|
||||
GameObject:
|
||||
m_CorrespondingSourceObject: {fileID: 7368601649257520958, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
m_PrefabInstance: {fileID: 3659765315877780117}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &-7142050134933705222
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6091277937240876459}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 89af0d17b8f24fa4ea9d4cbb01169c5f, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::TrajectoryPlatform
|
||||
moveSpeed: 5
|
||||
coordinates: []
|
||||
loop: 1
|
||||
attachPlayer: 1
|
||||
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7db3a0e7f73de1e4c8f5ad4b61d4097d
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
83
Assets/Prefabs/Props/Platforms/TriggeringPlatform.prefab
Normal file
83
Assets/Prefabs/Props/Platforms/TriggeringPlatform.prefab
Normal file
@ -0,0 +1,83 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &5972793445274325198
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications:
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6864733315602298511, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7368601649257520958, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: TriggeringPlatform
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents:
|
||||
- targetCorrespondingSourceObject: {fileID: 7368601649257520958, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
insertIndex: -1
|
||||
addedObject: {fileID: -5744794363907911638}
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
--- !u!1 &3792338571613016048 stripped
|
||||
GameObject:
|
||||
m_CorrespondingSourceObject: {fileID: 7368601649257520958, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
m_PrefabInstance: {fileID: 5972793445274325198}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &-5744794363907911638
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3792338571613016048}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: ea9b4f424a362c5449f2c099e4f3082d, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::RR.Game2D.Entities.Platforms.TriggeringPlatform
|
||||
moveSpeed: 1
|
||||
pathLength: 5
|
||||
moveDirection: 3
|
||||
attachPlayer: 1
|
||||
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e728f572052a1194dabe9481dea2d305
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -52,6 +52,10 @@ PrefabInstance:
|
||||
propertyPath: m_Name
|
||||
value: VanishingPlatform
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8025066920931157874, guid: 745f8f5963b5fe048a51dd7d435a8865, type: 3}
|
||||
propertyPath: m_GeometryType
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
@ -80,3 +84,4 @@ MonoBehaviour:
|
||||
vanishDuration: 0.5
|
||||
reappearDelay: 2
|
||||
reappearDuration: 0.5
|
||||
vanishStartDelay: 0.2
|
||||
|
||||
@ -34,7 +34,7 @@ TextureImporter:
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
@ -43,7 +43,7 @@ TextureImporter:
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteMode: 2
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
@ -106,9 +106,66 @@ TextureImporter:
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: WindowsStoreApps
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
sprites:
|
||||
- serializedVersion: 2
|
||||
name: Lever_Stick
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 24
|
||||
y: 37
|
||||
width: 24
|
||||
height: 59
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
customData:
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 6835a673e18a44345b14cb19b1c65209
|
||||
internalID: 1927729786
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
- serializedVersion: 2
|
||||
name: Lever_0
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 1
|
||||
width: 73
|
||||
height: 36
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
customData:
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 7d5354849e11acc4e9cc11b3c08bebf7
|
||||
internalID: 742792760
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
@ -122,7 +179,9 @@ TextureImporter:
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
nameFileIdTable:
|
||||
Lever_0: 742792760
|
||||
Lever_Stick: 1927729786
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31e4973578565bd448cb191ac2c707e5
|
||||
guid: bf491ba62b5d50d48b41ca23347f82d1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
@ -0,0 +1,50 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Lever
|
||||
m_Shader: {fileID: 4800000, guid: e260cfa7296ee7642b167f1eb5be5023, type: 3}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _AlphaTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: f8c847d5cac325b47a5a48506f30eff7, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MaskTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _NormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _EnableExternalAlpha: 0
|
||||
- _ZWrite: 0
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _RendererColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
m_AllowLocking: 1
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0cd3cbb27b17e294898e6b00b50f0948
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1658,6 +1658,7 @@ Transform:
|
||||
m_Children:
|
||||
- {fileID: 310989943}
|
||||
- {fileID: 658885398}
|
||||
- {fileID: 8762723050865976547}
|
||||
m_Father: {fileID: 1747659608}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &332519789
|
||||
@ -2672,6 +2673,7 @@ MonoBehaviour:
|
||||
vanishDuration: 0.5
|
||||
reappearDelay: 2
|
||||
reappearDuration: 0.5
|
||||
vanishStartDelay: 0.2
|
||||
--- !u!1 &556549583
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -3298,7 +3300,7 @@ Transform:
|
||||
m_GameObject: {fileID: 658885397}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: -13, y: 63, z: 0}
|
||||
m_LocalPosition: {x: 177, y: 63, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
@ -39803,6 +39805,68 @@ PrefabInstance:
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: ff70cd57edcbc3c439493cb8c61b9072, type: 3}
|
||||
--- !u!1001 &8762723050865976546
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 325799050}
|
||||
m_Modifications:
|
||||
- target: {fileID: 3012080002866914914, guid: 7db3a0e7f73de1e4c8f5ad4b61d4097d, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: -13
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3012080002866914914, guid: 7db3a0e7f73de1e4c8f5ad4b61d4097d, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: -2
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3012080002866914914, guid: 7db3a0e7f73de1e4c8f5ad4b61d4097d, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3012080002866914914, guid: 7db3a0e7f73de1e4c8f5ad4b61d4097d, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3012080002866914914, guid: 7db3a0e7f73de1e4c8f5ad4b61d4097d, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3012080002866914914, guid: 7db3a0e7f73de1e4c8f5ad4b61d4097d, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3012080002866914914, guid: 7db3a0e7f73de1e4c8f5ad4b61d4097d, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3012080002866914914, guid: 7db3a0e7f73de1e4c8f5ad4b61d4097d, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3012080002866914914, guid: 7db3a0e7f73de1e4c8f5ad4b61d4097d, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3012080002866914914, guid: 7db3a0e7f73de1e4c8f5ad4b61d4097d, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6101297246587189107, guid: 7db3a0e7f73de1e4c8f5ad4b61d4097d, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: TrajectoryPlatform_Common
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 7db3a0e7f73de1e4c8f5ad4b61d4097d, type: 3}
|
||||
--- !u!4 &8762723050865976547 stripped
|
||||
Transform:
|
||||
m_CorrespondingSourceObject: {fileID: 7894378856842464282, guid: 7db3a0e7f73de1e4c8f5ad4b61d4097d, type: 3}
|
||||
m_PrefabInstance: {fileID: 8762723050865976546}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!1660057539 &9223372036854775807
|
||||
SceneRoots:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -958,11 +958,11 @@ PrefabInstance:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8213225719790051476, guid: c95e72e011a10ca43a3cb1bd524cdc19, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 133.8579
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8213225719790051476, guid: c95e72e011a10ca43a3cb1bd524cdc19, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: -8.3745
|
||||
value: -8
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8213225719790051476, guid: c95e72e011a10ca43a3cb1bd524cdc19, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
|
||||
@ -6720,7 +6720,7 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.132, y: 0.5}
|
||||
m_AnchorMax: {x: 0.846, y: 0.77500004}
|
||||
m_AnchoredPosition: {x: -54.5, y: 5}
|
||||
m_AnchoredPosition: {x: -54.499996, y: 5}
|
||||
m_SizeDelta: {x: -107, y: -10}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &1474919456
|
||||
@ -10318,7 +10318,7 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.132, y: 0.21750003}
|
||||
m_AnchorMax: {x: 0.846, y: 0.5}
|
||||
m_AnchoredPosition: {x: -54.5, y: -79}
|
||||
m_AnchoredPosition: {x: -54.499996, y: -79}
|
||||
m_SizeDelta: {x: -107, y: -63}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &1959311160
|
||||
|
||||
@ -2,6 +2,10 @@
|
||||
|
||||
namespace RR.Common.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Интерфейс для объектов, которые могут быть возвращены к владельцу.
|
||||
/// Используется для реализации механики возврата брошенных объектов.
|
||||
/// </summary>
|
||||
public interface IRecallable
|
||||
{
|
||||
/// <summary>
|
||||
@ -12,6 +16,10 @@ namespace RR.Common.Interfaces
|
||||
public void Recall();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Интерфейс для объектов, которые могут быть подняты игроком.
|
||||
/// Реализуется объектами, которые можно подбирать и/или держать.
|
||||
/// </summary>
|
||||
public interface IPickable
|
||||
{
|
||||
/// <summary>
|
||||
@ -24,18 +32,52 @@ namespace RR.Common.Interfaces
|
||||
public bool TryPickup(GameObject newOwner, Transform optionalAttachPoint = null);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Интерфейс для объектов, которые могут получать и наносить урон.
|
||||
/// Реализуется всеми сущностями, имеющими систему здоровья.
|
||||
/// </summary>
|
||||
public interface IDamageable
|
||||
{
|
||||
/// <summary>
|
||||
/// Метод для получения урона объектом.
|
||||
/// </summary>
|
||||
/// <param name="amount">Количество урона</param>
|
||||
void TakeDamage(float amount);
|
||||
|
||||
/// <summary>
|
||||
/// Метод для восстановления здоровья объекта.
|
||||
/// </summary>
|
||||
/// <param name="amount">Количество восстанавливаемого здоровья</param>
|
||||
void Heal(float amount);
|
||||
|
||||
/// <summary>
|
||||
/// Метод для обработки смерти объекта.
|
||||
/// Вызывается когда здоровье достигает нуля или меньше.
|
||||
/// </summary>
|
||||
void Die();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Интерфейс для объектов, которые могут выполнять действие.
|
||||
/// Используется для интерактивных объектов в игре.
|
||||
/// </summary>
|
||||
public interface IActionable
|
||||
{
|
||||
/// <summary>
|
||||
/// Выполняет действие, связанное с объектом.
|
||||
/// Например, активация механизма, открытие двери и т.д.
|
||||
/// </summary>
|
||||
void PerformAction();
|
||||
}
|
||||
}
|
||||
|
||||
namespace RR.Game2D.Core.Managers.Interfaces
|
||||
{
|
||||
public interface ILauchable
|
||||
/// <summary>
|
||||
/// Интерфейс для объектов, которые могут быть запущены как снаряд.
|
||||
/// Реализуется объектами, которые можно бросать в определенном направлении.
|
||||
/// </summary>
|
||||
public interface ILaunchable
|
||||
{
|
||||
/// <summary>
|
||||
/// Метод для запуска объекта как снаряд
|
||||
@ -46,6 +88,10 @@ namespace RR.Game2D.Core.Managers.Interfaces
|
||||
public void Launch(Vector2 direction, float speed, GameObject thrower);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Интерфейс для объектов, которые могут отскакивать от поверхностей.
|
||||
/// Реализуется объектами с физикой отскока при столкновении.
|
||||
/// </summary>
|
||||
public interface IBouncy
|
||||
{
|
||||
|
||||
|
||||
@ -17,7 +17,11 @@ namespace RR.Common.Audio
|
||||
|
||||
private void OnEnable() => GameManager.Instance.PlayerSpawned += OnPlayerSpawned;
|
||||
|
||||
private void OnDisable() => GameManager.Instance.PlayerSpawned -= OnPlayerSpawned;
|
||||
private void OnDisable()
|
||||
{
|
||||
if (GameManager.Instance) GameManager.Instance.PlayerSpawned -= OnPlayerSpawned;
|
||||
}
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
|
||||
@ -6,7 +6,7 @@ using RR.Game2D.Core.Managers.Interfaces;
|
||||
namespace RR.Game2D.Entities.Projectiles
|
||||
{
|
||||
[RequireComponent(typeof(Rigidbody2D), typeof(Collider2D))]
|
||||
public abstract class Projectile2D : MonoBehaviour, ILauchable
|
||||
public abstract class Projectile2D : MonoBehaviour, ILaunchable
|
||||
{
|
||||
[Header("Базовые настройки")]
|
||||
[SerializeField] protected float initialSpeed = 15f;
|
||||
|
||||
99
Assets/Scripts/Entities/Props/Lever.cs
Normal file
99
Assets/Scripts/Entities/Props/Lever.cs
Normal file
@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
using RR.Common.Interfaces;
|
||||
|
||||
namespace RR.Game2D.Entities
|
||||
{
|
||||
[RequireComponent(typeof(Collider2D))]
|
||||
public class Lever : MonoBehaviour, IActionable
|
||||
{
|
||||
[Header("Управление")]
|
||||
[SerializeField] private InputActionReference activateKey;
|
||||
|
||||
[Header("Настройки частей рычага")]
|
||||
[SerializeField] private Transform stick;
|
||||
[SerializeField] private Transform leverBase;
|
||||
|
||||
[Header("Настройки поворота рычага")]
|
||||
[SerializeField] private float rotationAngle = 90f;
|
||||
[SerializeField] private float rotationSpeed = 5f;
|
||||
|
||||
[Header("События после активации")]
|
||||
[SerializeField] private UnityEvent onActivate;
|
||||
|
||||
private Quaternion _initialRotation;
|
||||
private Collider2D _collider;
|
||||
private bool _isActivated;
|
||||
private bool _canBeActivated = false;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_isActivated = false;
|
||||
// onActivate = new UnityEvent();
|
||||
|
||||
if (_collider == null) _collider = GetComponent<Collider2D>();
|
||||
if (_collider == null) _collider = gameObject.AddComponent<Collider2D>();
|
||||
if (!_collider.isTrigger) _collider.isTrigger = true;
|
||||
|
||||
if (stick == null)
|
||||
{
|
||||
Debug.LogError("Lever: Stick transform is not assigned!", this);
|
||||
}
|
||||
else
|
||||
{
|
||||
_initialRotation = stick.rotation;
|
||||
}
|
||||
|
||||
// activateKey.action.performed += OnActivateKey;
|
||||
activateKey.action.started += OnActivateKey;
|
||||
activateKey.action.Enable();
|
||||
}
|
||||
|
||||
private void OnTriggerEnter2D(Collider2D other)
|
||||
{
|
||||
if (!other.CompareTag("Player")) return;
|
||||
_canBeActivated = true;
|
||||
}
|
||||
|
||||
private void OnTriggerExit2D(Collider2D other)
|
||||
{
|
||||
if (!other.CompareTag("Player")) return;
|
||||
_canBeActivated = false;
|
||||
}
|
||||
|
||||
public void PerformAction()
|
||||
{
|
||||
StopAllCoroutines();
|
||||
StartCoroutine(RotateLever());
|
||||
|
||||
onActivate?.Invoke();
|
||||
}
|
||||
|
||||
private IEnumerator RotateLever()
|
||||
{
|
||||
// initialRotation = stick.rotation;
|
||||
Quaternion targetRotation = _initialRotation * Quaternion.Euler(0f, 0f, rotationAngle);
|
||||
float elapsedTime = 0f;
|
||||
|
||||
while (elapsedTime < rotationSpeed)
|
||||
{
|
||||
stick.rotation = Quaternion.Slerp(_initialRotation, targetRotation, elapsedTime / rotationSpeed);
|
||||
elapsedTime += Time.deltaTime;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
stick.rotation = targetRotation;
|
||||
_isActivated = true;
|
||||
}
|
||||
|
||||
private void OnActivateKey(InputAction.CallbackContext obj)
|
||||
{
|
||||
if (!_canBeActivated) return;
|
||||
PerformAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Entities/Props/Lever.cs.meta
Normal file
2
Assets/Scripts/Entities/Props/Lever.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce80a76f2d1833941876252f2475b965
|
||||
@ -1,5 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 530cb6df09ac2d74587e3db0e51f6f91
|
||||
guid: cc36b3c628aba664788d72de8fd885a7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using RR.Game2D.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RR.Game2D.Entities
|
||||
using RR.Game2D.Core;
|
||||
|
||||
namespace RR.Game2D.Entities.Platforms
|
||||
{
|
||||
public class MovingPlatform : MonoBehaviour
|
||||
{
|
||||
79
Assets/Scripts/Entities/Props/Platforms/ShiftingPlatform.cs
Normal file
79
Assets/Scripts/Entities/Props/Platforms/ShiftingPlatform.cs
Normal file
@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using RR.Game2D.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RR.Game2D.Entities.Platforms
|
||||
{
|
||||
public class ShiftingPlatform : MonoBehaviour
|
||||
{
|
||||
[Header("Настройки смещения платформы")]
|
||||
[SerializeField] private Vector3 shiftAmount = new Vector3(0f, 2f, 0f);
|
||||
[SerializeField] private float shiftDuration = 1f;
|
||||
[SerializeField] private Direction2D shiftDirection = Direction2D.Down;
|
||||
|
||||
[Header("Прикрепление игрока")]
|
||||
[SerializeField] private bool attachPlayer = true;
|
||||
|
||||
private Vector3 _startPosition;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_startPosition = transform.position;
|
||||
}
|
||||
|
||||
private void OnCollisionEnter2D(Collision2D other)
|
||||
{
|
||||
if (!other.gameObject.CompareTag("Player")) return;
|
||||
|
||||
if (attachPlayer) other.transform.SetParent(transform);
|
||||
|
||||
Vector3 shiftVector = shiftDirection switch
|
||||
{
|
||||
Direction2D.Down => Vector3.down * shiftAmount.y,
|
||||
Direction2D.Left => Vector3.left * shiftAmount.x,
|
||||
Direction2D.Right => Vector3.right * shiftAmount.x,
|
||||
Direction2D.Up => Vector3.up * shiftAmount.y,
|
||||
_ => Vector3.zero
|
||||
};
|
||||
|
||||
StopAllCoroutines();
|
||||
StartCoroutine(ShiftPlatform(shiftVector));
|
||||
}
|
||||
|
||||
private void OnCollisionExit2D(Collision2D other)
|
||||
{
|
||||
if (!other.gameObject.CompareTag("Player")) return;
|
||||
|
||||
if (attachPlayer) other.transform.SetParent(null);
|
||||
|
||||
Vector3 shiftVector = shiftDirection switch
|
||||
{
|
||||
Direction2D.Down => Vector3.up * shiftAmount.y,
|
||||
Direction2D.Left => Vector3.right * shiftAmount.x,
|
||||
Direction2D.Right => Vector3.left * shiftAmount.x,
|
||||
Direction2D.Up => Vector3.down * shiftAmount.y,
|
||||
_ => Vector3.zero
|
||||
};
|
||||
|
||||
StopAllCoroutines();
|
||||
StartCoroutine(ShiftPlatform(shiftVector));
|
||||
}
|
||||
|
||||
private IEnumerator ShiftPlatform(Vector3 shiftVector)
|
||||
{
|
||||
Vector3 initialPosition = transform.position;
|
||||
Vector3 finalPosition = initialPosition + shiftVector;
|
||||
float elapsedTime = 0f;
|
||||
|
||||
while (elapsedTime < shiftDuration)
|
||||
{
|
||||
transform.position = Vector3.Lerp(initialPosition, finalPosition, (elapsedTime / shiftDuration));
|
||||
elapsedTime += Time.deltaTime;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
transform.position = finalPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace RR.Game2D.Entities.Platforms
|
||||
{
|
||||
public class TrajectoryPlatform : MonoBehaviour
|
||||
{
|
||||
[Header("Настройки движения платформы")]
|
||||
[SerializeField] private float moveSpeed = 1f;
|
||||
[SerializeField] private Vector3[] coordinates;
|
||||
[SerializeField] private bool loop = true;
|
||||
|
||||
[Header("Прикрепление игрока")]
|
||||
[SerializeField] private bool attachPlayer = true;
|
||||
|
||||
private int _currentTargetIndex;
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (coordinates == null || coordinates.Length == 0) return;
|
||||
|
||||
// Определяем целевую точку
|
||||
Vector3 targetPoint = coordinates[_currentTargetIndex];
|
||||
|
||||
// Двигаем платформу к целевой точке
|
||||
transform.position = Vector3.MoveTowards(transform.position, targetPoint, moveSpeed * Time.fixedDeltaTime);
|
||||
|
||||
// Проверяем, достигли ли целевой точки
|
||||
if (!(Vector3.Distance(transform.position, targetPoint) < 0.01f)) return;
|
||||
if (loop)
|
||||
{
|
||||
// Режим зацикливания: переходим к следующей точке по кругу
|
||||
_currentTargetIndex = (_currentTargetIndex + 1) % (coordinates.Length + 1);
|
||||
|
||||
// Если вернулись к началу, корректируем индекс
|
||||
if (_currentTargetIndex == coordinates.Length)
|
||||
{
|
||||
_currentTargetIndex = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentTargetIndex++;
|
||||
if (_currentTargetIndex < coordinates.Length) return;
|
||||
transform.position = coordinates[0];
|
||||
_currentTargetIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCollisionEnter2D(Collision2D other)
|
||||
{
|
||||
if (!attachPlayer) return;
|
||||
if (!other.gameObject.CompareTag("Player")) return;
|
||||
other.transform.SetParent(transform);
|
||||
}
|
||||
|
||||
private void OnCollisionExit2D(Collision2D other)
|
||||
{
|
||||
if (!attachPlayer) return;
|
||||
if (!other.gameObject.CompareTag("Player")) return;
|
||||
other.transform.SetParent(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89af0d17b8f24fa4ea9d4cbb01169c5f
|
||||
@ -0,0 +1,61 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
using RR.Game2D.Core;
|
||||
|
||||
namespace RR.Game2D.Entities.Platforms
|
||||
{
|
||||
public class TriggeringPlatform : MonoBehaviour
|
||||
{
|
||||
[Header("Настройки движения платформы")]
|
||||
[SerializeField] private float moveSpeed = 3f;
|
||||
[SerializeField] private float pathLength = 5f;
|
||||
[SerializeField] private Direction2D moveDirection = Direction2D.Right;
|
||||
|
||||
[Header("Прикрепление игрока")]
|
||||
[SerializeField] private bool attachPlayer = true;
|
||||
|
||||
private Vector3 _startPosition;
|
||||
private Vector3 _endPosition;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_startPosition = transform.position;
|
||||
|
||||
_endPosition = moveDirection switch
|
||||
{
|
||||
Direction2D.Down => _startPosition + Vector3.down * pathLength,
|
||||
Direction2D.Left => _startPosition + Vector3.left * pathLength,
|
||||
Direction2D.Right => _startPosition + Vector3.right * pathLength,
|
||||
Direction2D.Up => _startPosition + Vector3.up * pathLength,
|
||||
_ => _startPosition
|
||||
};
|
||||
}
|
||||
|
||||
public void Move()
|
||||
{
|
||||
StopAllCoroutines();
|
||||
StartCoroutine(MovePlatform(_endPosition));
|
||||
}
|
||||
|
||||
public void MoveBack()
|
||||
{
|
||||
StopAllCoroutines();
|
||||
StartCoroutine(MovePlatform(_startPosition));
|
||||
}
|
||||
|
||||
private IEnumerator MovePlatform(Vector3 targetPosition)
|
||||
{
|
||||
while (transform.position != targetPosition)
|
||||
{
|
||||
transform.position = Vector3.MoveTowards(
|
||||
transform.position,
|
||||
targetPosition,
|
||||
Time.deltaTime * moveSpeed);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
transform.position = targetPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea9b4f424a362c5449f2c099e4f3082d
|
||||
259
Assets/Scripts/Entities/Props/Platforms/VanishingPlatform.cs
Normal file
259
Assets/Scripts/Entities/Props/Platforms/VanishingPlatform.cs
Normal file
@ -0,0 +1,259 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RR.Game2D.Entities.Platforms
|
||||
{
|
||||
public class VanishingPlatform : MonoBehaviour
|
||||
{
|
||||
[Header("Настройки исчезновения платформы")]
|
||||
[SerializeField] private float vanishDuration = 0.5f;
|
||||
[SerializeField] private float reappearDelay = 2f;
|
||||
[SerializeField] private float reappearDuration = 0.5f;
|
||||
[SerializeField, Min(0f)] private float vanishStartDelay = 0.2f;
|
||||
|
||||
private CompositeCollider2D _compositeCollider;
|
||||
private Rigidbody2D _rigidbody;
|
||||
private SpriteRenderer[] _spriteRenderers;
|
||||
private Coroutine _vanishCoroutine;
|
||||
private Coroutine _reappearCoroutine;
|
||||
private Coroutine _delayedVanishCoroutine;
|
||||
private Color[] _initialColors;
|
||||
|
||||
/// <summary>
|
||||
/// Кэширует необходимые компоненты и предупреждает, если чего-то не хватает.
|
||||
/// </summary>
|
||||
private void Awake()
|
||||
{
|
||||
_compositeCollider = GetComponent<CompositeCollider2D>();
|
||||
_rigidbody = GetComponent<Rigidbody2D>();
|
||||
_spriteRenderers = GetComponentsInChildren<SpriteRenderer>();
|
||||
|
||||
if (_compositeCollider == null)
|
||||
Debug.LogWarning($"[{nameof(VanishingPlatform)}] CompositeCollider2D не найден на {gameObject.name}.");
|
||||
|
||||
if (_rigidbody == null)
|
||||
Debug.LogWarning($"[{nameof(VanishingPlatform)}] Rigidbody2D не найден на {gameObject.name}. CompositeCollider2D требует Rigidbody2D.");
|
||||
|
||||
if (_spriteRenderers == null || _spriteRenderers.Length == 0)
|
||||
Debug.LogWarning($"[{nameof(VanishingPlatform)}] SpriteRenderer'ы не найдены на {gameObject.name} и его дочерних объектах.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Запускает отсрочку исчезновения при входе игрока на платформу.
|
||||
/// </summary>
|
||||
/// <param name="other">Коллизия, по которой определяем игрока.</param>
|
||||
private void OnCollisionEnter2D(Collision2D other)
|
||||
{
|
||||
if (!other.gameObject.CompareTag("Player")) return;
|
||||
|
||||
if (_delayedVanishCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_delayedVanishCoroutine);
|
||||
_delayedVanishCoroutine = null;
|
||||
}
|
||||
|
||||
// Если в процессе была корутина Reappear — её отменяем
|
||||
if (_reappearCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_reappearCoroutine);
|
||||
_reappearCoroutine = null;
|
||||
}
|
||||
|
||||
if (_vanishCoroutine != null)
|
||||
StopCoroutine(_vanishCoroutine);
|
||||
|
||||
// _vanishCoroutine = StartCoroutine(Vanish());
|
||||
_delayedVanishCoroutine = StartCoroutine(StartVanishWithDelay());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Останавливает исчезновение и инициирует процесс появления, когда игрок уходит.
|
||||
/// </summary>
|
||||
/// <param name="other">Коллизия выхода игрока.</param>
|
||||
private void OnCollisionExit2D(Collision2D other)
|
||||
{
|
||||
if (!other.gameObject.CompareTag("Player")) return;
|
||||
|
||||
if (_delayedVanishCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_delayedVanishCoroutine);
|
||||
_delayedVanishCoroutine = null;
|
||||
}
|
||||
|
||||
// Если в процессе была корутина Vanish — её отменяем
|
||||
if (_vanishCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_vanishCoroutine);
|
||||
_vanishCoroutine = null;
|
||||
}
|
||||
|
||||
if (_reappearCoroutine != null)
|
||||
StopCoroutine(_reappearCoroutine);
|
||||
|
||||
_reappearCoroutine = StartCoroutine(Reappear());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Плавно уменьшает альфу спрайтов до нуля и отключает физику платформы.
|
||||
/// </summary>
|
||||
private IEnumerator Vanish()
|
||||
{
|
||||
if (_spriteRenderers == null || _spriteRenderers.Length == 0)
|
||||
yield break; // нечего анимировать
|
||||
|
||||
// Сохраняем начальные цвета для всех рендереров (если ещё не сохранены)
|
||||
if (_initialColors == null || _initialColors.Length != _spriteRenderers.Length)
|
||||
{
|
||||
_initialColors = new Color[_spriteRenderers.Length];
|
||||
for (int i = 0; i < _spriteRenderers.Length; i++)
|
||||
_initialColors[i] = _spriteRenderers[i].color;
|
||||
}
|
||||
|
||||
// Запоминаем текущую альфу для каждого рендерера
|
||||
float[] startAlphas = new float[_spriteRenderers.Length];
|
||||
for (int i = 0; i < _spriteRenderers.Length; i++)
|
||||
startAlphas[i] = _spriteRenderers[i].color.a;
|
||||
|
||||
float elapsed = 0f;
|
||||
|
||||
while (elapsed < vanishDuration)
|
||||
{
|
||||
elapsed += Time.deltaTime;
|
||||
float t = vanishDuration > 0f ? Mathf.Clamp01(elapsed / vanishDuration) : 1f;
|
||||
|
||||
for (int i = 0; i < _spriteRenderers.Length; i++)
|
||||
{
|
||||
Color c = _initialColors[i];
|
||||
float alpha = Mathf.Lerp(startAlphas[i], 0f, t);
|
||||
_spriteRenderers[i].color = new Color(c.r, c.g, c.b, alpha);
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
// Принудительно установить 0 альфу
|
||||
for (int i = 0; i < _spriteRenderers.Length; i++)
|
||||
{
|
||||
Color c = _initialColors[i];
|
||||
_spriteRenderers[i].color = new Color(c.r, c.g, c.b, 0f);
|
||||
}
|
||||
|
||||
if (_rigidbody)
|
||||
_rigidbody.simulated = false; // отключаем Collider через Rigidbody2D
|
||||
|
||||
_vanishCoroutine = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Плавно возвращает платформу и повторно включает физику после задержки.
|
||||
/// </summary>
|
||||
private IEnumerator Reappear()
|
||||
{
|
||||
if (_spriteRenderers == null || _spriteRenderers.Length == 0)
|
||||
yield break; // нечего анимировать
|
||||
|
||||
// Убедимся, что у нас есть базовые цвета — если нет, прочитаем текущие
|
||||
if (_initialColors == null || _initialColors.Length != _spriteRenderers.Length)
|
||||
{
|
||||
_initialColors = new Color[_spriteRenderers.Length];
|
||||
for (int i = 0; i < _spriteRenderers.Length; i++)
|
||||
_initialColors[i] = _spriteRenderers[i].color;
|
||||
}
|
||||
|
||||
// Задержка перед появлением (как в предыдущей логике)
|
||||
yield return new WaitForSeconds(reappearDelay);
|
||||
|
||||
// Запоминаем текущую альфу для каждого рендерера
|
||||
float[] startAlphas = new float[_spriteRenderers.Length];
|
||||
for (int i = 0; i < _spriteRenderers.Length; i++)
|
||||
startAlphas[i] = _spriteRenderers[i].color.a;
|
||||
|
||||
float elapsed = 0f;
|
||||
|
||||
while (elapsed < reappearDuration)
|
||||
{
|
||||
elapsed += Time.deltaTime;
|
||||
float t = reappearDuration > 0f ? Mathf.Clamp01(elapsed / reappearDuration) : 1f;
|
||||
|
||||
for (int i = 0; i < _spriteRenderers.Length; i++)
|
||||
{
|
||||
Color c = _initialColors[i];
|
||||
float alpha = Mathf.Lerp(startAlphas[i], 1f, t);
|
||||
_spriteRenderers[i].color = new Color(c.r, c.g, c.b, alpha);
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
// Принудительно установить полную непрозрачность
|
||||
for (int i = 0; i < _spriteRenderers.Length; i++)
|
||||
{
|
||||
Color c = _initialColors[i];
|
||||
_spriteRenderers[i].color = new Color(c.r, c.g, c.b, 1f);
|
||||
}
|
||||
|
||||
if (_rigidbody)
|
||||
_rigidbody.simulated = true; // возвращаем физику
|
||||
|
||||
_reappearCoroutine = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Позволяет внешним системам сразу запустить исчезновение (без ожидания).
|
||||
/// </summary>
|
||||
public void TriggerVanish()
|
||||
{
|
||||
if (_delayedVanishCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_delayedVanishCoroutine);
|
||||
_delayedVanishCoroutine = null;
|
||||
}
|
||||
|
||||
if (_reappearCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_reappearCoroutine);
|
||||
_reappearCoroutine = null;
|
||||
}
|
||||
|
||||
if (_vanishCoroutine != null)
|
||||
StopCoroutine(_vanishCoroutine);
|
||||
|
||||
_vanishCoroutine = StartCoroutine(Vanish());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Позволяет внешним системам сразу запустить появление.
|
||||
/// </summary>
|
||||
public void TriggerReappear()
|
||||
{
|
||||
if (_delayedVanishCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_delayedVanishCoroutine);
|
||||
_delayedVanishCoroutine = null;
|
||||
}
|
||||
|
||||
if (_vanishCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_vanishCoroutine);
|
||||
_vanishCoroutine = null;
|
||||
}
|
||||
|
||||
if (_reappearCoroutine != null)
|
||||
StopCoroutine(_reappearCoroutine);
|
||||
|
||||
_reappearCoroutine = StartCoroutine(Reappear());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ожидает заданную задержку перед фактическим запуском корутины Vanish.
|
||||
/// </summary>
|
||||
private IEnumerator StartVanishWithDelay()
|
||||
{
|
||||
if (vanishStartDelay > 0f)
|
||||
yield return new WaitForSeconds(vanishStartDelay); // выдерживаем таймер ожидания
|
||||
|
||||
_vanishCoroutine = StartCoroutine(Vanish());
|
||||
_delayedVanishCoroutine = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,76 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using RR.Game2D.Core;
|
||||
using UnityEngine;
|
||||
|
||||
public class ShiftingPlatform : MonoBehaviour
|
||||
{
|
||||
[Header("Настройки смещения платформы")]
|
||||
[SerializeField] private Vector3 shiftAmount = new Vector3(0f, 2f, 0f);
|
||||
[SerializeField] private float shiftDuration = 1f;
|
||||
[SerializeField] private Direction2D shiftDirection = Direction2D.Down;
|
||||
|
||||
[Header("Прикрепление игрока")]
|
||||
[SerializeField] private bool attachPlayer = true;
|
||||
|
||||
private Vector3 _startPosition;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_startPosition = transform.position;
|
||||
}
|
||||
|
||||
private void OnCollisionEnter2D(Collision2D other)
|
||||
{
|
||||
if (!other.gameObject.CompareTag("Player")) return;
|
||||
|
||||
if (attachPlayer) other.transform.SetParent(transform);
|
||||
|
||||
Vector3 shiftVector = shiftDirection switch
|
||||
{
|
||||
Direction2D.Down => Vector3.down * shiftAmount.y,
|
||||
Direction2D.Left => Vector3.left * shiftAmount.x,
|
||||
Direction2D.Right => Vector3.right * shiftAmount.x,
|
||||
Direction2D.Up => Vector3.up * shiftAmount.y,
|
||||
_ => Vector3.zero
|
||||
};
|
||||
|
||||
StopAllCoroutines();
|
||||
StartCoroutine(ShiftPlatform(shiftVector));
|
||||
}
|
||||
|
||||
private void OnCollisionExit2D(Collision2D other)
|
||||
{
|
||||
if (!other.gameObject.CompareTag("Player")) return;
|
||||
|
||||
if (attachPlayer) other.transform.SetParent(null);
|
||||
|
||||
Vector3 shiftVector = shiftDirection switch
|
||||
{
|
||||
Direction2D.Down => Vector3.up * shiftAmount.y,
|
||||
Direction2D.Left => Vector3.right * shiftAmount.x,
|
||||
Direction2D.Right => Vector3.left * shiftAmount.x,
|
||||
Direction2D.Up => Vector3.down * shiftAmount.y,
|
||||
_ => Vector3.zero
|
||||
};
|
||||
|
||||
StopAllCoroutines();
|
||||
StartCoroutine(ShiftPlatform(shiftVector));
|
||||
}
|
||||
|
||||
private IEnumerator ShiftPlatform(Vector3 shiftVector)
|
||||
{
|
||||
Vector3 initialPosition = transform.position;
|
||||
Vector3 finalPosition = initialPosition + shiftVector;
|
||||
float elapsedTime = 0f;
|
||||
|
||||
while (elapsedTime < shiftDuration)
|
||||
{
|
||||
transform.position = Vector3.Lerp(initialPosition, finalPosition, (elapsedTime / shiftDuration));
|
||||
elapsedTime += Time.deltaTime;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
transform.position = finalPosition;
|
||||
}
|
||||
}
|
||||
@ -1,256 +0,0 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
public class VanishingPlatform : MonoBehaviour
|
||||
{
|
||||
[Header("Настройки исчезновения платформы")]
|
||||
[SerializeField] private float vanishDuration = 0.5f;
|
||||
[SerializeField] private float reappearDelay = 2f;
|
||||
[SerializeField] private float reappearDuration = 0.5f;
|
||||
[SerializeField, Min(0f)] private float vanishStartDelay = 0.2f;
|
||||
|
||||
private CompositeCollider2D _compositeCollider;
|
||||
private Rigidbody2D _rigidbody;
|
||||
private SpriteRenderer[] _spriteRenderers;
|
||||
private Coroutine _vanishCoroutine;
|
||||
private Coroutine _reappearCoroutine;
|
||||
private Coroutine _delayedVanishCoroutine;
|
||||
private Color[] _initialColors;
|
||||
|
||||
/// <summary>
|
||||
/// Кэширует необходимые компоненты и предупреждает, если чего-то не хватает.
|
||||
/// </summary>
|
||||
private void Awake()
|
||||
{
|
||||
_compositeCollider = GetComponent<CompositeCollider2D>();
|
||||
_rigidbody = GetComponent<Rigidbody2D>();
|
||||
_spriteRenderers = GetComponentsInChildren<SpriteRenderer>();
|
||||
|
||||
if (_compositeCollider == null)
|
||||
Debug.LogWarning($"[{nameof(VanishingPlatform)}] CompositeCollider2D не найден на {gameObject.name}.");
|
||||
|
||||
if (_rigidbody == null)
|
||||
Debug.LogWarning($"[{nameof(VanishingPlatform)}] Rigidbody2D не найден на {gameObject.name}. CompositeCollider2D требует Rigidbody2D.");
|
||||
|
||||
if (_spriteRenderers == null || _spriteRenderers.Length == 0)
|
||||
Debug.LogWarning($"[{nameof(VanishingPlatform)}] SpriteRenderer'ы не найдены на {gameObject.name} и его дочерних объектах.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Запускает отсрочку исчезновения при входе игрока на платформу.
|
||||
/// </summary>
|
||||
/// <param name="other">Коллизия, по которой определяем игрока.</param>
|
||||
private void OnCollisionEnter2D(Collision2D other)
|
||||
{
|
||||
if (!other.gameObject.CompareTag("Player")) return;
|
||||
|
||||
if (_delayedVanishCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_delayedVanishCoroutine);
|
||||
_delayedVanishCoroutine = null;
|
||||
}
|
||||
|
||||
// Если в процессе была корутина Reappear — её отменяем
|
||||
if (_reappearCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_reappearCoroutine);
|
||||
_reappearCoroutine = null;
|
||||
}
|
||||
|
||||
if (_vanishCoroutine != null)
|
||||
StopCoroutine(_vanishCoroutine);
|
||||
|
||||
// _vanishCoroutine = StartCoroutine(Vanish());
|
||||
_delayedVanishCoroutine = StartCoroutine(StartVanishWithDelay());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Останавливает исчезновение и инициирует процесс появления, когда игрок уходит.
|
||||
/// </summary>
|
||||
/// <param name="other">Коллизия выхода игрока.</param>
|
||||
private void OnCollisionExit2D(Collision2D other)
|
||||
{
|
||||
if (!other.gameObject.CompareTag("Player")) return;
|
||||
|
||||
if (_delayedVanishCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_delayedVanishCoroutine);
|
||||
_delayedVanishCoroutine = null;
|
||||
}
|
||||
|
||||
// Если в процессе была корутина Vanish — её отменяем
|
||||
if (_vanishCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_vanishCoroutine);
|
||||
_vanishCoroutine = null;
|
||||
}
|
||||
|
||||
if (_reappearCoroutine != null)
|
||||
StopCoroutine(_reappearCoroutine);
|
||||
|
||||
_reappearCoroutine = StartCoroutine(Reappear());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Плавно уменьшает альфу спрайтов до нуля и отключает физику платформы.
|
||||
/// </summary>
|
||||
private IEnumerator Vanish()
|
||||
{
|
||||
if (_spriteRenderers == null || _spriteRenderers.Length == 0)
|
||||
yield break; // нечего анимировать
|
||||
|
||||
// Сохраняем начальные цвета для всех рендереров (если ещё не сохранены)
|
||||
if (_initialColors == null || _initialColors.Length != _spriteRenderers.Length)
|
||||
{
|
||||
_initialColors = new Color[_spriteRenderers.Length];
|
||||
for (int i = 0; i < _spriteRenderers.Length; i++)
|
||||
_initialColors[i] = _spriteRenderers[i].color;
|
||||
}
|
||||
|
||||
// Запоминаем текущую альфу для каждого рендерера
|
||||
float[] startAlphas = new float[_spriteRenderers.Length];
|
||||
for (int i = 0; i < _spriteRenderers.Length; i++)
|
||||
startAlphas[i] = _spriteRenderers[i].color.a;
|
||||
|
||||
float elapsed = 0f;
|
||||
|
||||
while (elapsed < vanishDuration)
|
||||
{
|
||||
elapsed += Time.deltaTime;
|
||||
float t = vanishDuration > 0f ? Mathf.Clamp01(elapsed / vanishDuration) : 1f;
|
||||
|
||||
for (int i = 0; i < _spriteRenderers.Length; i++)
|
||||
{
|
||||
Color c = _initialColors[i];
|
||||
float alpha = Mathf.Lerp(startAlphas[i], 0f, t);
|
||||
_spriteRenderers[i].color = new Color(c.r, c.g, c.b, alpha);
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
// Принудительно установить 0 альфу
|
||||
for (int i = 0; i < _spriteRenderers.Length; i++)
|
||||
{
|
||||
Color c = _initialColors[i];
|
||||
_spriteRenderers[i].color = new Color(c.r, c.g, c.b, 0f);
|
||||
}
|
||||
|
||||
if (_rigidbody)
|
||||
_rigidbody.simulated = false; // отключаем Collider через Rigidbody2D
|
||||
|
||||
_vanishCoroutine = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Плавно возвращает платформу и повторно включает физику после задержки.
|
||||
/// </summary>
|
||||
private IEnumerator Reappear()
|
||||
{
|
||||
if (_spriteRenderers == null || _spriteRenderers.Length == 0)
|
||||
yield break; // нечего анимировать
|
||||
|
||||
// Убедимся, что у нас есть базовые цвета — если нет, прочитаем текущие
|
||||
if (_initialColors == null || _initialColors.Length != _spriteRenderers.Length)
|
||||
{
|
||||
_initialColors = new Color[_spriteRenderers.Length];
|
||||
for (int i = 0; i < _spriteRenderers.Length; i++)
|
||||
_initialColors[i] = _spriteRenderers[i].color;
|
||||
}
|
||||
|
||||
// Задержка перед появлением (как в предыдущей логике)
|
||||
yield return new WaitForSeconds(reappearDelay);
|
||||
|
||||
// Запоминаем текущую альфу для каждого рендерера
|
||||
float[] startAlphas = new float[_spriteRenderers.Length];
|
||||
for (int i = 0; i < _spriteRenderers.Length; i++)
|
||||
startAlphas[i] = _spriteRenderers[i].color.a;
|
||||
|
||||
float elapsed = 0f;
|
||||
|
||||
while (elapsed < reappearDuration)
|
||||
{
|
||||
elapsed += Time.deltaTime;
|
||||
float t = reappearDuration > 0f ? Mathf.Clamp01(elapsed / reappearDuration) : 1f;
|
||||
|
||||
for (int i = 0; i < _spriteRenderers.Length; i++)
|
||||
{
|
||||
Color c = _initialColors[i];
|
||||
float alpha = Mathf.Lerp(startAlphas[i], 1f, t);
|
||||
_spriteRenderers[i].color = new Color(c.r, c.g, c.b, alpha);
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
// Принудительно установить полную непрозрачность
|
||||
for (int i = 0; i < _spriteRenderers.Length; i++)
|
||||
{
|
||||
Color c = _initialColors[i];
|
||||
_spriteRenderers[i].color = new Color(c.r, c.g, c.b, 1f);
|
||||
}
|
||||
|
||||
if (_rigidbody)
|
||||
_rigidbody.simulated = true; // возвращаем физику
|
||||
|
||||
_reappearCoroutine = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Позволяет внешним системам сразу запустить исчезновение (без ожидания).
|
||||
/// </summary>
|
||||
public void TriggerVanish()
|
||||
{
|
||||
if (_delayedVanishCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_delayedVanishCoroutine);
|
||||
_delayedVanishCoroutine = null;
|
||||
}
|
||||
|
||||
if (_reappearCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_reappearCoroutine);
|
||||
_reappearCoroutine = null;
|
||||
}
|
||||
|
||||
if (_vanishCoroutine != null)
|
||||
StopCoroutine(_vanishCoroutine);
|
||||
|
||||
_vanishCoroutine = StartCoroutine(Vanish());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Позволяет внешним системам сразу запустить появление.
|
||||
/// </summary>
|
||||
public void TriggerReappear()
|
||||
{
|
||||
if (_delayedVanishCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_delayedVanishCoroutine);
|
||||
_delayedVanishCoroutine = null;
|
||||
}
|
||||
|
||||
if (_vanishCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_vanishCoroutine);
|
||||
_vanishCoroutine = null;
|
||||
}
|
||||
|
||||
if (_reappearCoroutine != null)
|
||||
StopCoroutine(_reappearCoroutine);
|
||||
|
||||
_reappearCoroutine = StartCoroutine(Reappear());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ожидает заданную задержку перед фактическим запуском корутины Vanish.
|
||||
/// </summary>
|
||||
private IEnumerator StartVanishWithDelay()
|
||||
{
|
||||
if (vanishStartDelay > 0f)
|
||||
yield return new WaitForSeconds(vanishStartDelay); // выдерживаем таймер ожидания
|
||||
|
||||
_vanishCoroutine = StartCoroutine(Vanish());
|
||||
_delayedVanishCoroutine = null;
|
||||
}
|
||||
}
|
||||
@ -1,143 +1,146 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections;
|
||||
|
||||
public class ScrollSelectionFollower : MonoBehaviour
|
||||
namespace RR.Common.UI
|
||||
{
|
||||
[SerializeField] private ScrollRect scrollRect;
|
||||
[SerializeField] private float padding = 8f; // отступы сверху/снизу/слева/справа
|
||||
[SerializeField] private float duration = 0.15f; // длительность анимации
|
||||
[SerializeField] private bool onlyWhenNotVisible = true; // если false — центрируем всегда
|
||||
|
||||
private GameObject _lastSelected;
|
||||
private Coroutine _anim;
|
||||
|
||||
private void Reset()
|
||||
public class ScrollSelectionFollower : MonoBehaviour
|
||||
{
|
||||
scrollRect = GetComponentInChildren<ScrollRect>();
|
||||
}
|
||||
[SerializeField] private ScrollRect scrollRect;
|
||||
[SerializeField] private float padding = 8f; // отступы сверху/снизу/слева/справа
|
||||
[SerializeField] private float duration = 0.15f; // длительность анимации
|
||||
[SerializeField] private bool onlyWhenNotVisible = true; // если false — центрируем всегда
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
GameObject sel = EventSystem.current ? EventSystem.current.currentSelectedGameObject : null;
|
||||
if (!sel || sel == _lastSelected) return;
|
||||
private GameObject _lastSelected;
|
||||
private Coroutine _anim;
|
||||
|
||||
// Только если элемент внутри нашего Content
|
||||
if (!scrollRect || sel.transform is not RectTransform tr || !tr.IsChildOf(scrollRect.content)) return;
|
||||
ScrollTo(tr);
|
||||
_lastSelected = sel;
|
||||
}
|
||||
|
||||
public void ScrollTo(RectTransform target)
|
||||
{
|
||||
if (!scrollRect || !target) return;
|
||||
|
||||
// Сначала убедимся, что лейауты посчитались
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
RectTransform content = scrollRect.content;
|
||||
RectTransform viewport = scrollRect.viewport != null ? scrollRect.viewport : (RectTransform)scrollRect.transform;
|
||||
|
||||
// Получаем мировые углы и преобразуем в локальное пространство viewport
|
||||
Vector3[] itemCorners = new Vector3[4];
|
||||
target.GetWorldCorners(itemCorners);
|
||||
|
||||
Vector3[] viewportCorners = new Vector3[4];
|
||||
viewport.GetWorldCorners(viewportCorners);
|
||||
|
||||
// Преобразуем в локальное пространство content
|
||||
for (int i = 0; i < 4; i++)
|
||||
private void Reset()
|
||||
{
|
||||
itemCorners[i] = content.InverseTransformPoint(itemCorners[i]);
|
||||
viewportCorners[i] = content.InverseTransformPoint(viewportCorners[i]);
|
||||
scrollRect = GetComponentInChildren<ScrollRect>();
|
||||
}
|
||||
|
||||
// Вычисляем границы
|
||||
float itemTop = itemCorners[1].y;
|
||||
float itemBottom = itemCorners[0].y;
|
||||
float itemLeft = itemCorners[0].x;
|
||||
float itemRight = itemCorners[2].x;
|
||||
|
||||
float viewTop = viewportCorners[1].y;
|
||||
float viewBottom = viewportCorners[0].y;
|
||||
float viewLeft = viewportCorners[0].x;
|
||||
float viewRight = viewportCorners[2].x;
|
||||
|
||||
Vector2 offset = Vector2.zero;
|
||||
|
||||
// Вертикальная прокрутка
|
||||
if (scrollRect.vertical)
|
||||
private void LateUpdate()
|
||||
{
|
||||
float delta = 0f;
|
||||
bool above = itemTop > viewTop - padding;
|
||||
bool below = itemBottom < viewBottom + padding;
|
||||
GameObject sel = EventSystem.current ? EventSystem.current.currentSelectedGameObject : null;
|
||||
if (!sel || sel == _lastSelected) return;
|
||||
|
||||
if (!onlyWhenNotVisible || above || below)
|
||||
// Только если элемент внутри нашего Content
|
||||
if (!scrollRect || sel.transform is not RectTransform tr || !tr.IsChildOf(scrollRect.content)) return;
|
||||
ScrollTo(tr);
|
||||
_lastSelected = sel;
|
||||
}
|
||||
|
||||
private void ScrollTo(RectTransform target)
|
||||
{
|
||||
if (!scrollRect || !target) return;
|
||||
|
||||
// Сначала убедимся, что лейауты посчитались
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
RectTransform content = scrollRect.content;
|
||||
RectTransform viewport = scrollRect.viewport != null ? scrollRect.viewport : (RectTransform)scrollRect.transform;
|
||||
|
||||
// Получаем мировые углы и преобразуем в локальное пространство viewport
|
||||
Vector3[] itemCorners = new Vector3[4];
|
||||
target.GetWorldCorners(itemCorners);
|
||||
|
||||
Vector3[] viewportCorners = new Vector3[4];
|
||||
viewport.GetWorldCorners(viewportCorners);
|
||||
|
||||
// Преобразуем в локальное пространство content
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (above && below)
|
||||
{
|
||||
// Элемент больше viewport - выравниваем по верхнему краю
|
||||
delta = itemTop - (viewTop - padding);
|
||||
}
|
||||
else if (above)
|
||||
{
|
||||
delta = itemTop - (viewTop - padding);
|
||||
}
|
||||
else if (below)
|
||||
{
|
||||
delta = itemBottom - (viewBottom + padding);
|
||||
}
|
||||
offset.y = delta;
|
||||
itemCorners[i] = content.InverseTransformPoint(itemCorners[i]);
|
||||
viewportCorners[i] = content.InverseTransformPoint(viewportCorners[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Горизонтальная прокрутка
|
||||
if (scrollRect.horizontal)
|
||||
{
|
||||
float delta = 0f;
|
||||
bool left = itemLeft < viewLeft + padding;
|
||||
bool right = itemRight > viewRight - padding;
|
||||
// Вычисляем границы
|
||||
float itemTop = itemCorners[1].y;
|
||||
float itemBottom = itemCorners[0].y;
|
||||
float itemLeft = itemCorners[0].x;
|
||||
float itemRight = itemCorners[2].x;
|
||||
|
||||
if (!onlyWhenNotVisible || left || right)
|
||||
float viewTop = viewportCorners[1].y;
|
||||
float viewBottom = viewportCorners[0].y;
|
||||
float viewLeft = viewportCorners[0].x;
|
||||
float viewRight = viewportCorners[2].x;
|
||||
|
||||
Vector2 offset = Vector2.zero;
|
||||
|
||||
// Вертикальная прокрутка
|
||||
if (scrollRect.vertical)
|
||||
{
|
||||
if (left && right)
|
||||
float delta = 0f;
|
||||
bool above = itemTop > viewTop - padding;
|
||||
bool below = itemBottom < viewBottom + padding;
|
||||
|
||||
if (!onlyWhenNotVisible || above || below)
|
||||
{
|
||||
// Элемент больше viewport - выравниваем по левому краю
|
||||
delta = itemLeft - (viewLeft + padding);
|
||||
if (above && below)
|
||||
{
|
||||
// Элемент больше viewport - выравниваем по верхнему краю
|
||||
delta = itemTop - (viewTop - padding);
|
||||
}
|
||||
else if (above)
|
||||
{
|
||||
delta = itemTop - (viewTop - padding);
|
||||
}
|
||||
else if (below)
|
||||
{
|
||||
delta = itemBottom - (viewBottom + padding);
|
||||
}
|
||||
offset.y = delta;
|
||||
}
|
||||
else if (left)
|
||||
{
|
||||
delta = itemLeft - (viewLeft + padding);
|
||||
}
|
||||
else if (right)
|
||||
{
|
||||
delta = itemRight - (viewRight - padding);
|
||||
}
|
||||
offset.x = delta;
|
||||
}
|
||||
|
||||
// Горизонтальная прокрутка
|
||||
if (scrollRect.horizontal)
|
||||
{
|
||||
float delta = 0f;
|
||||
bool left = itemLeft < viewLeft + padding;
|
||||
bool right = itemRight > viewRight - padding;
|
||||
|
||||
if (!onlyWhenNotVisible || left || right)
|
||||
{
|
||||
if (left && right)
|
||||
{
|
||||
// Элемент больше viewport - выравниваем по левому краю
|
||||
delta = itemLeft - (viewLeft + padding);
|
||||
}
|
||||
else if (left)
|
||||
{
|
||||
delta = itemLeft - (viewLeft + padding);
|
||||
}
|
||||
else if (right)
|
||||
{
|
||||
delta = itemRight - (viewRight - padding);
|
||||
}
|
||||
offset.x = delta;
|
||||
}
|
||||
}
|
||||
|
||||
if (offset == Vector2.zero) return;
|
||||
|
||||
Vector2 targetPos = content.anchoredPosition - offset;
|
||||
|
||||
if (_anim != null) StopCoroutine(_anim);
|
||||
_anim = StartCoroutine(AnimateTo(content, targetPos, duration));
|
||||
}
|
||||
|
||||
if (offset == Vector2.zero) return;
|
||||
|
||||
Vector2 targetPos = content.anchoredPosition - offset;
|
||||
|
||||
if (_anim != null) StopCoroutine(_anim);
|
||||
_anim = StartCoroutine(AnimateTo(content, targetPos, duration));
|
||||
}
|
||||
|
||||
private static IEnumerator AnimateTo(RectTransform content, Vector2 target, float time)
|
||||
{
|
||||
Vector2 start = content.anchoredPosition;
|
||||
float t = 0f;
|
||||
while (t < 1f)
|
||||
private static IEnumerator AnimateTo(RectTransform content, Vector2 target, float time)
|
||||
{
|
||||
t += Time.unscaledDeltaTime / Mathf.Max(0.0001f, time);
|
||||
// лёгкая ease-in-out
|
||||
float s = t * t * (3f - 2f * t);
|
||||
content.anchoredPosition = Vector2.LerpUnclamped(start, target, s);
|
||||
yield return null;
|
||||
Vector2 start = content.anchoredPosition;
|
||||
float t = 0f;
|
||||
while (t < 1f)
|
||||
{
|
||||
t += Time.unscaledDeltaTime / Mathf.Max(0.0001f, time);
|
||||
// лёгкая ease-in-out
|
||||
float s = t * t * (3f - 2f * t);
|
||||
content.anchoredPosition = Vector2.LerpUnclamped(start, target, s);
|
||||
yield return null;
|
||||
}
|
||||
content.anchoredPosition = target;
|
||||
}
|
||||
content.anchoredPosition = target;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,7 @@ using RR.Game2D.Core.Managers;
|
||||
|
||||
namespace RR.Common.UI
|
||||
{
|
||||
[RequireComponent(typeof(CanvasGroup), typeof(SettingsUIList))]
|
||||
[RequireComponent(typeof(CanvasGroup))]
|
||||
public class SettingsUI : MonoBehaviour
|
||||
{
|
||||
[Header("Управление")]
|
||||
|
||||
@ -1,54 +1,57 @@
|
||||
using System;
|
||||
using System;
|
||||
using RR.Common.Managers;
|
||||
using RR.Game2D.Core.Managers;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
public class UICreditsTextController : MonoBehaviour
|
||||
namespace RR.Common.UI
|
||||
{
|
||||
// UI elements
|
||||
[SerializeField] private TextMeshProUGUI livesIncreaseText;
|
||||
[SerializeField] private TextMeshProUGUI livesText;
|
||||
|
||||
// Strings to display
|
||||
[SerializeField] private string livesIncreaseString = "{0}";
|
||||
[SerializeField] private string livesString = "У вас будет {0}";
|
||||
|
||||
private GameManager _gameManager;
|
||||
private SettingsManager _settingsManager;
|
||||
|
||||
private void Start()
|
||||
public class UICreditsTextController : MonoBehaviour
|
||||
{
|
||||
_gameManager = GameManager.Instance;
|
||||
// UI elements
|
||||
[SerializeField] private TextMeshProUGUI livesIncreaseText;
|
||||
[SerializeField] private TextMeshProUGUI livesText;
|
||||
|
||||
if (_gameManager == null) return;
|
||||
// Strings to display
|
||||
[SerializeField] private string livesIncreaseString = "{0}";
|
||||
[SerializeField] private string livesString = "У вас будет {0}";
|
||||
|
||||
_settingsManager = _gameManager.Settings;
|
||||
|
||||
if (_settingsManager == null) _settingsManager = SettingsManager.Instance;
|
||||
|
||||
UpdateLivesText(_gameManager.MaxLives);
|
||||
UpdateLivesIncreaseText();
|
||||
|
||||
_gameManager.MaxLivesChanged += (UpdateLivesText);
|
||||
_gameManager.Settings.OnSettingsLoaded += UpdateLivesIncreaseText;
|
||||
_gameManager.Settings.OnSettingsSaved += UpdateLivesIncreaseText;
|
||||
}
|
||||
private GameManager _gameManager;
|
||||
private SettingsManager _settingsManager;
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (_gameManager == null) _gameManager = GameManager.Instance;
|
||||
|
||||
if (_gameManager != null) _gameManager.MaxLivesChanged -= UpdateLivesText;
|
||||
}
|
||||
private void Start()
|
||||
{
|
||||
_gameManager = GameManager.Instance;
|
||||
|
||||
private void UpdateLivesIncreaseText()
|
||||
{
|
||||
livesIncreaseText.text = string.Format(livesIncreaseString, _settingsManager.GetCurrentGameSettings().livesIncreasedByCredits);
|
||||
if (_gameManager == null) return;
|
||||
|
||||
_settingsManager = _gameManager.Settings;
|
||||
|
||||
if (_settingsManager == null) _settingsManager = SettingsManager.Instance;
|
||||
|
||||
UpdateLivesText(_gameManager.MaxLives);
|
||||
UpdateLivesIncreaseText();
|
||||
|
||||
_gameManager.MaxLivesChanged += (UpdateLivesText);
|
||||
_gameManager.Settings.OnSettingsLoaded += UpdateLivesIncreaseText;
|
||||
_gameManager.Settings.OnSettingsSaved += UpdateLivesIncreaseText;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (_gameManager == null) _gameManager = GameManager.Instance;
|
||||
|
||||
if (_gameManager != null) _gameManager.MaxLivesChanged -= UpdateLivesText;
|
||||
}
|
||||
|
||||
private void UpdateLivesIncreaseText()
|
||||
{
|
||||
livesIncreaseText.text = string.Format(livesIncreaseString, _settingsManager.GetCurrentGameSettings().livesIncreasedByCredits);
|
||||
}
|
||||
|
||||
private void UpdateLivesText(int newLives)
|
||||
{
|
||||
livesText.text = string.Format(livesString, newLives);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateLivesText(int newLives)
|
||||
{
|
||||
livesText.text = string.Format(livesString, newLives);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,126 +1,129 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
public class UIPointer : MonoBehaviour
|
||||
namespace RR.Common.UI
|
||||
{
|
||||
[Header("Настройки")]
|
||||
[SerializeField] private GameObject pointer;
|
||||
[SerializeField] private RectTransform content; // Content ScrollView, где находятся элементы
|
||||
[SerializeField] private float smoothSpeed = 10f; // Скорость перемещения указателя
|
||||
[SerializeField] private Vector2 offset = Vector2.zero; // Смещение указателя относительно элемента
|
||||
|
||||
private RectTransform pointerRect;
|
||||
|
||||
private void Start()
|
||||
public class UIPointer : MonoBehaviour
|
||||
{
|
||||
if (pointer != null)
|
||||
[Header("Настройки")]
|
||||
[SerializeField] private GameObject pointer;
|
||||
[SerializeField] private RectTransform content; // Content ScrollView, где находятся элементы
|
||||
[SerializeField] private float smoothSpeed = 10f; // Скорость перемещения указателя
|
||||
[SerializeField] private Vector2 offset = Vector2.zero; // Смещение указателя относительно элемента
|
||||
|
||||
private RectTransform pointerRect;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
pointerRect = pointer.GetComponent<RectTransform>();
|
||||
if (pointerRect == null)
|
||||
if (pointer != null)
|
||||
{
|
||||
Debug.LogError("UIPointer: pointer не имеет RectTransform!");
|
||||
pointerRect = pointer.GetComponent<RectTransform>();
|
||||
if (pointerRect == null)
|
||||
{
|
||||
Debug.LogError("UIPointer: pointer не имеет RectTransform!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("UIPointer: pointer не назначен!");
|
||||
}
|
||||
|
||||
// Если content не задан, пытаемся найти его автоматически
|
||||
if (content == null)
|
||||
{
|
||||
content = GetComponent<RectTransform>();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
Debug.LogError("UIPointer: pointer не назначен!");
|
||||
if (!pointerRect || !content) return;
|
||||
|
||||
// Получаем текущий выбранный элемент из EventSystem
|
||||
GameObject selected = EventSystem.current?.currentSelectedGameObject;
|
||||
|
||||
// Если ничего не выбрано, скрываем указатель
|
||||
if (selected == null)
|
||||
{
|
||||
if (pointer.activeSelf)
|
||||
pointer.SetActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Проверяем, что выбранный элемент находится внутри нашего content
|
||||
RectTransform selectedRect = selected.GetComponent<RectTransform>();
|
||||
if (!selectedRect || !selectedRect.IsChildOf(content))
|
||||
{
|
||||
if (pointer.activeSelf)
|
||||
pointer.SetActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Показываем указатель, если он был скрыт
|
||||
if (!pointer.activeSelf)
|
||||
pointer.SetActive(true);
|
||||
|
||||
// Вычисляем целевую позицию
|
||||
Vector2 targetPos = GetTargetPosition(selectedRect);
|
||||
|
||||
// Плавно перемещаем указатель
|
||||
if (smoothSpeed > 0)
|
||||
{
|
||||
pointerRect.anchoredPosition = Vector2.Lerp(
|
||||
pointerRect.anchoredPosition,
|
||||
targetPos,
|
||||
Time.unscaledDeltaTime * smoothSpeed
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
pointerRect.anchoredPosition = targetPos;
|
||||
}
|
||||
}
|
||||
|
||||
// Если content не задан, пытаемся найти его автоматически
|
||||
if (content == null)
|
||||
private Vector2 GetTargetPosition(RectTransform target)
|
||||
{
|
||||
content = GetComponent<RectTransform>();
|
||||
}
|
||||
}
|
||||
// Получаем позицию целевого элемента относительно content
|
||||
Vector2 targetAnchoredPos = target.anchoredPosition;
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (!pointerRect || !content) return;
|
||||
// Если элементы не прямые дети content, нужно пересчитать позицию
|
||||
if (target.parent == content)
|
||||
return new Vector2(
|
||||
pointerRect.anchoredPosition.x + offset.x, // X оставляем как есть (или применяем offset)
|
||||
targetAnchoredPos.y + offset.y // Y берем от целевого элемента
|
||||
);
|
||||
// Конвертируем мировую позицию в локальную позицию content
|
||||
Vector3[] corners = new Vector3[4];
|
||||
target.GetWorldCorners(corners);
|
||||
Vector3 center = (corners[0] + corners[2]) * 0.5f;
|
||||
|
||||
// Получаем текущий выбранный элемент из EventSystem
|
||||
GameObject selected = EventSystem.current?.currentSelectedGameObject;
|
||||
|
||||
// Если ничего не выбрано, скрываем указатель
|
||||
if (selected == null)
|
||||
{
|
||||
if (pointer.activeSelf)
|
||||
pointer.SetActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Проверяем, что выбранный элемент находится внутри нашего content
|
||||
RectTransform selectedRect = selected.GetComponent<RectTransform>();
|
||||
if (!selectedRect || !selectedRect.IsChildOf(content))
|
||||
{
|
||||
if (pointer.activeSelf)
|
||||
pointer.SetActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Показываем указатель, если он был скрыт
|
||||
if (!pointer.activeSelf)
|
||||
pointer.SetActive(true);
|
||||
|
||||
// Вычисляем целевую позицию
|
||||
Vector2 targetPos = GetTargetPosition(selectedRect);
|
||||
|
||||
// Плавно перемещаем указатель
|
||||
if (smoothSpeed > 0)
|
||||
{
|
||||
pointerRect.anchoredPosition = Vector2.Lerp(
|
||||
pointerRect.anchoredPosition,
|
||||
targetPos,
|
||||
Time.unscaledDeltaTime * smoothSpeed
|
||||
RectTransformUtility.ScreenPointToLocalPointInRectangle(
|
||||
content,
|
||||
RectTransformUtility.WorldToScreenPoint(null, center),
|
||||
null,
|
||||
out Vector2 localPos
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
pointerRect.anchoredPosition = targetPos;
|
||||
}
|
||||
}
|
||||
targetAnchoredPos = localPos;
|
||||
|
||||
private Vector2 GetTargetPosition(RectTransform target)
|
||||
{
|
||||
// Получаем позицию целевого элемента относительно content
|
||||
Vector2 targetAnchoredPos = target.anchoredPosition;
|
||||
|
||||
// Если элементы не прямые дети content, нужно пересчитать позицию
|
||||
if (target.parent == content)
|
||||
// Применяем смещение
|
||||
return new Vector2(
|
||||
pointerRect.anchoredPosition.x + offset.x, // X оставляем как есть (или применяем offset)
|
||||
targetAnchoredPos.y + offset.y // Y берем от целевого элемента
|
||||
);
|
||||
// Конвертируем мировую позицию в локальную позицию content
|
||||
Vector3[] corners = new Vector3[4];
|
||||
target.GetWorldCorners(corners);
|
||||
Vector3 center = (corners[0] + corners[2]) * 0.5f;
|
||||
}
|
||||
|
||||
RectTransformUtility.ScreenPointToLocalPointInRectangle(
|
||||
content,
|
||||
RectTransformUtility.WorldToScreenPoint(null, center),
|
||||
null,
|
||||
out Vector2 localPos
|
||||
);
|
||||
targetAnchoredPos = localPos;
|
||||
// Метод для ручного обновления позиции указателя (если нужно)
|
||||
public void UpdatePointerPosition()
|
||||
{
|
||||
if (pointerRect == null || content == null) return;
|
||||
|
||||
// Применяем смещение
|
||||
return new Vector2(
|
||||
pointerRect.anchoredPosition.x + offset.x, // X оставляем как есть (или применяем offset)
|
||||
targetAnchoredPos.y + offset.y // Y берем от целевого элемента
|
||||
);
|
||||
GameObject selected = EventSystem.current?.currentSelectedGameObject;
|
||||
if (selected == null) return;
|
||||
|
||||
RectTransform selectedRect = selected.GetComponent<RectTransform>();
|
||||
if (selectedRect == null || !selectedRect.IsChildOf(content)) return;
|
||||
|
||||
pointerRect.anchoredPosition = GetTargetPosition(selectedRect);
|
||||
}
|
||||
}
|
||||
|
||||
// Метод для ручного обновления позиции указателя (если нужно)
|
||||
public void UpdatePointerPosition()
|
||||
{
|
||||
if (pointerRect == null || content == null) return;
|
||||
|
||||
GameObject selected = EventSystem.current?.currentSelectedGameObject;
|
||||
if (selected == null) return;
|
||||
|
||||
RectTransform selectedRect = selected.GetComponent<RectTransform>();
|
||||
if (selectedRect == null || !selectedRect.IsChildOf(content)) return;
|
||||
|
||||
pointerRect.anchoredPosition = GetTargetPosition(selectedRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -697,7 +697,7 @@ PlayerSettings:
|
||||
framebufferDepthMemorylessMode: 0
|
||||
qualitySettingsNames: []
|
||||
projectName: Mario-like platformer
|
||||
organizationId: dis_bro
|
||||
organizationId:
|
||||
cloudEnabled: 0
|
||||
legacyClampBlendShapeWeights: 0
|
||||
hmiLoadingImage: {fileID: 0}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user