Удалить устаревший код и упростить структуру проекта

This commit is contained in:
Сергей Бондарь 2026-08-28 13:28:30 +03:00
parent f86eed2d70
commit a656816fce
56 changed files with 13929 additions and 106 deletions

View File

@ -322,6 +322,7 @@ GameObject:
m_Component:
- component: {fileID: 1649651658890651227}
- component: {fileID: 4851732468212733041}
- component: {fileID: 3035129523181316746}
m_Layer: 0
m_Name: WinDots
m_TagString: Untagged
@ -338,8 +339,8 @@ Transform:
m_GameObject: {fileID: 5381885663262334684}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -1.885, y: -1.411, z: 0}
m_LocalScale: {x: 0.1, y: 0.1, z: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 2308229979791902274}
@ -393,8 +394,8 @@ SpriteRenderer:
m_SortingLayer: 2
m_SortingOrder: 1
m_MaskInteraction: 1
m_Sprite: {fileID: 21300000, guid: 8a5c9e10e873e84469d2775643ee2963, type: 3}
m_Color: {r: 0.906171, g: 0.72264147, b: 1, a: 0.39215687}
m_Sprite: {fileID: 5926679086967000773, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 0.5019608}
m_FlipX: 0
m_FlipY: 0
m_DrawMode: 0
@ -403,6 +404,44 @@ SpriteRenderer:
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_SpriteSortPoint: 0
--- !u!114 &3035129523181316746
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5381885663262334684}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4339cf20ac8758e4d95e76fa7d8a49d8, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::WinDotsSpriteAnimation
_frames:
- {fileID: 5926679086967000773, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: 3636919418153618306, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: 4515922743439741304, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: 8132584066278862514, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: -8108738257191919818, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: 5476654092949210065, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: -1990881141348228837, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: -7416603296217001524, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: 3118335388394741567, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: -6336752160069933936, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: -1039031528695854209, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: -5269464141798107413, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: 5142607469940596662, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: -8690711018983002392, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: -67496403243326737, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: -2071637404648840656, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: -6499610286121366947, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: -2245256199062182782, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: 1652010674694780367, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: -6167259795869830211, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: 9007253255794517222, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: 2205569462954929695, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: 3608606768418714753, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: -2975377606414988421, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
- {fileID: -8500441694541564097, guid: cced5ca6a5acfe446a69a222c5a3101e, type: 3}
--- !u!1 &7100645357252458328
GameObject:
m_ObjectHideFlags: 0
@ -485,12 +524,12 @@ SpriteRenderer:
m_SortingLayer: 2
m_SortingOrder: 0
m_MaskInteraction: 0
m_Sprite: {fileID: 21300000, guid: 024833a84adf142449000086760fe890, type: 3}
m_Sprite: {fileID: -8703082228858259314, guid: 86e3e7edd9d4ad44badffb017e45ffc7, 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.2641976, y: 1.2641976}
m_Size: {x: 1.0076336, y: 1}
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
@ -543,7 +582,7 @@ SpriteMask:
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_Sprite: {fileID: 21300000, guid: 024833a84adf142449000086760fe890, type: 3}
m_Sprite: {fileID: -8703082228858259314, guid: 86e3e7edd9d4ad44badffb017e45ffc7, type: 3}
m_MaskAlphaCutoff: 0.2
m_FrontSortingLayerID: 0
m_BackSortingLayerID: 0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 29e887253f375c14592cbe27f3ebf9ba
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5ac08a20c3c95d244b5e0dab8caa0f37
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,107 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &76364904654376910
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2018842502904421549}
- component: {fileID: 1768772482836322451}
- component: {fileID: 1819202205107719226}
- component: {fileID: 2146224851953945163}
- component: {fileID: 6150878258172159458}
m_Layer: 5
m_Name: ScreenTestPanel
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &2018842502904421549
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 76364904654376910}
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: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!225 &1768772482836322451
CanvasGroup:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 76364904654376910}
m_Enabled: 1
m_Alpha: 0
m_Interactable: 1
m_BlocksRaycasts: 1
m_IgnoreParentGroups: 0
--- !u!222 &1819202205107719226
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 76364904654376910}
m_CullTransparentMesh: 1
--- !u!114 &2146224851953945163
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 76364904654376910}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
m_Material: {fileID: 0}
m_Color: {r: 1, g: 0, b: 0, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &6150878258172159458
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 76364904654376910}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: b3697f5ff7aa25f489f065e5a259e89b, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::ScreenTestPanel
_canvasGroup: {fileID: 1768772482836322451}
_background: {fileID: 2146224851953945163}
_fadeDuration: 0.35
_rgbAnimationDuration: 5

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d13e67e4802f2564d8f9ffc72a09ce86
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a2d2b2360300dea4b8642897c27af2a3
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -496,6 +496,7 @@ MonoBehaviour:
m_EditorClassIdentifier: Assembly-CSharp::MenuSettingsTransit
_menu: {fileID: 1122363137}
_settingsScreen: {fileID: 1967587905}
_passwordPanelPrefab: {fileID: 3698661281615635426, guid: a2d2b2360300dea4b8642897c27af2a3, type: 3}
--- !u!224 &31006179 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 5596715831000475182, guid: 36522aeb3edb1f14eb882ff35e1a57bd, type: 3}
@ -4386,7 +4387,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchorMin.x
@ -4394,7 +4395,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_SizeDelta.x
@ -4434,11 +4435,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 116.51001
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -22.955
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
@ -5120,7 +5121,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchorMin.x
@ -5128,7 +5129,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_SizeDelta.x
@ -5168,11 +5169,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 271.19003
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -22.955
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
@ -7636,7 +7637,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchorMin.x
@ -7644,7 +7645,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_SizeDelta.x
@ -7684,11 +7685,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 348.53003
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -22.955
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
@ -10408,7 +10409,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchorMin.x
@ -10416,7 +10417,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_SizeDelta.x
@ -10456,11 +10457,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 193.85
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -22.955
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
@ -18706,8 +18707,23 @@ MonoBehaviour:
_canvas: {fileID: 1967587903}
_settingsScreen: {fileID: 1967587905}
_prizesConfigurator: {fileID: 141381090}
_screenTestPanelPrefab: {fileID: 6150878258172159458, guid: d13e67e4802f2564d8f9ffc72a09ce86, type: 3}
_inputTestPanelPrefab: {fileID: 6307352032178720536, guid: 29e887253f375c14592cbe27f3ebf9ba, type: 3}
_passwordPanelPrefab: {fileID: 3698661281615635426, guid: a2d2b2360300dea4b8642897c27af2a3, type: 3}
_countersPanelPrefab: {fileID: 8913567922555786375, guid: 5ac08a20c3c95d244b5e0dab8caa0f37, type: 3}
_qrTestPanelPrefab: {fileID: 892320005122046078, guid: 5a977adc6a025e34c8be865b38cfb4c7, type: 3}
_qrTestUnavailableClip: {fileID: 0}
_soundTestReplicas:
- {fileID: 8300000, guid: 64f45a3984b4b4d4e8c131b2e5b3ed09, type: 3}
- {fileID: 8300000, guid: 3b7b182a4894254478af77c3a4918a18, type: 3}
- {fileID: 8300000, guid: 819c33148b0c685418f60b15dcddb8aa, type: 3}
- {fileID: 8300000, guid: 4f2600f2dbf30c7448532477cfbdafb3, type: 3}
- {fileID: 8300000, guid: c9a29f5b4b4e1484284e7a7c89e111ff, type: 3}
- {fileID: 8300000, guid: cb495d78bf78528468abc6a8db5727c1, type: 3}
- {fileID: 8300000, guid: 5425d3d04722587498b02014418ddc20, type: 3}
- {fileID: 8300000, guid: d39b30d4fe7d41343b9548f3047239e6, type: 3}
- {fileID: 8300000, guid: 6a930fd99794efd47ad9b23d50eb41e6, type: 3}
- {fileID: 8300000, guid: 63560c033ce15244c832c6bb91985fb8, type: 3}
--- !u!114 &1967587907
MonoBehaviour:
m_ObjectHideFlags: 0
@ -22192,7 +22208,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchorMin.x
@ -22200,7 +22216,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_SizeDelta.x
@ -22240,11 +22256,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 39.170002
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -22.955
objectReference: {fileID: 0}
- target: {fileID: 1909234588782507268, guid: e45c4d0b012452f40ad1dc153ae38811, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
@ -22859,147 +22875,147 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 333912590944302499, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 333912590944302499, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 333912590944302499, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.x
value: 0
value: 7
objectReference: {fileID: 0}
- target: {fileID: 333912590944302499, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.y
value: 0
value: 132.9175
objectReference: {fileID: 0}
- target: {fileID: 333912590944302499, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 3.5
objectReference: {fileID: 0}
- target: {fileID: 333912590944302499, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -214.97626
objectReference: {fileID: 0}
- target: {fileID: 770108196109532210, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 770108196109532210, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 770108196109532210, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.x
value: 0
value: 7
objectReference: {fileID: 0}
- target: {fileID: 770108196109532210, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.y
value: 0
value: 132.9175
objectReference: {fileID: 0}
- target: {fileID: 770108196109532210, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 3.5
objectReference: {fileID: 0}
- target: {fileID: 770108196109532210, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -363.49374
objectReference: {fileID: 0}
- target: {fileID: 935420627850452094, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 935420627850452094, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 935420627850452094, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.x
value: 0
value: 703.71
objectReference: {fileID: 0}
- target: {fileID: 935420627850452094, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.y
value: 0
value: 59.390003
objectReference: {fileID: 0}
- target: {fileID: 935420627850452094, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 351.855
objectReference: {fileID: 0}
- target: {fileID: 935420627850452094, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -153.81502
objectReference: {fileID: 0}
- target: {fileID: 1190827924149678685, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1190827924149678685, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1190827924149678685, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.x
value: 0
value: 703.71
objectReference: {fileID: 0}
- target: {fileID: 1190827924149678685, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.y
value: 0
value: 59.390003
objectReference: {fileID: 0}
- target: {fileID: 1190827924149678685, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 351.855
objectReference: {fileID: 0}
- target: {fileID: 1190827924149678685, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -215.87502
objectReference: {fileID: 0}
- target: {fileID: 1477235949744466647, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1477235949744466647, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1477235949744466647, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.x
value: 0
value: 703.71
objectReference: {fileID: 0}
- target: {fileID: 1477235949744466647, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.y
value: 0
value: 59.390003
objectReference: {fileID: 0}
- target: {fileID: 1477235949744466647, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 351.855
objectReference: {fileID: 0}
- target: {fileID: 1477235949744466647, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -277.935
objectReference: {fileID: 0}
- target: {fileID: 3543665328416834874, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3543665328416834874, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3543665328416834874, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.x
value: 0
value: 703.71
objectReference: {fileID: 0}
- target: {fileID: 3543665328416834874, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.y
value: 0
value: 59.390003
objectReference: {fileID: 0}
- target: {fileID: 3543665328416834874, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 351.855
objectReference: {fileID: 0}
- target: {fileID: 3543665328416834874, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -91.755005
objectReference: {fileID: 0}
- target: {fileID: 5483391176823058074, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_IsActive
@ -23095,75 +23111,75 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 7417418181170801207, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7417418181170801207, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7417418181170801207, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.x
value: 0
value: 7
objectReference: {fileID: 0}
- target: {fileID: 7417418181170801207, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.y
value: 0
value: 132.9175
objectReference: {fileID: 0}
- target: {fileID: 7417418181170801207, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 3.5
objectReference: {fileID: 0}
- target: {fileID: 7417418181170801207, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -512.0112
objectReference: {fileID: 0}
- target: {fileID: 7755885942619096437, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7755885942619096437, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7755885942619096437, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.x
value: 0
value: 7
objectReference: {fileID: 0}
- target: {fileID: 7755885942619096437, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.y
value: 0
value: 132.9175
objectReference: {fileID: 0}
- target: {fileID: 7755885942619096437, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 3.5
objectReference: {fileID: 0}
- target: {fileID: 7755885942619096437, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -66.45875
objectReference: {fileID: 0}
- target: {fileID: 8295315770064589757, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 8295315770064589757, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 8295315770064589757, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.x
value: 0
value: 703.71
objectReference: {fileID: 0}
- target: {fileID: 8295315770064589757, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_SizeDelta.y
value: 0
value: 59.390003
objectReference: {fileID: 0}
- target: {fileID: 8295315770064589757, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 351.855
objectReference: {fileID: 0}
- target: {fileID: 8295315770064589757, guid: a34b2a0441a3e2c4a96fca5080d8f203, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -29.695002
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
@ -23191,19 +23207,19 @@ PrefabInstance:
m_Modifications:
- target: {fileID: 1871089524602559658, guid: 14e3225697047e04f9fc5a33f4690443, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1871089524602559658, guid: 14e3225697047e04f9fc5a33f4690443, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 1871089524602559658, guid: 14e3225697047e04f9fc5a33f4690443, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 261.665
objectReference: {fileID: 0}
- target: {fileID: 1871089524602559658, guid: 14e3225697047e04f9fc5a33f4690443, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -22.816446
objectReference: {fileID: 0}
- target: {fileID: 3994272294263330828, guid: 14e3225697047e04f9fc5a33f4690443, type: 3}
propertyPath: m_Pivot.x
@ -23287,19 +23303,19 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 7909369483914820580, guid: 14e3225697047e04f9fc5a33f4690443, type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7909369483914820580, guid: 14e3225697047e04f9fc5a33f4690443, type: 3}
propertyPath: m_AnchorMin.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7909369483914820580, guid: 14e3225697047e04f9fc5a33f4690443, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
value: 132.94
objectReference: {fileID: 0}
- target: {fileID: 7909369483914820580, guid: 14e3225697047e04f9fc5a33f4690443, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
value: -32.385
objectReference: {fileID: 0}
- target: {fileID: 8523793110535762614, guid: 14e3225697047e04f9fc5a33f4690443, type: 3}
propertyPath: m_Name

8
Assets/Screenshots.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 43ddf81f090e77346989c6f46aee96ba
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -70,6 +70,7 @@ public class Bootstrap : MonoBehaviour
characterController.Initialize();
gameManager.Initialize();
MachineCountersService.Initialize();
board.Init();
chipPool.Init(chipPrefab, 30);
@ -148,4 +149,4 @@ public class Bootstrap : MonoBehaviour
PrizeStandController.Initialize(h, 5);
}
}
}
}

View File

@ -17,8 +17,15 @@ public class Chip : MonoBehaviour
private float chipVelocity = 0;
private float rotationSpeed = 0;
private float winDotsPosition = 1.5f;
private Tween winTween;
private WinDotsSpriteAnimation _winDotsAnimation;
public int WinAnimationFrameCount => _winDotsAnimation.FrameCount;
private void Awake()
{
_winDotsAnimation = winDots.GetComponent<WinDotsSpriteAnimation>();
}
public void Configure(Sprite sprite, Team team)
{
@ -73,17 +80,20 @@ public class Chip : MonoBehaviour
}
mask.enabled = true;
winDots.localPosition = Vector3.zero;
winDots.localScale = Vector3.one;
winDots.gameObject.SetActive(true);
Vector2 startPosition = new Vector2(winDotsPosition, winDotsPosition);
winDots.localPosition = startPosition;
winTween = winDots.DOLocalMove(-startPosition, winAnimationDuration).SetEase(Ease.Linear);
winTween.onComplete = () =>
winTween = DOVirtual.DelayedCall(winAnimationDuration, () =>
{
mask.enabled = false;
winDots.gameObject.SetActive(false);
};
}, false);
winTween.PlayForward();
}
}
public void SetWinAnimationFrame(int frameIndex)
{
_winDotsAnimation.SetFrame(frameIndex);
}
}

View File

@ -1,4 +1,5 @@
using CharacterSystem;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
@ -10,6 +11,19 @@ public class EndGameHandler : MonoBehaviour
[SerializeField, FormerlySerializedAs("pvpWinPanel")] private PvpWinPanel _pvpWinPanel;
[SerializeField, FormerlySerializedAs("drawPanel")] private PveLossPanel _drawPanel;
private const float WinAnimationFrameRate = 40f;
private Coroutine _winAnimationCoroutine;
private void OnDisable()
{
if (_winAnimationCoroutine != null)
{
StopCoroutine(_winAnimationCoroutine);
_winAnimationCoroutine = null;
}
}
public void HandleEndGame(Team lastPlayer, GameMode gameMode, CheckResult lastResult)
{
Debug.Log("Конец игры");
@ -49,11 +63,13 @@ public class EndGameHandler : MonoBehaviour
{
if (winner == Team.Player1)
{
MachineCountersService.RecordBotResult(true);
EventBus.TriggerEvent(GameEvent.PlayerWin);
_winPanel.Open();
}
else
{
MachineCountersService.RecordBotResult(false);
EventBus.TriggerEvent(GameEvent.BotWin);
_lossPanel.Open(GameManager.Instance.ContinueAfterPveLoss);
}
@ -76,8 +92,38 @@ public class EndGameHandler : MonoBehaviour
private void PlayWinChipsAnimation(HashSet<(int row, int col)> winChipsCoords)
{
Chip[,] grid = Board.Instance.Grid;
Chip[] winChips = new Chip[winChipsCoords.Count];
int chipIndex = 0;
foreach ((int row, int col) winCoord in winChipsCoords)
grid[winCoord.col, winCoord.row].WinAnimation();
{
Chip chip = grid[winCoord.col, winCoord.row];
winChips[chipIndex++] = chip;
chip.WinAnimation();
}
if (winChips.Length == 0)
return;
if (_winAnimationCoroutine != null)
StopCoroutine(_winAnimationCoroutine);
_winAnimationCoroutine = StartCoroutine(PlayWinDotsAnimation(winChips));
}
private IEnumerator PlayWinDotsAnimation(Chip[] winChips)
{
int frameCount = winChips[0].WinAnimationFrameCount;
WaitForSeconds frameDelay = new WaitForSeconds(1f / WinAnimationFrameRate);
for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
{
for (int chipIndex = 0; chipIndex < winChips.Length; chipIndex++)
winChips[chipIndex].SetWinAnimationFrame(frameIndex);
yield return frameDelay;
}
_winAnimationCoroutine = null;
}
}

View File

@ -120,6 +120,7 @@ public class TurnManager : MonoBehaviour
private void OnPlayerMoveCommitted()
{
_player1.OnMoveCommitted -= OnPlayerMoveCommitted;
MachineCountersService.RecordFirstMove();
GameManager.Instance.DisableEarlyMenuExit();
if (_gameMode == GameMode.pve)

View File

@ -0,0 +1,25 @@
using UnityEngine;
[RequireComponent(typeof(SpriteRenderer))]
public sealed class WinDotsSpriteAnimation : MonoBehaviour
{
[SerializeField] private Sprite[] _frames;
private SpriteRenderer _spriteRenderer;
public int FrameCount => _frames.Length;
private void Awake()
{
if (!TryGetComponent(out _spriteRenderer))
enabled = false;
}
public void SetFrame(int frameIndex)
{
if ((uint)frameIndex >= (uint)_frames.Length)
return;
_spriteRenderer.sprite = _frames[frameIndex];
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4339cf20ac8758e4d95e76fa7d8a49d8

View File

@ -9,6 +9,7 @@ public static class PaymentSystem
public static event Action<int> onCoinAdded;
public static event Action<int> onCoinRemoved;
public static event Action<int> OnBalanceChanged;
public static event Action<int> OnRevenueReceived;
public static event Action OnNotEnoughMoney;
public static event Action OnPaymentDataChanged;
@ -58,6 +59,7 @@ public static class PaymentSystem
//вот это вот некрасивое надо куда то девать.
PlayerPrefs.SetInt(PrefsKeyVault.CASH_COUNTER, PlayerPrefs.GetInt(PrefsKeyVault.CASH_COUNTER) + ValutaPerImpulse);
PlayerPrefs.SetInt(PrefsKeyVault.CASH_COUNTER_NUL, PlayerPrefs.GetInt(PrefsKeyVault.CASH_COUNTER_NUL) + ValutaPerImpulse);
OnRevenueReceived?.Invoke(ValutaPerImpulse);
if (SettingsManager.GetString(SettingKey.DIFFICULTY_MODE) == "Заработок")
{

View File

@ -11,6 +11,7 @@ namespace PrizeSystem
{
public static event Action<PrizeContainer> OnPrizesChanged;
public static event Action<bool> OnErrorStateChanged;
public static event Action OnPrizeIssued;
[Header("Звук")]
[SerializeField] private AudioClip prizeErrorSound;
@ -139,6 +140,7 @@ namespace PrizeSystem
//Счетчики
IncreasePrizeCounters(Type);
ReportPrizeIssued();
//хотя бы что то успешно выпало
atLeastOnePrize = true;
@ -189,6 +191,17 @@ namespace PrizeSystem
PlayerPrefs.SetInt(PrefsKeyVault.SPECIAL_GIVEN_COUNTER + "Nullable", 0);
}
public static void ReportPrizeIssued()
{
PlayerPrefs.SetInt(
PrefsKeyVault.PRIZES_GIVEN_COUNTER,
PlayerPrefs.GetInt(PrefsKeyVault.PRIZES_GIVEN_COUNTER, 0) + 1);
PlayerPrefs.SetInt(
PrefsKeyVault.PRIZES_GIVEN_COUNTER_NUL,
PlayerPrefs.GetInt(PrefsKeyVault.PRIZES_GIVEN_COUNTER_NUL, 0) + 1);
OnPrizeIssued?.Invoke();
}
private void SoundNotificationIfNeeds()
{
if (PrizeNotificationSounds == null || PrizeNotificationSounds.Count == 0) return;
@ -213,4 +226,4 @@ public struct PrizeImageMap
{
public PrizeType prizeType;
public Sprite sprite;
}
}

View File

@ -39,6 +39,7 @@ public class QrPanel : MonoBehaviour
var sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f));
QrImage.sprite = sprite;
Label.text = qrPrize.PrizeText;
PrizeSystemManager.ReportPrizeIssued();
}
else
{

View File

@ -7,9 +7,18 @@ public class SettingFunctions : MonoBehaviour
[SerializeField] private RectTransform _canvas;
[SerializeField] private SettingsScreen _settingsScreen;
[SerializeField] private CharacterPrizeConfigurator _prizesConfigurator;
[SerializeField] private ScreenTestPanel _screenTestPanelPrefab;
[SerializeField] private InputTestPanel _inputTestPanelPrefab;
[SerializeField] private SettingsPasswordPanel _passwordPanelPrefab;
[SerializeField] private MachineCountersPanel _countersPanelPrefab;
[SerializeField] private QrTestPanel _qrTestPanelPrefab;
[SerializeField] private AudioClip _qrTestUnavailableClip;
[SerializeField] private AudioClip[] _soundTestReplicas;
private ScreenTestPanel _activeScreenTestPanel;
private InputTestPanel _activeInputTestPanel;
private SettingsPasswordPanel _activePasswordPanel;
private MachineCountersPanel _activeCountersPanel;
private QrTestPanel _activeQrTestPanel;
private void Awake()
@ -21,6 +30,21 @@ public class SettingFunctions : MonoBehaviour
{
_prizesConfigurator.OnClosed -= ReturnToSettings;
if (_activeScreenTestPanel != null)
_activeScreenTestPanel.OnClosed -= CloseScreenTest;
if (_activeInputTestPanel != null)
_activeInputTestPanel.OnClosed -= CloseInputTest;
if (_activePasswordPanel != null)
{
_activePasswordPanel.OnAccepted -= ClosePasswordPanel;
_activePasswordPanel.OnCancelled -= ClosePasswordPanel;
}
if (_activeCountersPanel != null)
_activeCountersPanel.OnClosed -= CloseCountersPanel;
if (_activeQrTestPanel != null)
_activeQrTestPanel.OnClosed -= CloseQrTest;
}
@ -73,17 +97,56 @@ public class SettingFunctions : MonoBehaviour
public void ScreenTest()
{
if (_activeScreenTestPanel != null)
return;
_activeScreenTestPanel = Instantiate(_screenTestPanelPrefab, _canvas);
_activeScreenTestPanel.OnClosed += CloseScreenTest;
_settingsScreen.BlockControls();
ControlsPerformer.Instance.SetControlable(_activeScreenTestPanel);
_activeScreenTestPanel.Open();
}
public void InputTest()
{
if (_activeInputTestPanel != null)
return;
_activeInputTestPanel = Instantiate(_inputTestPanelPrefab, _canvas);
_activeInputTestPanel.OnClosed += CloseInputTest;
_settingsScreen.BlockControls();
ControlsPerformer.Instance.SetControlable(_activeInputTestPanel);
_activeInputTestPanel.Open();
}
public void SoundTest()
{
if (SoundManager.instance == null)
{
Debug.LogWarning("SoundManager не инициализирован");
return;
}
if (_soundTestReplicas == null || _soundTestReplicas.Length == 0)
{
Debug.LogWarning("Не заданы реплики для теста звука");
return;
}
int firstReplicaIndex = Random.Range(0, _soundTestReplicas.Length);
for (int offset = 0; offset < _soundTestReplicas.Length; offset++)
{
AudioClip replica = _soundTestReplicas[(firstReplicaIndex + offset) % _soundTestReplicas.Length];
if (replica == null)
continue;
SoundManager.instance.playClip(replica);
return;
}
Debug.LogWarning("В списке теста звука нет назначенных реплик");
}
public void HopperTest()
@ -117,17 +180,33 @@ public class SettingFunctions : MonoBehaviour
public void SetPassword()
{
if (_activePasswordPanel != null)
return;
_activePasswordPanel = Instantiate(_passwordPanelPrefab, _canvas);
_activePasswordPanel.OnAccepted += ClosePasswordPanel;
_activePasswordPanel.OnCancelled += ClosePasswordPanel;
_settingsScreen.BlockControls();
ControlsPerformer.Instance.SetControlable(_activePasswordPanel);
_activePasswordPanel.OpenForPasswordChange();
}
public void ResetPassword()
{
SettingsPasswordStore.Reset();
_settingsScreen.BlockControls();
}
public void OpenCounters()
{
if (_activeCountersPanel != null)
return;
_activeCountersPanel = Instantiate(_countersPanelPrefab, _canvas);
_activeCountersPanel.OnClosed += CloseCountersPanel;
_settingsScreen.BlockControls();
ControlsPerformer.Instance.SetControlable(_activeCountersPanel);
_activeCountersPanel.Open();
}
public void OpenPrizesRest()
@ -141,6 +220,39 @@ public class SettingFunctions : MonoBehaviour
ControlsPerformer.Instance.SetControlable(_settingsScreen);
}
private void CloseScreenTest()
{
_activeScreenTestPanel.OnClosed -= CloseScreenTest;
Destroy(_activeScreenTestPanel.gameObject);
_activeScreenTestPanel = null;
ReturnToSettings();
}
private void CloseInputTest()
{
_activeInputTestPanel.OnClosed -= CloseInputTest;
Destroy(_activeInputTestPanel.gameObject);
_activeInputTestPanel = null;
ReturnToSettings();
}
private void ClosePasswordPanel()
{
_activePasswordPanel.OnAccepted -= ClosePasswordPanel;
_activePasswordPanel.OnCancelled -= ClosePasswordPanel;
Destroy(_activePasswordPanel.gameObject);
_activePasswordPanel = null;
ReturnToSettings();
}
private void CloseCountersPanel()
{
_activeCountersPanel.OnClosed -= CloseCountersPanel;
Destroy(_activeCountersPanel.gameObject);
_activeCountersPanel = null;
ReturnToSettings();
}
private void CloseQrTest()
{
_activeQrTestPanel.OnClosed -= CloseQrTest;

View File

@ -0,0 +1,114 @@
using System;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;
public sealed class InputTestPanel : MonoBehaviour, IControlable
{
public event Action OnClosed;
[SerializeField] private CanvasGroup _canvasGroup;
[SerializeField] private RectTransform _leftJoystickHandle;
[SerializeField] private RectTransform _rightJoystickHandle;
[SerializeField] private Image _leftActionButton;
[SerializeField] private Image _rightActionButton;
[SerializeField] private Image _serviceButton;
[SerializeField] private RectTransform _exitProgressFill;
[SerializeField] private float _joystickTravel = 80f;
[SerializeField] private float _exitHoldDuration = 1f;
[SerializeField] private float _fadeDuration = 0.25f;
[SerializeField] private Color _idleColor = new Color(0.25f, 0.25f, 0.28f, 1f);
[SerializeField] private Color _pressedColor = new Color(1f, 0.85f, 0.1f, 1f);
private Tween _fadeTween;
private float _exitHoldTime;
private bool _isClosing;
public bool ControlsEnabled { get; set; }
private void OnDisable()
{
_fadeTween?.Kill();
_fadeTween = null;
ControlsEnabled = false;
}
public void Open()
{
_fadeTween?.Kill();
transform.SetAsLastSibling();
_canvasGroup.alpha = 0f;
_canvasGroup.blocksRaycasts = true;
_exitHoldTime = 0f;
_isClosing = false;
ControlsEnabled = true;
ResetVisuals();
_fadeTween = _canvasGroup.DOFade(1f, _fadeDuration).SetEase(Ease.OutCubic).SetUpdate(true);
_fadeTween.PlayForward();
}
public void UpdateControls()
{
Vector2Int leftAxis = In.GetAxis(JoystickSide.Left, InteractMode.Continious);
Vector2Int rightAxis = In.GetAxis(JoystickSide.Right, InteractMode.Continious);
bool leftActionPressed = In.GetAction(JoystickSide.Left, InteractMode.Continious);
bool rightActionPressed = In.GetAction(JoystickSide.Right, InteractMode.Continious);
_leftJoystickHandle.anchoredPosition = (Vector2)leftAxis * _joystickTravel;
_rightJoystickHandle.anchoredPosition = (Vector2)rightAxis * _joystickTravel;
SetButtonState(_leftActionButton, leftActionPressed);
SetButtonState(_rightActionButton, rightActionPressed);
SetButtonState(_serviceButton, In.GetService());
bool exitButtonsHeld = leftActionPressed && rightActionPressed;
_exitHoldTime = exitButtonsHeld
? Mathf.Min(_exitHoldTime + Time.unscaledDeltaTime, _exitHoldDuration)
: 0f;
SetExitProgress(_exitHoldTime / _exitHoldDuration);
if (_exitHoldTime >= _exitHoldDuration)
Close();
}
private void Close()
{
if (_isClosing)
return;
_isClosing = true;
ControlsEnabled = false;
_fadeTween?.Kill();
_fadeTween = _canvasGroup.DOFade(0f, _fadeDuration).SetEase(Ease.InCubic).SetUpdate(true);
_fadeTween.OnComplete(() =>
{
_canvasGroup.blocksRaycasts = false;
OnClosed?.Invoke();
});
_fadeTween.PlayForward();
}
private void ResetVisuals()
{
_leftJoystickHandle.anchoredPosition = Vector2.zero;
_rightJoystickHandle.anchoredPosition = Vector2.zero;
SetButtonState(_leftActionButton, false);
SetButtonState(_rightActionButton, false);
SetButtonState(_serviceButton, false);
SetExitProgress(0f);
}
private void SetButtonState(Image button, bool pressed)
{
button.color = pressed ? _pressedColor : _idleColor;
button.rectTransform.localScale = pressed ? Vector3.one * 0.92f : Vector3.one;
}
private void SetExitProgress(float progress)
{
Vector2 anchorMax = _exitProgressFill.anchorMax;
anchorMax.x = Mathf.Clamp01(progress);
_exitProgressFill.anchorMax = anchorMax;
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 478f256823101cc4ea5ce2f8b2e0b0d5

View File

@ -0,0 +1,234 @@
using System;
using DG.Tweening;
using TMPro;
using UnityEngine;
public sealed class MachineCountersPanel : MonoBehaviour, IControlable
{
public event Action OnClosed;
[SerializeField] private CanvasGroup _canvasGroup;
[SerializeField] private TextMeshProUGUI[] _resettableValues;
[SerializeField] private TextMeshProUGUI[] _lifetimeValues;
[SerializeField] private TextMeshProUGUI _resetButton;
[SerializeField] private TextMeshProUGUI _backButton;
[SerializeField] private TextMeshProUGUI _status;
[SerializeField] private RectTransform _holdProgressFill;
[SerializeField] private float _resetHoldDuration = 1f;
[SerializeField] private float _serviceHoldDuration = 1f;
[SerializeField] private float _fadeDuration = 0.25f;
[SerializeField] private Color _normalButtonColor = Color.white;
[SerializeField] private Color _selectedButtonColor = new Color(1f, 0.85f, 0.1f, 1f);
private const int ResetButtonIndex = 0;
private const int BackButtonIndex = 1;
private const int ValuesCount = 11;
private Tween _fadeTween;
private int _selectedButtonIndex;
private float _resetHoldTime;
private float _serviceHoldTime;
private float _statusHideTime;
private bool _actionReleased;
private bool _serviceReleased;
private bool _isClosing;
public bool ControlsEnabled { get; set; }
private void OnDisable()
{
_fadeTween?.Kill();
_fadeTween = null;
ControlsEnabled = false;
}
public void Open()
{
_fadeTween?.Kill();
transform.SetAsLastSibling();
_canvasGroup.alpha = 0f;
_canvasGroup.blocksRaycasts = true;
_selectedButtonIndex = BackButtonIndex;
_resetHoldTime = 0f;
_serviceHoldTime = 0f;
_statusHideTime = 0f;
_actionReleased = false;
_serviceReleased = false;
_isClosing = false;
_status.text = string.Empty;
ControlsEnabled = true;
RefreshValues();
UpdateButtonSelection();
SetHoldProgress(0f);
_fadeTween = _canvasGroup.DOFade(1f, _fadeDuration).SetEase(Ease.OutCubic).SetUpdate(true);
_fadeTween.PlayForward();
}
public void UpdateControls()
{
UpdateStatus();
UpdateServiceExit();
if (_isClosing)
return;
int horizontal = In.GetAxis(JoystickSide.Both, InteractMode.Discrete).x;
if (horizontal != 0)
{
_selectedButtonIndex = _selectedButtonIndex == ResetButtonIndex ? BackButtonIndex : ResetButtonIndex;
_resetHoldTime = 0f;
SetHoldProgress(0f);
UpdateButtonSelection();
}
bool actionHeld = In.GetAction(JoystickSide.Both, InteractMode.Continious);
if (actionHeld == false)
_actionReleased = true;
if (_selectedButtonIndex == BackButtonIndex)
{
_resetHoldTime = 0f;
SetHoldProgress(0f);
if (_actionReleased && In.GetAction(JoystickSide.Both, InteractMode.Discrete))
Close();
return;
}
_resetHoldTime = _actionReleased && actionHeld
? Mathf.Min(_resetHoldTime + Time.unscaledDeltaTime, _resetHoldDuration)
: 0f;
SetHoldProgress(_resetHoldTime / _resetHoldDuration);
if (_resetHoldTime < _resetHoldDuration)
return;
MachineCountersService.ResetResettableCounters();
_resetHoldTime = 0f;
_actionReleased = false;
SetHoldProgress(0f);
RefreshValues();
ShowStatus("ОБНУЛЯЕМЫЕ СЧЁТЧИКИ СБРОШЕНЫ", 2f);
}
private void RefreshValues()
{
if (_resettableValues.Length < ValuesCount || _lifetimeValues.Length < ValuesCount)
return;
MachineCounterSet resettable = MachineCountersService.GetResettableCounters();
MachineCounterSet lifetime = MachineCountersService.GetLifetimeCounters();
SetValues(_resettableValues, resettable);
SetValues(_lifetimeValues, lifetime);
}
private void SetValues(TextMeshProUGUI[] labels, MachineCounterSet counters)
{
labels[0].text = FormatRevenue(counters.revenue);
labels[1].text = counters.prizesIssued.ToString();
labels[2].text = counters.gamesStarted.ToString();
labels[3].text = counters.pveGamesStarted.ToString();
labels[4].text = counters.pvpGamesStarted.ToString();
labels[5].text = FormatDuration(counters.AverageSessionDurationSeconds);
for (int botIndex = 0; botIndex < MachineCounterSet.BotCount; botIndex++)
labels[6 + botIndex].text = FormatBotResults(counters, botIndex);
}
private void UpdateButtonSelection()
{
SetButtonSelected(_resetButton, _selectedButtonIndex == ResetButtonIndex);
SetButtonSelected(_backButton, _selectedButtonIndex == BackButtonIndex);
}
private void UpdateServiceExit()
{
bool serviceHeld = In.GetService();
if (serviceHeld == false)
_serviceReleased = true;
_serviceHoldTime = _serviceReleased && serviceHeld
? Mathf.Min(_serviceHoldTime + Time.unscaledDeltaTime, _serviceHoldDuration)
: 0f;
if (_serviceHoldTime >= _serviceHoldDuration)
Close();
}
private void ShowStatus(string message, float duration)
{
_status.text = message;
_statusHideTime = Time.unscaledTime + duration;
}
private void UpdateStatus()
{
if (_statusHideTime <= 0f || Time.unscaledTime < _statusHideTime)
return;
_status.text = string.Empty;
_statusHideTime = 0f;
}
private void SetHoldProgress(float progress)
{
Vector2 anchorMax = _holdProgressFill.anchorMax;
anchorMax.x = Mathf.Clamp01(progress);
_holdProgressFill.anchorMax = anchorMax;
}
private void SetButtonSelected(TextMeshProUGUI button, bool selected)
{
button.color = selected ? _selectedButtonColor : _normalButtonColor;
button.rectTransform.localScale = selected ? Vector3.one * 1.08f : Vector3.one;
}
private void Close()
{
if (_isClosing)
return;
_isClosing = true;
ControlsEnabled = false;
_fadeTween?.Kill();
_fadeTween = _canvasGroup.DOFade(0f, _fadeDuration).SetEase(Ease.InCubic).SetUpdate(true);
_fadeTween.OnComplete(() =>
{
_canvasGroup.blocksRaycasts = false;
OnClosed?.Invoke();
});
_fadeTween.PlayForward();
}
private static string FormatRevenue(long revenue)
{
string currency = PluralizeUtil.GetValutaPluralized(
PaymentSystem.ValutaName,
(int)(revenue % 100));
if (currency == "Valuta_Error")
currency = PaymentSystem.ValutaName;
return $"{revenue:N0} {currency}";
}
private static string FormatDuration(double seconds)
{
TimeSpan duration = TimeSpan.FromSeconds(Math.Max(0d, seconds));
return duration.TotalHours >= 1d
? $"{(int)duration.TotalHours:00}:{duration.Minutes:00}:{duration.Seconds:00}"
: $"{duration.Minutes:00}:{duration.Seconds:00}";
}
private static string FormatBotResults(MachineCounterSet counters, int botIndex)
{
return $"Л {counters.easyBotWins[botIndex]}/{counters.easyBotLosses[botIndex]} "
+ $"С {counters.mediumBotWins[botIndex]}/{counters.mediumBotLosses[botIndex]} "
+ $"Т {counters.hardBotWins[botIndex]}/{counters.hardBotLosses[botIndex]}";
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4ebfbd71390db924583deda26402fdc3

View File

@ -0,0 +1,57 @@
using System;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;
public sealed class ScreenTestPanel : MonoBehaviour, IControlable
{
public event Action OnClosed;
[SerializeField] private CanvasGroup _canvasGroup;
[SerializeField] private Image _background;
[SerializeField] private float _fadeDuration = 0.35f;
[SerializeField] private float _rgbAnimationDuration = 5f;
private Sequence _animation;
public bool ControlsEnabled { get; set; }
private void OnDisable()
{
_animation?.Kill();
_animation = null;
ControlsEnabled = false;
}
public void Open()
{
_animation?.Kill();
transform.SetAsLastSibling();
_canvasGroup.alpha = 0f;
_canvasGroup.blocksRaycasts = true;
_background.color = Color.red;
ControlsEnabled = true;
float colorStepDuration = _rgbAnimationDuration / 3f;
_animation = DOTween.Sequence();
_animation.Append(_canvasGroup.DOFade(1f, _fadeDuration).SetEase(Ease.OutCubic));
_animation.Append(_background.DOColor(Color.green, colorStepDuration).SetEase(Ease.Linear));
_animation.Append(_background.DOColor(Color.blue, colorStepDuration).SetEase(Ease.Linear));
_animation.Append(_background.DOColor(Color.red, colorStepDuration).SetEase(Ease.Linear));
_animation.Append(_canvasGroup.DOFade(0f, _fadeDuration).SetEase(Ease.InCubic));
_animation.SetUpdate(true);
_animation.OnComplete(Close);
_animation.PlayForward();
}
public void UpdateControls()
{
}
private void Close()
{
ControlsEnabled = false;
_canvasGroup.blocksRaycasts = false;
OnClosed?.Invoke();
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b3697f5ff7aa25f489f065e5a259e89b

View File

@ -0,0 +1,370 @@
using System;
using System.Text;
using DG.Tweening;
using TMPro;
using UnityEngine;
public sealed class SettingsPasswordPanel : MonoBehaviour, IControlable
{
public event Action OnAccepted;
public event Action OnCancelled;
[SerializeField] private CanvasGroup _canvasGroup;
[SerializeField] private TextMeshProUGUI _title;
[SerializeField] private TextMeshProUGUI _combination;
[SerializeField] private TextMeshProUGUI _hint;
[SerializeField] private TextMeshProUGUI _status;
[SerializeField] private RectTransform _confirmProgressFill;
[SerializeField] private CanvasGroup _confirmationGroup;
[SerializeField] private TextMeshProUGUI[] _confirmationOptions;
[SerializeField] private float _confirmHoldDuration = 1f;
[SerializeField] private float _cancelHoldDuration = 1f;
[SerializeField] private float _fadeDuration = 0.25f;
[SerializeField] private Color _normalOptionColor = Color.white;
[SerializeField] private Color _selectedOptionColor = new Color(1f, 0.85f, 0.1f, 1f);
[SerializeField] private Color _errorColor = new Color(1f, 0.25f, 0.25f, 1f);
private const int PasswordLength = 6;
private const int SaveOptionIndex = 0;
private const int ReenterOptionIndex = 1;
private const int CancelOptionIndex = 2;
private readonly StringBuilder _enteredCombination = new StringBuilder(PasswordLength);
private Tween _fadeTween;
private PanelPurpose _purpose;
private PanelStage _stage;
private float _confirmHoldTime;
private float _cancelHoldTime;
private float _statusHideTime;
private int _selectedOptionIndex;
private bool _actionReleased;
private bool _serviceReleased;
private bool _isClosing;
public bool ControlsEnabled { get; set; }
private void OnDisable()
{
_fadeTween?.Kill();
_fadeTween = null;
ControlsEnabled = false;
}
public void OpenForSettingsAccess()
{
_purpose = PanelPurpose.SettingsAccess;
Open(PanelStage.VerifyPassword);
}
public void OpenForPasswordChange()
{
_purpose = PanelPurpose.PasswordChange;
Open(SettingsPasswordStore.HasPassword ? PanelStage.VerifyPassword : PanelStage.EnterNewPassword);
}
public void UpdateControls()
{
UpdateStatus();
UpdateCancelInput();
if (_isClosing)
return;
if (_stage == PanelStage.ConfirmPassword)
UpdateConfirmationControls();
else
UpdatePasswordControls();
}
private void Open(PanelStage initialStage)
{
_fadeTween?.Kill();
transform.SetAsLastSibling();
_canvasGroup.alpha = 0f;
_canvasGroup.blocksRaycasts = true;
_isClosing = false;
_serviceReleased = false;
ControlsEnabled = true;
SetStage(initialStage);
_fadeTween = _canvasGroup.DOFade(1f, _fadeDuration).SetEase(Ease.OutCubic).SetUpdate(true);
_fadeTween.PlayForward();
}
private void UpdatePasswordControls()
{
Vector2Int axis = In.GetAxis(JoystickSide.Both, InteractMode.Discrete);
if (_enteredCombination.Length < PasswordLength)
AddDirection(axis);
bool actionHeld = In.GetAction(JoystickSide.Both, InteractMode.Continious);
if (actionHeld == false)
_actionReleased = true;
bool canConfirm = _enteredCombination.Length == PasswordLength && _actionReleased;
_confirmHoldTime = canConfirm && actionHeld
? Mathf.Min(_confirmHoldTime + Time.unscaledDeltaTime, _confirmHoldDuration)
: 0f;
SetConfirmProgress(_confirmHoldTime / _confirmHoldDuration);
if (_confirmHoldTime < _confirmHoldDuration)
return;
_confirmHoldTime = 0f;
_actionReleased = false;
SetConfirmProgress(0f);
if (_stage == PanelStage.VerifyPassword)
VerifyPassword();
else
SetStage(PanelStage.ConfirmPassword);
}
private void UpdateConfirmationControls()
{
Vector2Int axis = In.GetAxis(JoystickSide.Both, InteractMode.Discrete);
int selectionDirection = axis.y != 0 ? -axis.y : axis.x;
if (selectionDirection != 0)
{
_selectedOptionIndex = (_selectedOptionIndex + Math.Sign(selectionDirection) + _confirmationOptions.Length)
% _confirmationOptions.Length;
UpdateConfirmationSelection();
}
bool actionHeld = In.GetAction(JoystickSide.Both, InteractMode.Continious);
if (actionHeld == false)
_actionReleased = true;
if (_actionReleased && In.GetAction(JoystickSide.Both, InteractMode.Discrete))
ExecuteConfirmationOption();
}
private void UpdateCancelInput()
{
bool serviceHeld = In.GetService();
if (serviceHeld == false)
_serviceReleased = true;
_cancelHoldTime = _serviceReleased && serviceHeld
? Mathf.Min(_cancelHoldTime + Time.unscaledDeltaTime, _cancelHoldDuration)
: 0f;
if (_cancelHoldTime >= _cancelHoldDuration)
Close(false);
}
private void AddDirection(Vector2Int axis)
{
char direction = GetDirectionSymbol(axis);
if (direction == default)
return;
_enteredCombination.Append(direction);
UpdateCombinationView();
ClearStatus();
}
private void VerifyPassword()
{
if (SettingsPasswordStore.Validate(_enteredCombination.ToString()))
{
if (_purpose == PanelPurpose.SettingsAccess)
Close(true);
else
SetStage(PanelStage.EnterNewPassword);
return;
}
_enteredCombination.Clear();
UpdateCombinationView();
ShowStatus("НЕВЕРНЫЙ ПАРОЛЬ", _errorColor, 1.5f);
}
private void ExecuteConfirmationOption()
{
_actionReleased = false;
if (_selectedOptionIndex == SaveOptionIndex)
{
if (SettingsPasswordStore.Save(_enteredCombination.ToString()))
Close(true);
else
ShowStatus("НЕ УДАЛОСЬ СОХРАНИТЬ ПАРОЛЬ", _errorColor, 2f);
return;
}
if (_selectedOptionIndex == ReenterOptionIndex)
{
SetStage(PanelStage.EnterNewPassword);
return;
}
if (_selectedOptionIndex == CancelOptionIndex)
Close(false);
}
private void SetStage(PanelStage stage)
{
_stage = stage;
if (stage != PanelStage.ConfirmPassword)
_enteredCombination.Clear();
_confirmHoldTime = 0f;
_selectedOptionIndex = 0;
_actionReleased = false;
SetConfirmProgress(0f);
ClearStatus();
bool confirmationVisible = stage == PanelStage.ConfirmPassword;
_confirmationGroup.alpha = confirmationVisible ? 1f : 0f;
_confirmationGroup.blocksRaycasts = confirmationVisible;
_combination.gameObject.SetActive(confirmationVisible == false);
_confirmProgressFill.parent.gameObject.SetActive(confirmationVisible == false);
if (stage == PanelStage.VerifyPassword)
{
_title.text = _purpose == PanelPurpose.SettingsAccess ? "ВВЕДИТЕ ПАРОЛЬ" : "СТАРЫЙ ПАРОЛЬ";
_hint.text = "Введите 6 движений любым джойстиком\nи удерживайте кнопку действия 1 секунду";
}
else if (stage == PanelStage.EnterNewPassword)
{
_title.text = "НОВЫЙ ПАРОЛЬ";
_hint.text = "Введите 6 движений любым джойстиком\nи удерживайте кнопку действия 1 секунду";
}
else
{
_title.text = "ПОДТВЕРЖДЕНИЕ";
_hint.text = $"Сохранить комбинацию {FormatCombination(_enteredCombination.ToString())}?";
UpdateConfirmationSelection();
}
UpdateCombinationView();
}
private void UpdateCombinationView()
=> _combination.text = FormatCombination(_enteredCombination.ToString());
private void UpdateConfirmationSelection()
{
for (int i = 0; i < _confirmationOptions.Length; i++)
{
bool selected = i == _selectedOptionIndex;
_confirmationOptions[i].color = selected ? _selectedOptionColor : _normalOptionColor;
_confirmationOptions[i].rectTransform.localScale = selected ? Vector3.one * 1.08f : Vector3.one;
}
}
private void SetConfirmProgress(float progress)
{
Vector2 anchorMax = _confirmProgressFill.anchorMax;
anchorMax.x = Mathf.Clamp01(progress);
_confirmProgressFill.anchorMax = anchorMax;
}
private void ShowStatus(string message, Color color, float duration)
{
_status.text = message;
_status.color = color;
_statusHideTime = Time.unscaledTime + duration;
}
private void UpdateStatus()
{
if (_statusHideTime > 0f && Time.unscaledTime >= _statusHideTime)
ClearStatus();
}
private void ClearStatus()
{
_status.text = string.Empty;
_statusHideTime = 0f;
}
private void Close(bool accepted)
{
if (_isClosing)
return;
_isClosing = true;
ControlsEnabled = false;
_fadeTween?.Kill();
_fadeTween = _canvasGroup.DOFade(0f, _fadeDuration).SetEase(Ease.InCubic).SetUpdate(true);
_fadeTween.OnComplete(() =>
{
_canvasGroup.blocksRaycasts = false;
if (accepted)
OnAccepted?.Invoke();
else
OnCancelled?.Invoke();
});
_fadeTween.PlayForward();
}
private static char GetDirectionSymbol(Vector2Int axis)
{
if (axis.y > 0)
return 'U';
if (axis.y < 0)
return 'D';
if (axis.x < 0)
return 'L';
if (axis.x > 0)
return 'R';
return default;
}
private static string FormatCombination(string combination)
{
var result = new StringBuilder();
for (int i = 0; i < PasswordLength; i++)
{
if (i > 0)
result.Append(" ");
result.Append(i < combination.Length ? GetDirectionArrow(combination[i]) : "·");
}
return result.ToString();
}
private static string GetDirectionArrow(char direction)
{
return direction switch
{
'U' => "↑",
'D' => "↓",
'L' => "←",
'R' => "→",
_ => "·"
};
}
private enum PanelPurpose
{
SettingsAccess,
PasswordChange
}
private enum PanelStage
{
VerifyPassword,
EnterNewPassword,
ConfirmPassword
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1ac08509f3fa8754a936cde21a025812

View File

@ -0,0 +1,99 @@
using System;
using System.IO;
using UnityEngine;
public static class SettingsPasswordStore
{
private const string FileName = "settings-password.txt";
private const int PasswordLength = 6;
public static string PasswordFilePath => Path.Combine(Application.persistentDataPath, FileName);
public static bool HasPassword => TryGetPassword(out _);
public static bool Save(string combination)
{
string normalizedCombination = Normalize(combination);
if (IsValid(normalizedCombination) == false)
return false;
try
{
File.WriteAllText(PasswordFilePath, normalizedCombination);
return true;
}
catch (Exception exception)
{
Debug.LogError($"Не удалось сохранить пароль настроек: {exception.Message}");
return false;
}
}
public static bool Validate(string combination)
{
if (TryGetPassword(out string savedPassword) == false)
return false;
return string.Equals(savedPassword, Normalize(combination), StringComparison.Ordinal);
}
public static bool Reset()
{
try
{
if (File.Exists(PasswordFilePath))
File.Delete(PasswordFilePath);
return true;
}
catch (Exception exception)
{
Debug.LogError($"Не удалось сбросить пароль настроек: {exception.Message}");
return false;
}
}
private static bool TryGetPassword(out string password)
{
password = null;
try
{
if (File.Exists(PasswordFilePath) == false)
return false;
string savedPassword = Normalize(File.ReadAllText(PasswordFilePath));
if (IsValid(savedPassword) == false)
return false;
password = savedPassword;
return true;
}
catch (Exception exception)
{
Debug.LogError($"Не удалось прочитать пароль настроек: {exception.Message}");
return false;
}
}
private static string Normalize(string combination)
=> string.IsNullOrWhiteSpace(combination) ? string.Empty : combination.Trim().ToUpperInvariant();
private static bool IsValid(string combination)
{
if (combination.Length != PasswordLength)
return false;
for (int i = 0; i < combination.Length; i++)
{
char symbol = combination[i];
if (symbol != 'U' && symbol != 'D' && symbol != 'L' && symbol != 'R')
return false;
}
return true;
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 866c213f7e1c5aa40b49009d82dac689

View File

@ -0,0 +1,325 @@
using System;
using UnityEngine;
public static class MachineCountersService
{
private const string CountersFileName = "machine-counters.json";
private static MachineCountersData _data;
private static double _sessionStartedAt;
private static GameMode _pendingGameMode;
private static bool _sessionArmed;
private static bool _sessionActive;
public static string CountersFilePath => System.IO.Path.Combine(Application.persistentDataPath, CountersFileName);
public static void Initialize()
{
PaymentSystem.OnRevenueReceived -= RecordRevenue;
PaymentSystem.OnRevenueReceived += RecordRevenue;
PrizeSystem.PrizeSystemManager.OnPrizeIssued -= RecordPrizeIssued;
PrizeSystem.PrizeSystemManager.OnPrizeIssued += RecordPrizeIssued;
GameManager.OnGameStarted -= RecordGameStarted;
GameManager.OnGameStarted += RecordGameStarted;
GameManager.OnGameFinished -= RecordGameFinished;
GameManager.OnGameFinished += RecordGameFinished;
Load();
_sessionArmed = false;
_sessionActive = false;
}
public static MachineCounterSet GetLifetimeCounters()
{
EnsureInitialized();
return _data.lifetime.Clone();
}
public static MachineCounterSet GetResettableCounters()
{
EnsureInitialized();
return _data.resettable.Clone();
}
public static void RecordFirstMove()
{
if (_sessionArmed == false || _sessionActive)
return;
EnsureInitialized();
IncreaseGamesStarted(_data.lifetime, _pendingGameMode);
IncreaseGamesStarted(_data.resettable, _pendingGameMode);
_sessionStartedAt = Time.realtimeSinceStartupAsDouble;
_sessionActive = true;
Save();
}
public static void RecordBotResult(bool playerWon)
{
EnsureInitialized();
if (CharacterSystem.CharactersController.HasActiveCharacter == false)
return;
int botIndex = CharacterSystem.CharactersController.CharacterIndex;
int difficultyIndex = GetCurrentDifficultyIndex();
IncreaseBotResult(_data.lifetime, botIndex, difficultyIndex, playerWon);
IncreaseBotResult(_data.resettable, botIndex, difficultyIndex, playerWon);
Save();
}
public static void ResetResettableCounters()
{
EnsureInitialized();
_data.resettable = new MachineCounterSet();
PlayerPrefs.SetInt(PrefsKeyVault.CASH_COUNTER_NUL, 0);
PlayerPrefs.SetInt(PrefsKeyVault.PRIZES_GIVEN_COUNTER_NUL, 0);
PrizeSystem.PrizeSystemManager.ResetPrizeCounters();
PlayerPrefs.Save();
Save();
}
private static void RecordRevenue(int amount)
{
if (amount <= 0)
return;
EnsureInitialized();
_data.lifetime.revenue += amount;
_data.resettable.revenue += amount;
Save();
}
private static void RecordPrizeIssued()
{
EnsureInitialized();
_data.lifetime.prizesIssued++;
_data.resettable.prizesIssued++;
Save();
}
private static void RecordGameStarted(GameMode mode)
{
EnsureInitialized();
_pendingGameMode = mode;
_sessionArmed = true;
_sessionActive = false;
}
private static void RecordGameFinished(GameMode mode)
{
_sessionArmed = false;
if (_sessionActive == false)
return;
EnsureInitialized();
double duration = Math.Max(0d, Time.realtimeSinceStartupAsDouble - _sessionStartedAt);
AddCompletedSession(_data.lifetime, duration);
AddCompletedSession(_data.resettable, duration);
_sessionActive = false;
Save();
}
private static void IncreaseGamesStarted(MachineCounterSet counters, GameMode mode)
{
counters.gamesStarted++;
if (mode == GameMode.pve)
counters.pveGamesStarted++;
else
counters.pvpGamesStarted++;
}
private static void AddCompletedSession(MachineCounterSet counters, double duration)
{
counters.completedSessions++;
counters.totalSessionDurationSeconds += duration;
}
private static void IncreaseBotResult(
MachineCounterSet counters,
int botIndex,
int difficultyIndex,
bool playerWon)
{
counters.NormalizeBotCounters();
int[] values = playerWon
? counters.GetBotWins(difficultyIndex)
: counters.GetBotLosses(difficultyIndex);
values[botIndex]++;
}
private static int GetCurrentDifficultyIndex()
{
if (SettingsManager.GetString(SettingKey.DIFFICULTY_MODE) == "Заработок")
return MachineCounterSet.HardDifficultyIndex;
return SettingsManager.GetString(SettingKey.DIFFICULTY) switch
{
"Легкая" => MachineCounterSet.EasyDifficultyIndex,
"Сложная" => MachineCounterSet.HardDifficultyIndex,
_ => MachineCounterSet.MediumDifficultyIndex
};
}
private static void EnsureInitialized()
{
if (_data == null)
Load();
}
private static void Load()
{
var loadResult = FileUtil.LoadJson<MachineCountersData>(CountersFileName, FileUtil.AppDirectory.Persistent);
if (loadResult.OK && loadResult.Data != null)
{
_data = loadResult.Data;
_data.lifetime ??= new MachineCounterSet();
_data.resettable ??= new MachineCounterSet();
_data.lifetime.NormalizeBotCounters();
_data.resettable.NormalizeBotCounters();
return;
}
_data = CreateFromLegacyCounters();
Save();
}
private static MachineCountersData CreateFromLegacyCounters()
{
int lifetimePrizes = Mathf.Max(
PlayerPrefs.GetInt(PrefsKeyVault.PRIZES_GIVEN_COUNTER, 0),
GetLegacyPrizeTotal(false));
int resettablePrizes = Mathf.Max(
PlayerPrefs.GetInt(PrefsKeyVault.PRIZES_GIVEN_COUNTER_NUL, 0),
GetLegacyPrizeTotal(true));
return new MachineCountersData
{
lifetime = new MachineCounterSet
{
revenue = PlayerPrefs.GetInt(PrefsKeyVault.CASH_COUNTER, 0),
prizesIssued = lifetimePrizes
},
resettable = new MachineCounterSet
{
revenue = PlayerPrefs.GetInt(PrefsKeyVault.CASH_COUNTER_NUL, 0),
prizesIssued = resettablePrizes
}
};
}
private static int GetLegacyPrizeTotal(bool resettable)
{
string suffix = resettable ? "Nullable" : string.Empty;
return PlayerPrefs.GetInt(PrefsKeyVault.HOPPER_GIVEN_COUNTER + suffix, 0)
+ PlayerPrefs.GetInt(PrefsKeyVault.MARBLES_GIVEN_COUNTER + suffix, 0)
+ PlayerPrefs.GetInt(PrefsKeyVault.TICKET_GIVEN_COUNTER + suffix, 0)
+ PlayerPrefs.GetInt(PrefsKeyVault.SPECIAL_GIVEN_COUNTER + suffix, 0);
}
private static void Save()
{
var saveResult = FileUtil.SaveJson(CountersFileName, FileUtil.AppDirectory.Persistent, _data);
if (saveResult.OK == false)
Debug.LogError(saveResult.Message);
}
}
[Serializable]
public sealed class MachineCountersData
{
public MachineCounterSet lifetime = new MachineCounterSet();
public MachineCounterSet resettable = new MachineCounterSet();
}
[Serializable]
public sealed class MachineCounterSet
{
public const int BotCount = 5;
public const int EasyDifficultyIndex = 0;
public const int MediumDifficultyIndex = 1;
public const int HardDifficultyIndex = 2;
public long revenue;
public int prizesIssued;
public int gamesStarted;
public int pveGamesStarted;
public int pvpGamesStarted;
public int completedSessions;
public double totalSessionDurationSeconds;
public int[] easyBotWins = new int[BotCount];
public int[] easyBotLosses = new int[BotCount];
public int[] mediumBotWins = new int[BotCount];
public int[] mediumBotLosses = new int[BotCount];
public int[] hardBotWins = new int[BotCount];
public int[] hardBotLosses = new int[BotCount];
public double AverageSessionDurationSeconds
=> completedSessions == 0 ? 0d : totalSessionDurationSeconds / completedSessions;
public int[] GetBotWins(int difficultyIndex)
{
return difficultyIndex switch
{
EasyDifficultyIndex => easyBotWins,
HardDifficultyIndex => hardBotWins,
_ => mediumBotWins
};
}
public int[] GetBotLosses(int difficultyIndex)
{
return difficultyIndex switch
{
EasyDifficultyIndex => easyBotLosses,
HardDifficultyIndex => hardBotLosses,
_ => mediumBotLosses
};
}
public void NormalizeBotCounters()
{
easyBotWins = NormalizeArray(easyBotWins);
easyBotLosses = NormalizeArray(easyBotLosses);
mediumBotWins = NormalizeArray(mediumBotWins);
mediumBotLosses = NormalizeArray(mediumBotLosses);
hardBotWins = NormalizeArray(hardBotWins);
hardBotLosses = NormalizeArray(hardBotLosses);
}
public MachineCounterSet Clone()
{
return new MachineCounterSet
{
revenue = revenue,
prizesIssued = prizesIssued,
gamesStarted = gamesStarted,
pveGamesStarted = pveGamesStarted,
pvpGamesStarted = pvpGamesStarted,
completedSessions = completedSessions,
totalSessionDurationSeconds = totalSessionDurationSeconds,
easyBotWins = (int[])easyBotWins.Clone(),
easyBotLosses = (int[])easyBotLosses.Clone(),
mediumBotWins = (int[])mediumBotWins.Clone(),
mediumBotLosses = (int[])mediumBotLosses.Clone(),
hardBotWins = (int[])hardBotWins.Clone(),
hardBotLosses = (int[])hardBotLosses.Clone()
};
}
private static int[] NormalizeArray(int[] values)
{
if (values != null && values.Length == BotCount)
return values;
var normalized = new int[BotCount];
if (values != null)
Array.Copy(values, normalized, Math.Min(values.Length, normalized.Length));
return normalized;
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 8560e070f5ce38d4199790e7cfed876c

View File

@ -4,17 +4,78 @@ public class MenuSettingsTransit : MonoBehaviour
{
[SerializeField] private Menu _menu;
[SerializeField] private SettingsScreen _settingsScreen;
[SerializeField] private SettingsPasswordPanel _passwordPanelPrefab;
private SettingsPasswordPanel _activePasswordPanel;
private void OnDestroy()
{
if (_activePasswordPanel == null)
return;
_activePasswordPanel.OnAccepted -= AcceptSettingsAccess;
_activePasswordPanel.OnCancelled -= CancelSettingsAccess;
}
public void GotoSettings()
{
if (_activePasswordPanel != null)
return;
_menu.ControlsEnabled = false;
_settingsScreen.gameObject.SetActive(true);
ControlsPerformer.Instance.SetControlable(_settingsScreen);
if (SettingsPasswordStore.HasPassword == false)
{
EnterSettings();
return;
}
_activePasswordPanel = Instantiate(_passwordPanelPrefab, _settingsScreen.transform);
_activePasswordPanel.OnAccepted += AcceptSettingsAccess;
_activePasswordPanel.OnCancelled += CancelSettingsAccess;
_settingsScreen.BlockControls();
ControlsPerformer.Instance.SetControlable(_activePasswordPanel);
_activePasswordPanel.OpenForSettingsAccess();
}
public void GotoMenu()
{
ClosePasswordPanel();
_settingsScreen.gameObject.SetActive(false);
SettingsManager.SaveSettings();
_menu.ControlsEnabled = true;
ControlsPerformer.Instance.SetControlable(_menu);
}
}
private void EnterSettings()
{
_settingsScreen.BlockControls();
ControlsPerformer.Instance.SetControlable(_settingsScreen);
}
private void AcceptSettingsAccess()
{
ClosePasswordPanel();
EnterSettings();
}
private void CancelSettingsAccess()
{
ClosePasswordPanel();
_settingsScreen.gameObject.SetActive(false);
_menu.ControlsEnabled = true;
ControlsPerformer.Instance.SetControlable(_menu);
}
private void ClosePasswordPanel()
{
if (_activePasswordPanel == null)
return;
_activePasswordPanel.OnAccepted -= AcceptSettingsAccess;
_activePasswordPanel.OnCancelled -= CancelSettingsAccess;
Destroy(_activePasswordPanel.gameObject);
_activePasswordPanel = null;
}
}

View File

@ -89,7 +89,7 @@ public static class PrizeStandController
{
if(!await _lock.WaitAsync(0))
{
OpeningFinished?.Invoke(true, "Выдача уже в процессе");
OpeningFinished?.Invoke(false, "Выдача уже в процессе");
return;
}
@ -127,7 +127,7 @@ public static class PrizeStandController
else
{
Log($"[Модуль витрины] Ошибка при открытии ячейки {boxNumber}");
OpeningFinished?.Invoke(true, $"Ошибка при открытии ячейки {boxNumber}");
OpeningFinished?.Invoke(false, $"Ошибка при открытии ячейки {boxNumber}");
}
}
catch (Exception ex)
@ -454,4 +454,4 @@ public enum BoxStatus
ParsingError, //При парсинге что то пошло не так, или пришла непредусмотренная фигня
NotFound, //Коробка с требуемым номером не найдена
Error //Общая ошибка (например дали команду на открытие пустого ящика или сломан замок)
}
}

View File

@ -51,6 +51,9 @@ public class VitrinaCatcher : MonoBehaviour
public void DisplayOpenResult(bool success, string message)
{
if (success)
PrizeSystem.PrizeSystemManager.ReportPrizeIssued();
InitializeBySuccess(success);
}

3
Assets/Sprites/blik.png Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3a3b14ffe41d86c375c8f533849adde93a1e1937750c2cac223628326e16a306
size 194969

1568
Assets/Sprites/blik.png.meta Normal file

File diff suppressed because it is too large Load Diff