FEAT: Added new settings system
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled

- Добавил новую систему настроек, возможности:
    - Динамически создает список настроек
    - Сохраняет настройки в JSON-файл
    - Возможность группировать настройки
    - Широкие возможности по кастомизации
    - Применение настроек в реальном времени (частично)
- Добавил префабы для новых элементов настроек
- Изменил поведение игры исходя из нового формата настроек
This commit is contained in:
Данил Ярош 2026-02-04 14:32:15 +03:00
parent f88861cdba
commit 4d05d1adbb
94 changed files with 13704 additions and 6412 deletions

1
.gitignore vendored
View File

@ -2,6 +2,7 @@
#
*_[Tt]emp.*
*[Tt]emp*
#
## --------------------------------------------

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BetterCommentsSettings">
<option name="initialized" value="true" />
<option name="tags">
<list>
<CustomTag>
<option name="color" value="#FF2D00" />
<option name="type" value="!" />
</CustomTag>
<CustomTag>
<option name="color" value="#3498DB" />
<option name="type" value="?" />
</CustomTag>
<CustomTag>
<option name="color" value="#474747" />
<option name="hasStrikethrough" value="true" />
<option name="type" value="//" />
</CustomTag>
<CustomTag>
<option name="color" value="#FF8C00" />
<option name="type" value="todo" />
</CustomTag>
<CustomTag>
<option name="color" value="#98C379" />
<option name="type" value="*" />
</CustomTag>
</list>
</option>
</component>
</project>

View File

@ -178,11 +178,7 @@
- `PauseMenu.cs` - Меню паузы
- `GameEndUIController.cs` - UI завершения игры
- `LoseBannerController.cs` - Баннер поражения (с таймером продолжения)
- `SettingsUI.cs` - UI настроек
- `SettingsUIList.cs` - Список настроек:
- Слайдеры громкости (музыка/SFX)
- Тогглы оплаты (бесплатная игра, призы)
- Настройки жизней игрока
- `SettingsUI.cs` - Модальное окно настроек
- `LevelSelectModal.cs` - Модальное окно выбора уровня
- `LevelButton.cs` - Кнопка уровня
- `TopPanelTextController.cs` - Верхняя панель с информацией
@ -193,31 +189,39 @@
- `ModalFocusTrap.cs` - Захват фокуса в модальных окнах
- `FullscreenToggle.cs` - Переключение полноэкранного режима
#### **7. ScriptableObjects/** - Ресурсы конфигурации
- `GameSettings.cs` - Настройки игры:
- Общие: полноэкранный режим, громкость
- Оплата: бесплатная игра, призы, телефон
- Игрок: стартовые жизни, прирост жизней
- Методы: `SetDefaultValues()`, `ValidateSettings()`, `ApplySettings()`
#### **7. Settings/** - Система настроек
- **Core/**
- `SettingsManager.cs` - Менеджер настроек (синглтон)
- `SettingsDatabase.cs` - ScriptableObject база данных настроек
- `SettingsApplier.cs` - Применение настроек (AudioMixer и т.д.)
- `SettingsButtonDispatcher.cs` - Диспетчер событий кнопок настроек
- `SettingsButtonActions.cs` - Готовые действия для кнопок
- **UI/**
- `SettingsUIGenerator.cs` - Генератор UI из базы данных
- `SettingsGroupPanel.cs` - Сворачиваемая группа настроек
- `SettingUIItem.cs` - Элемент настройки (toggle, slider, button и т.д.)
- `SettingsButtonBinder.cs` - Биндер кнопок для взаимодействия с объектами сцены
- `SettingToggleBinder.cs`, `SettingSliderBinder.cs` - Биндеры для ручной привязки
#### **8. ScriptableObjects/** - Ресурсы конфигурации
- `SFXAsset.cs` - Набор звуковых эффектов
- `EnemySFXAsset.cs` - Звуки врагов
- `EnemyControllerConfiguration.cs` - Конфигурация врагов
- `EnemyFireConfiguration.cs` - Конфигурация стрельбы врагов
#### **8. Animations/** - Анимационные события
#### **9. Animations/** - Анимационные события
- `PlayerAnimationEvents.cs` - События анимаций игрока
- `EnemyAnimationEvents.cs` - События анимаций врагов
#### **9. Audio/** - Звуковая система
#### **10. Audio/** - Звуковая система
- `SoundEffect.cs` - Базовый звуковой эффект
- `LevelPlayerSFX.cs` - SFX для уровня
#### **10. FX/** - Визуальные эффекты
#### **11. FX/** - Визуальные эффекты
- `PlayerRunVFX.cs` - Эффекты бега игрока
- `CheckPointFX.cs` - Эффекты чекпоинтов
#### **11. Utilities/** - Вспомогательные утилиты
#### **12. Utilities/** - Вспомогательные утилиты
- `FileLogger.cs` - Логирование в файл
- `CompositeLogger.cs` - Комбинированное логирование
- `LoggerInitializer.cs` - Инициализация логгера
@ -228,15 +232,10 @@
- `ReadOnlyInInspectorAttribute.cs` - Атрибут только для чтения в Inspector
- `AdvancedLoggingExample.cs` - Пример продвинутого логирования
#### **12. Editor/** - Редакторские скрипты
#### **13. Editor/** - Редакторские скрипты
- `MusicController_Inspector.cs` - Кастомный инспектор для MusicController
#### **13. Settings/_sega/** - Альтернативная система настроек (для SEGA автоматов)
- `SettingsScreen.cs` - Экран настроек
- `SettingsManager.cs` - Менеджер настроек
- `SettingsCombination.cs` - Комбинации настроек
- `SettingOption.cs` - Отдельная настройка
- `GameSettings.cs` - Настройки игры
- `SettingEntryDrawer.cs` - Кастомный drawer для настроек
- `SettingsDatabaseEditor.cs` - Редактор базы данных настроек
---
@ -479,16 +478,24 @@ GameSettings.ApplySettings()
4. Обновить switch в `In.Initialize()`
### Добавление новой настройки:
1. Добавить поле в `GameSettings`
2. Обновить UI в `SettingsUIList`
3. Добавить валидацию в `GameSettings.ValidateSettings()`
4. Реализовать применение в `GameSettings.ApplySettings()`
1. Открыть `MainSettingsDatabase.asset` в инспекторе
2. Добавить новую запись в список `Entries`:
- `Key` - уникальный ключ (например, `gameplay.newSetting`)
- `Display Name` - отображаемое имя
- `Group` - группа настроек
- `Value Type` - тип значения (Bool, Int, Float, String, Button, OptionPicker)
- Значения по умолчанию и диапазоны
3. Если нужно применять настройку автоматически:
- Указать `Apply Target` (например, AudioMixerFloat01ToDb)
- Или добавить логику в `SettingsApplier.cs`
4. Для кнопок - использовать `SettingsButtonBinder` на объекте сцены
5. Для доступа из кода - добавить ключ в `SettingKeys` и свойство в `SettingsManager`
---
## Известные особенности
1. **Двойная система настроек**: Есть основная система настроек и альтернативная в папке `_sega` для специфичных аркадных автоматов.
1. **Система настроек**: Использует ScriptableObject `SettingsDatabase` для хранения конфигурации и JSON-файл для сохранения значений.
2. **Временные файлы**: Файлы с суффиксом `_Temp` являются временными решениями или устаревшими версиями.
@ -506,4 +513,3 @@ GameSettings.ApplySettings()
---
*Документ создан автоматически на основе анализа структуры проекта.*

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,42 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 027e2a80a35347cc88fd95122dff58a5, type: 3}
m_Name: MainSettingsDatabase
m_EditorClassIdentifier: Assembly-CSharp::SettingsNew.Core.SettingsDatabase
entries:
- key: btn.c
displayName:
description:
group:
valueType: 4
defaultBool: 0
defaultInt: 0
defaultFloat: 0
defaultString:
minInt: 0
maxInt: 0
minFloat: 0
maxFloat: 0
applyTarget: 0
mixer: {fileID: 0}
mixerParameter:
minDb: 0
maxDb: 0
buttonText:
buttonData:
buttonColor: {r: 1, g: 1, b: 1, a: 1}
buttonSprite: {fileID: 0}
buttonClickEvent:
m_PersistentCalls:
m_Calls: []
options: []
defaultOptionIndex: 0

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 70cc67715dadf564eab708239afeeec6
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -59,7 +59,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
title: {fileID: 2985328858931436486}
btn: {fileID: 7403115420713256969}
button: {fileID: 0}
--- !u!1 &2307937535396352836
GameObject:
m_ObjectHideFlags: 0
@ -163,6 +163,7 @@ MonoBehaviour:
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0

View File

@ -0,0 +1,461 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &417335184483867252
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7223620359343937790}
- component: {fileID: 1586005624957061752}
- component: {fileID: 6977524014547828627}
- component: {fileID: 7538078367188529335}
- component: {fileID: 1483858353458498645}
m_Layer: 0
m_Name: Header
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &7223620359343937790
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 417335184483867252}
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: 44893884476176364}
m_Father: {fileID: 5150043027333259689}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &1586005624957061752
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 417335184483867252}
m_CullTransparentMesh: 1
--- !u!114 &6977524014547828627
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 417335184483867252}
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: 1, b: 1, 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: -8111322212487550922, guid: 31b2877e77610584cac3a41c46e85320, type: 3}
m_Type: 1
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 &7538078367188529335
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 417335184483867252}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Button
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 6977524014547828627}
m_OnClick:
m_PersistentCalls:
m_Calls: []
--- !u!114 &1483858353458498645
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 417335184483867252}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.LayoutElement
m_IgnoreLayout: 0
m_MinWidth: -1
m_MinHeight: -1
m_PreferredWidth: 600
m_PreferredHeight: 50
m_FlexibleWidth: -1
m_FlexibleHeight: -1
m_LayoutPriority: 1
--- !u!1 &2377691962366175998
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6166457296002841149}
- component: {fileID: 8196548391682863322}
- component: {fileID: 8608163453578936731}
- component: {fileID: 1081386272082221597}
m_Layer: 0
m_Name: ContentRoot
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &6166457296002841149
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2377691962366175998}
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: 5150043027333259689}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 300, y: -50}
m_SizeDelta: {x: 600, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &8196548391682863322
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2377691962366175998}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.VerticalLayoutGroup
m_Padding:
m_Left: 0
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 0
m_ChildForceExpandWidth: 0
m_ChildForceExpandHeight: 0
m_ChildControlWidth: 1
m_ChildControlHeight: 1
m_ChildScaleWidth: 0
m_ChildScaleHeight: 0
m_ReverseArrangement: 0
--- !u!114 &8608163453578936731
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2377691962366175998}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.LayoutElement
m_IgnoreLayout: 0
m_MinWidth: -1
m_MinHeight: -1
m_PreferredWidth: 600
m_PreferredHeight: -1
m_FlexibleWidth: -1
m_FlexibleHeight: -1
m_LayoutPriority: 1
--- !u!114 &1081386272082221597
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2377691962366175998}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.ContentSizeFitter
m_HorizontalFit: 0
m_VerticalFit: 2
--- !u!1 &4929744536442776760
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5150043027333259689}
- component: {fileID: 7434999243356666657}
- component: {fileID: 2186865876444500735}
m_Layer: 0
m_Name: Panel_Group
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5150043027333259689
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4929744536442776760}
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: 7223620359343937790}
- {fileID: 6166457296002841149}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 600, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &7434999243356666657
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4929744536442776760}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.VerticalLayoutGroup
m_Padding:
m_Left: 0
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 0
m_ChildForceExpandWidth: 0
m_ChildForceExpandHeight: 0
m_ChildControlWidth: 1
m_ChildControlHeight: 1
m_ChildScaleWidth: 0
m_ChildScaleHeight: 0
m_ReverseArrangement: 0
--- !u!114 &2186865876444500735
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4929744536442776760}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 128f5ee47aca9f446aa436d617fa5dcf, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::RR.Common.UI.SettingsGroupPanel
titleText: {fileID: 8727212233685038289}
headerButton: {fileID: 7538078367188529335}
contentRoot: {fileID: 2377691962366175998}
iconExpanded: {fileID: 0}
iconCollapsed: {fileID: 0}
--- !u!1 &7809264704238187303
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 44893884476176364}
- component: {fileID: 7557072363394649782}
- component: {fileID: 8727212233685038289}
m_Layer: 0
m_Name: Text (TMP)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &44893884476176364
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7809264704238187303}
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: 7223620359343937790}
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!222 &7557072363394649782
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7809264704238187303}
m_CullTransparentMesh: 1
--- !u!114 &8727212233685038289
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7809264704238187303}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, 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_text: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4281479730
m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 24
m_fontSizeBase: 24
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}

View File

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

View File

@ -0,0 +1,350 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1758083603916175787
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7082477975537308933}
- component: {fileID: 6418208233271057322}
- component: {fileID: 226186850308132312}
- component: {fileID: 6489304585556535039}
m_Layer: 0
m_Name: Row_Button
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &7082477975537308933
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1758083603916175787}
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: 4651342010868548259}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 200, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &6418208233271057322
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1758083603916175787}
m_CullTransparentMesh: 1
--- !u!114 &226186850308132312
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1758083603916175787}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.LayoutElement
m_IgnoreLayout: 0
m_MinWidth: -1
m_MinHeight: -1
m_PreferredWidth: 200
m_PreferredHeight: 70
m_FlexibleWidth: -1
m_FlexibleHeight: -1
m_LayoutPriority: 1
--- !u!114 &6489304585556535039
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1758083603916175787}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4c856f3cf51e81642a471d0300e1cdea, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::RR.Common.UI.SettingUIItem
titleText: {fileID: 2985328858931436486}
descriptionText: {fileID: 0}
toggle: {fileID: 0}
slider: {fileID: 0}
dropdown: {fileID: 0}
input: {fileID: 0}
button: {fileID: 7403115420713256969}
prevButton: {fileID: 0}
nextButton: {fileID: 0}
optionValueText: {fileID: 0}
sliderValueText: {fileID: 0}
--- !u!1 &2307937535396352836
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7969020585539137307}
- component: {fileID: 2544164544592874034}
- component: {fileID: 2985328858931436486}
m_Layer: 0
m_Name: Title
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &7969020585539137307
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2307937535396352836}
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: 4651342010868548259}
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: -20, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &2544164544592874034
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2307937535396352836}
m_CullTransparentMesh: 1
--- !u!114 &2985328858931436486
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2307937535396352836}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, 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_text: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 5302535af1044152a457ed104f1f4b91, type: 2}
m_sharedMaterial: {fileID: 2164040, guid: 5302535af1044152a457ed104f1f4b91, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4278190080
m_fontColor: {r: 0, g: 0, b: 0, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 36.35
m_fontSizeBase: 48
m_fontWeight: 400
m_enableAutoSizing: 1
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &7033118707232536323
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4651342010868548259}
- component: {fileID: 739767321169741777}
- component: {fileID: 4558843671109735324}
- component: {fileID: 7403115420713256969}
m_Layer: 0
m_Name: Button
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &4651342010868548259
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7033118707232536323}
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: 7969020585539137307}
m_Father: {fileID: 7082477975537308933}
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!222 &739767321169741777
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7033118707232536323}
m_CullTransparentMesh: 1
--- !u!114 &4558843671109735324
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7033118707232536323}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, 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: -8111322212487550922, guid: 31b2877e77610584cac3a41c46e85320, type: 3}
m_Type: 1
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 &7403115420713256969
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7033118707232536323}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 0.76862746, g: 0.76862746, b: 0.76862746, a: 1}
m_HighlightedColor: {r: 1, g: 1, b: 1, a: 1}
m_PressedColor: {r: 1, g: 1, b: 1, a: 1}
m_SelectedColor: {r: 1, g: 1, b: 1, a: 1}
m_DisabledColor: {r: 0.63529414, g: 0.63529414, b: 0.63529414, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 4558843671109735324}
m_OnClick:
m_PersistentCalls:
m_Calls: []

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -0,0 +1,746 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &860684354036165143
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4502610026847037412}
- component: {fileID: 3008051135215609571}
- component: {fileID: 3009196513636579794}
m_Layer: 5
m_Name: Title
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &4502610026847037412
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 860684354036165143}
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: 5150043027333259689}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 125, y: 0}
m_SizeDelta: {x: 200, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3008051135215609571
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 860684354036165143}
m_CullTransparentMesh: 1
--- !u!114 &3009196513636579794
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 860684354036165143}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, 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_text: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 5302535af1044152a457ed104f1f4b91, type: 2}
m_sharedMaterial: {fileID: 2164040, guid: 5302535af1044152a457ed104f1f4b91, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4294967295
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 40.4
m_fontSizeBase: 36
m_fontWeight: 400
m_enableAutoSizing: 1
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &4428142733030258062
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8721797739197876139}
- component: {fileID: 5585280728525912448}
- component: {fileID: 3160103770041870317}
m_Layer: 0
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &8721797739197876139
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4428142733030258062}
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: 2877456500549799049}
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!222 &5585280728525912448
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4428142733030258062}
m_CullTransparentMesh: 1
--- !u!114 &3160103770041870317
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4428142733030258062}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, 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_text: "\u200B"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4281479730
m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 14
m_fontSizeBase: 14
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 1
m_VerticalAlignment: 256
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 3
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 1
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &4929744536442776760
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5150043027333259689}
- component: {fileID: 2440819936744142218}
- component: {fileID: 895630567611506380}
m_Layer: 0
m_Name: Row_Input
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5150043027333259689
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4929744536442776760}
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: 4502610026847037412}
- {fileID: 4122145645385241789}
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!114 &2440819936744142218
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4929744536442776760}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.LayoutElement
m_IgnoreLayout: 0
m_MinWidth: -1
m_MinHeight: -1
m_PreferredWidth: -1
m_PreferredHeight: 70
m_FlexibleWidth: -1
m_FlexibleHeight: -1
m_LayoutPriority: 1
--- !u!114 &895630567611506380
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4929744536442776760}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4c856f3cf51e81642a471d0300e1cdea, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::RR.Common.UI.SettingUIItem
titleText: {fileID: 3009196513636579794}
descriptionText: {fileID: 0}
toggle: {fileID: 0}
slider: {fileID: 0}
dropdown: {fileID: 0}
input: {fileID: 8272964721386694048}
button: {fileID: 0}
prevButton: {fileID: 0}
nextButton: {fileID: 0}
optionValueText: {fileID: 0}
sliderValueText: {fileID: 0}
--- !u!1 &6023921782997141132
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 365479938881989914}
- component: {fileID: 8120212292789898930}
- component: {fileID: 3068325503824783100}
- component: {fileID: 588040392967248182}
m_Layer: 0
m_Name: Placeholder
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &365479938881989914
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6023921782997141132}
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: 2877456500549799049}
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!222 &8120212292789898930
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6023921782997141132}
m_CullTransparentMesh: 1
--- !u!114 &3068325503824783100
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6023921782997141132}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, 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_text: Enter text...
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 2150773298
m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 32
m_fontSizeBase: 32
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 2
m_HorizontalAlignment: 1
m_VerticalAlignment: 256
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 0
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 1
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!114 &588040392967248182
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6023921782997141132}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.LayoutElement
m_IgnoreLayout: 1
m_MinWidth: -1
m_MinHeight: -1
m_PreferredWidth: -1
m_PreferredHeight: -1
m_FlexibleWidth: -1
m_FlexibleHeight: -1
m_LayoutPriority: 1
--- !u!1 &6208252631599812857
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2877456500549799049}
- component: {fileID: 896467222847671967}
m_Layer: 0
m_Name: Text Area
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &2877456500549799049
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6208252631599812857}
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: 365479938881989914}
- {fileID: 8721797739197876139}
m_Father: {fileID: 4122145645385241789}
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.5}
m_SizeDelta: {x: -20, y: -13}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &896467222847671967
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6208252631599812857}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3312d7739989d2b4e91e6319e9a96d76, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.RectMask2D
m_Padding: {x: -8, y: -5, z: -8, w: -5}
m_Softness: {x: 0, y: 0}
--- !u!1 &6581149825556948445
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4122145645385241789}
- component: {fileID: 2680561742725202181}
- component: {fileID: 8567026936409664070}
- component: {fileID: 8272964721386694048}
m_Layer: 0
m_Name: InputField (TMP)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &4122145645385241789
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6581149825556948445}
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: 2877456500549799049}
m_Father: {fileID: 5150043027333259689}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 355, y: 0}
m_SizeDelta: {x: 200, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &2680561742725202181
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6581149825556948445}
m_CullTransparentMesh: 1
--- !u!114 &8567026936409664070
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6581149825556948445}
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: 1, b: 1, 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: 10911, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
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 &8272964721386694048
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6581149825556948445}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TMP_InputField
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 8567026936409664070}
m_TextViewport: {fileID: 2877456500549799049}
m_TextComponent: {fileID: 3160103770041870317}
m_Placeholder: {fileID: 3068325503824783100}
m_VerticalScrollbar: {fileID: 0}
m_VerticalScrollbarEventHandler: {fileID: 0}
m_LayoutGroup: {fileID: 0}
m_ScrollSensitivity: 1
m_ContentType: 0
m_InputType: 0
m_AsteriskChar: 42
m_KeyboardType: 0
m_LineType: 0
m_HideMobileInput: 0
m_HideSoftKeyboard: 0
m_CharacterValidation: 0
m_RegexValue:
m_GlobalPointSize: 14
m_CharacterLimit: 0
m_OnEndEdit:
m_PersistentCalls:
m_Calls: []
m_OnSubmit:
m_PersistentCalls:
m_Calls: []
m_OnSelect:
m_PersistentCalls:
m_Calls: []
m_OnDeselect:
m_PersistentCalls:
m_Calls: []
m_OnTextSelection:
m_PersistentCalls:
m_Calls: []
m_OnEndTextSelection:
m_PersistentCalls:
m_Calls: []
m_OnValueChanged:
m_PersistentCalls:
m_Calls: []
m_OnTouchScreenKeyboardStatusChanged:
m_PersistentCalls:
m_Calls: []
m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_CustomCaretColor: 0
m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412}
m_Text:
m_CaretBlinkRate: 0.85
m_CaretWidth: 1
m_ReadOnly: 0
m_RichText: 1
m_GlobalFontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_OnFocusSelectAll: 1
m_ResetOnDeActivation: 1
m_KeepTextSelectionVisible: 0
m_RestoreOriginalTextOnEscape: 1
m_isRichTextEditingAllowed: 0
m_LineLimit: 0
isAlert: 0
m_InputValidator: {fileID: 0}
m_ShouldActivateOnSelect: 1

View File

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

View File

@ -0,0 +1,746 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &773340722142896225
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1051025939675208193}
- component: {fileID: 6471654452244886751}
- component: {fileID: 4494883196475282028}
m_Layer: 5
m_Name: Fill
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1051025939675208193
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 773340722142896225}
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: 4866847921894050172}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 10, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &6471654452244886751
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 773340722142896225}
m_CullTransparentMesh: 1
--- !u!114 &4494883196475282028
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 773340722142896225}
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: 0, g: 1, b: 0.13725491, 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: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
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!1 &860684354036165143
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4502610026847037412}
- component: {fileID: 3008051135215609571}
- component: {fileID: 3009196513636579794}
m_Layer: 5
m_Name: Title
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &4502610026847037412
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 860684354036165143}
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: 5150043027333259689}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 125, y: 0}
m_SizeDelta: {x: 200, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3008051135215609571
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 860684354036165143}
m_CullTransparentMesh: 1
--- !u!114 &3009196513636579794
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 860684354036165143}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, 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_text: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 5302535af1044152a457ed104f1f4b91, type: 2}
m_sharedMaterial: {fileID: 2164040, guid: 5302535af1044152a457ed104f1f4b91, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4294967295
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 40.4
m_fontSizeBase: 36
m_fontWeight: 400
m_enableAutoSizing: 1
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 1
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &1497013245918143361
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 561097124473651085}
- component: {fileID: 248643673657322142}
- component: {fileID: 6894216868823741208}
m_Layer: 5
m_Name: Background
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &561097124473651085
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1497013245918143361}
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: 403938188213259336}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.25}
m_AnchorMax: {x: 1, y: 0.75}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &248643673657322142
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1497013245918143361}
m_CullTransparentMesh: 1
--- !u!114 &6894216868823741208
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1497013245918143361}
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: 1, b: 1, 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: 10907, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
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!1 &1708180760562552811
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4866847921894050172}
m_Layer: 5
m_Name: Fill Area
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &4866847921894050172
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1708180760562552811}
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: 1051025939675208193}
m_Father: {fileID: 403938188213259336}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.25}
m_AnchorMax: {x: 1, y: 0.75}
m_AnchoredPosition: {x: 2.5, y: 0}
m_SizeDelta: {x: -5, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &2123479710510939704
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 403938188213259336}
- component: {fileID: 460307191981496633}
m_Layer: 5
m_Name: Slider
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &403938188213259336
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2123479710510939704}
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: 1
m_Children:
- {fileID: 561097124473651085}
- {fileID: 4866847921894050172}
- {fileID: 5357950672568869866}
m_Father: {fileID: 5150043027333259689}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 335, y: 0}
m_SizeDelta: {x: 160, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &460307191981496633
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2123479710510939704}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 67db9e8f0e2ae9c40bc1e2b64352a6b4, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Slider
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 8648751873657311392}
m_FillRect: {fileID: 1051025939675208193}
m_HandleRect: {fileID: 7945817689209150983}
m_Direction: 0
m_MinValue: 0
m_MaxValue: 1
m_WholeNumbers: 0
m_Value: 0
m_OnValueChanged:
m_PersistentCalls:
m_Calls: []
--- !u!1 &4929744536442776760
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5150043027333259689}
- component: {fileID: 2440819936744142218}
- component: {fileID: 5445087308684328405}
m_Layer: 0
m_Name: Row_Slider
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5150043027333259689
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4929744536442776760}
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: 4502610026847037412}
- {fileID: 403938188213259336}
- {fileID: 1157046496909858781}
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!114 &2440819936744142218
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4929744536442776760}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.LayoutElement
m_IgnoreLayout: 0
m_MinWidth: -1
m_MinHeight: -1
m_PreferredWidth: -1
m_PreferredHeight: 70
m_FlexibleWidth: -1
m_FlexibleHeight: -1
m_LayoutPriority: 1
--- !u!114 &5445087308684328405
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4929744536442776760}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4c856f3cf51e81642a471d0300e1cdea, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::RR.Common.UI.SettingUIItem
titleText: {fileID: 3009196513636579794}
descriptionText: {fileID: 0}
toggle: {fileID: 0}
slider: {fileID: 460307191981496633}
dropdown: {fileID: 0}
input: {fileID: 0}
button: {fileID: 0}
prevButton: {fileID: 0}
nextButton: {fileID: 0}
optionValueText: {fileID: 0}
sliderValueText: {fileID: 1248121056443275380}
--- !u!1 &7179815661374964089
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1157046496909858781}
- component: {fileID: 7030323190132174259}
- component: {fileID: 1248121056443275380}
m_Layer: 5
m_Name: Value
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1157046496909858781
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7179815661374964089}
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: 1
m_Children: []
m_Father: {fileID: 5150043027333259689}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 550, y: 0}
m_SizeDelta: {x: 200, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &7030323190132174259
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7179815661374964089}
m_CullTransparentMesh: 1
--- !u!114 &1248121056443275380
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7179815661374964089}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, 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_text: 100%
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 5302535af1044152a457ed104f1f4b91, type: 2}
m_sharedMaterial: {fileID: 2164040, guid: 5302535af1044152a457ed104f1f4b91, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4294967295
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 36
m_fontSizeBase: 36
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 1
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &7987741479391981253
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5357950672568869866}
m_Layer: 5
m_Name: Handle Slide Area
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5357950672568869866
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7987741479391981253}
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: 7945817689209150983}
m_Father: {fileID: 403938188213259336}
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: -20, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &9054950456300918208
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7945817689209150983}
- component: {fileID: 6908825906697791335}
- component: {fileID: 8648751873657311392}
m_Layer: 5
m_Name: Handle
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &7945817689209150983
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9054950456300918208}
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: 5357950672568869866}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 40, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &6908825906697791335
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9054950456300918208}
m_CullTransparentMesh: 1
--- !u!114 &8648751873657311392
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9054950456300918208}
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: 1, b: 1, a: 0}
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: 10913, guid: 0000000000000000f000000000000000, type: 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

View File

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

View File

@ -0,0 +1,457 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &860684354036165143
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4502610026847037412}
- component: {fileID: 3008051135215609571}
- component: {fileID: 3009196513636579794}
m_Layer: 5
m_Name: Title
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &4502610026847037412
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 860684354036165143}
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: 5150043027333259689}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 125, y: 0}
m_SizeDelta: {x: 200, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3008051135215609571
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 860684354036165143}
m_CullTransparentMesh: 1
--- !u!114 &3009196513636579794
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 860684354036165143}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, 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_text: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 5302535af1044152a457ed104f1f4b91, type: 2}
m_sharedMaterial: {fileID: 2164040, guid: 5302535af1044152a457ed104f1f4b91, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4294967295
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 40.4
m_fontSizeBase: 36
m_fontWeight: 400
m_enableAutoSizing: 1
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &4929744536442776760
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5150043027333259689}
- component: {fileID: 2440819936744142218}
- component: {fileID: -3497382869404314779}
m_Layer: 0
m_Name: Row_Toggle
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5150043027333259689
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4929744536442776760}
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: 4502610026847037412}
- {fileID: 3024015130496851427}
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!114 &2440819936744142218
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4929744536442776760}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.LayoutElement
m_IgnoreLayout: 0
m_MinWidth: -1
m_MinHeight: -1
m_PreferredWidth: -1
m_PreferredHeight: 70
m_FlexibleWidth: -1
m_FlexibleHeight: -1
m_LayoutPriority: 1
--- !u!114 &-3497382869404314779
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4929744536442776760}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4c856f3cf51e81642a471d0300e1cdea, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::RR.Common.UI.SettingUIItem
titleText: {fileID: 3009196513636579794}
descriptionText: {fileID: 0}
toggle: {fileID: 7885915603881838214}
slider: {fileID: 0}
dropdown: {fileID: 0}
input: {fileID: 0}
button: {fileID: 0}
prevButton: {fileID: 0}
nextButton: {fileID: 0}
optionValueText: {fileID: 0}
sliderValueText: {fileID: 0}
--- !u!1 &5250804521055294169
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4046930335402022471}
- component: {fileID: 7842595529731259020}
- component: {fileID: 7981003531007891996}
m_Layer: 0
m_Name: Background
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &4046930335402022471
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5250804521055294169}
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: 1097500978698976594}
m_Father: {fileID: 3024015130496851427}
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!222 &7842595529731259020
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5250804521055294169}
m_CullTransparentMesh: 1
--- !u!114 &7981003531007891996
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5250804521055294169}
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: 1, b: 1, 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: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
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!1 &7951234635662685345
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3024015130496851427}
- component: {fileID: 7885915603881838214}
m_Layer: 0
m_Name: Toggle
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &3024015130496851427
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7951234635662685345}
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: 4046930335402022471}
m_Father: {fileID: 5150043027333259689}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 275, y: 0}
m_SizeDelta: {x: 50, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &7885915603881838214
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7951234635662685345}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Toggle
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 7981003531007891996}
toggleTransition: 1
graphic: {fileID: 5944280515083907282}
m_Group: {fileID: 0}
onValueChanged:
m_PersistentCalls:
m_Calls: []
m_IsOn: 1
--- !u!1 &9163954176978666614
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1097500978698976594}
- component: {fileID: 6878167230870725067}
- component: {fileID: 5944280515083907282}
m_Layer: 0
m_Name: Checkmark
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1097500978698976594
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9163954176978666614}
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: 4046930335402022471}
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: -10, y: -10}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &6878167230870725067
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9163954176978666614}
m_CullTransparentMesh: 1
--- !u!114 &5944280515083907282
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9163954176978666614}
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: 1, b: 1, 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: -6415649246072548017, guid: 27834320931067c4b9127246cba948d2, type: 3}
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

View File

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

View File

@ -60,10 +60,10 @@ MonoBehaviour:
m_GameObject: {fileID: 4763496076470024150}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a0811f9af9cb5dc4fbd4d2be780bb43f, type: 3}
m_Script: {fileID: 11500000, guid: 2c4a3f878fc0c59429e24e6f7f80ed2a, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::RR.Common.Managers.SettingsManager
gameSettings: {fileID: 11400000, guid: bdc702de5b61eae45a0dc18413673fd8, type: 2}
m_EditorClassIdentifier: Assembly-CSharp::RR.Common.Settings.SettingsManager
database: {fileID: 11400000, guid: 29cc91230b52fab4494eb90856f51c2c, type: 2}
--- !u!114 &4577859410310799261
MonoBehaviour:
m_ObjectHideFlags: 0
@ -75,7 +75,7 @@ MonoBehaviour:
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d793a5f3669a676418d43519feaf3a8d, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::ComWrapper
m_EditorClassIdentifier: Assembly-CSharp::RR.Common.Controls.ComWrapper
saveMoneyBetweenSessions: 0
enablePrizeChecking: 0
keepAlive: 1
@ -90,7 +90,7 @@ MonoBehaviour:
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dec428d33ffedb846aa3568b5dbc6d49, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::In
m_EditorClassIdentifier: Assembly-CSharp::RR.Common.Controls.In
inputType: 0
--- !u!114 &6566017136146807207
MonoBehaviour:
@ -103,7 +103,7 @@ MonoBehaviour:
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 04cb8758b49014f4caca890b913d86c0, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::PrizeSystem
m_EditorClassIdentifier: Assembly-CSharp::RR.Common.Controls.PrizeSystem
prizeErrorSound: {fileID: 0}
--- !u!114 &5633451267958679388
MonoBehaviour:
@ -116,7 +116,7 @@ MonoBehaviour:
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6e1ef22bfa89b354ea58dcf83572936a, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::PrizeSystemManager
m_EditorClassIdentifier: Assembly-CSharp::RR.Common.Managers.PrizeSystemManager
givePrizes: 1
enableHopper: 0
qrCodes:
@ -170,7 +170,7 @@ MonoBehaviour:
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 10f5cf4411135b245baf35e2705982c7, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::ComInputToInputSystemAdapter
m_EditorClassIdentifier: Assembly-CSharp::RR.Common.Controls.ComInputToInputSystemAdapter
useAnyPlayer: 1
actionBindings: []
pinBindings:

View File

@ -0,0 +1,204 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 027e2a80a35347cc88fd95122dff58a5, type: 3}
m_Name: SettingsDatabase
m_EditorClassIdentifier: Assembly-CSharp::RR.Common.Settings.SettingsDatabase
entries:
- key: musicVolume
displayName: Громкость музыки
description:
group: Музыка и звуки
valueType: 2
defaultBool: 0
defaultInt: 0
defaultFloat: 1
defaultString:
minInt: 0
maxInt: 100
minFloat: 0
maxFloat: 1
applyTarget: 0
mixer: {fileID: 0}
mixerParameter:
minDb: -80
maxDb: 0
buttonText:
buttonData:
buttonColor: {r: 1, g: 1, b: 1, a: 1}
buttonSprite: {fileID: 0}
buttonClickEvent:
m_PersistentCalls:
m_Calls: []
options: []
defaultOptionIndex: 0
- key: sfxVolume
displayName: Громкость звуков
description:
group: Музыка и звуки
valueType: 2
defaultBool: 0
defaultInt: 0
defaultFloat: 1
defaultString:
minInt: 0
maxInt: 100
minFloat: 0
maxFloat: 1
applyTarget: 0
mixer: {fileID: 0}
mixerParameter:
minDb: -80
maxDb: 0
buttonText:
buttonData:
buttonColor: {r: 1, g: 1, b: 1, a: 1}
buttonSprite: {fileID: 0}
buttonClickEvent:
m_PersistentCalls:
m_Calls: []
options: []
defaultOptionIndex: 0
- key: isFreeGame
displayName: Бесплатная игра
description:
group: Оплата и стоимость
valueType: 0
defaultBool: 0
defaultInt: 0
defaultFloat: 0
defaultString:
minInt: 0
maxInt: 0
minFloat: 0
maxFloat: 0
applyTarget: 0
mixer: {fileID: 0}
mixerParameter:
minDb: 0
maxDb: 0
buttonText:
buttonData:
buttonColor: {r: 1, g: 1, b: 1, a: 1}
buttonSprite: {fileID: 0}
buttonClickEvent:
m_PersistentCalls:
m_Calls: []
options: []
defaultOptionIndex: 0
- key: isGivingPrizes
displayName: Выдача призов
description:
group: Призы и выдача
valueType: 0
defaultBool: 1
defaultInt: 0
defaultFloat: 0
defaultString:
minInt: 0
maxInt: 0
minFloat: 0
maxFloat: 0
applyTarget: 0
mixer: {fileID: 0}
mixerParameter:
minDb: 0
maxDb: 0
buttonText:
buttonData:
buttonColor: {r: 1, g: 1, b: 1, a: 1}
buttonSprite: {fileID: 0}
buttonClickEvent:
m_PersistentCalls:
m_Calls: []
options: []
defaultOptionIndex: 0
- key: startLivesCount
displayName: Начальные жизни
description:
group: Игровой процесс
valueType: 1
defaultBool: 0
defaultInt: 3
defaultFloat: 0
defaultString:
minInt: 1
maxInt: 10
minFloat: 0
maxFloat: 0
applyTarget: 0
mixer: {fileID: 0}
mixerParameter:
minDb: 0
maxDb: 0
buttonText:
buttonData:
buttonColor: {r: 1, g: 1, b: 1, a: 1}
buttonSprite: {fileID: 0}
buttonClickEvent:
m_PersistentCalls:
m_Calls: []
options: []
defaultOptionIndex: 0
- key: livesIncreasedByCredits
displayName: Жизни за кредит
description:
group: Игровой процесс
valueType: 1
defaultBool: 0
defaultInt: 1
defaultFloat: 0
defaultString:
minInt: 0
maxInt: 5
minFloat: 0
maxFloat: 0
applyTarget: 0
mixer: {fileID: 0}
mixerParameter:
minDb: 0
maxDb: 0
buttonText:
buttonData:
buttonColor: {r: 1, g: 1, b: 1, a: 1}
buttonSprite: {fileID: 0}
buttonClickEvent:
m_PersistentCalls:
m_Calls: []
options: []
defaultOptionIndex: 0
- key: isFullscreen
displayName: Полноэкранный режим
description:
group: Графика
valueType: 0
defaultBool: 1
defaultInt: 0
defaultFloat: 0
defaultString:
minInt: 0
maxInt: 0
minFloat: 0
maxFloat: 0
applyTarget: 5
mixer: {fileID: 0}
mixerParameter:
minDb: 0
maxDb: 0
buttonText:
buttonData:
buttonColor: {r: 1, g: 1, b: 1, a: 1}
buttonSprite: {fileID: 0}
buttonClickEvent:
m_PersistentCalls:
m_Calls: []
options: []
defaultOptionIndex: 0

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 302a6a5d301a42b449794804665ca05d
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -954,6 +954,63 @@ Transform:
m_CorrespondingSourceObject: {fileID: 4000011826580284, guid: 93b90907e99e38a448aca4707806a9be, type: 3}
m_PrefabInstance: {fileID: 253012030}
m_PrefabAsset: {fileID: 0}
--- !u!1001 &267442482
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 1000013301305156, guid: ce611ebabf8eb0f4683c660f008c8b88, type: 3}
propertyPath: m_Name
value: Enemy_2
objectReference: {fileID: 0}
- target: {fileID: 4000010470550876, guid: ce611ebabf8eb0f4683c660f008c8b88, type: 3}
propertyPath: m_LocalPosition.x
value: 53.317066
objectReference: {fileID: 0}
- target: {fileID: 4000010470550876, guid: ce611ebabf8eb0f4683c660f008c8b88, type: 3}
propertyPath: m_LocalPosition.y
value: 64.18047
objectReference: {fileID: 0}
- target: {fileID: 4000010470550876, guid: ce611ebabf8eb0f4683c660f008c8b88, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000010470550876, guid: ce611ebabf8eb0f4683c660f008c8b88, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4000010470550876, guid: ce611ebabf8eb0f4683c660f008c8b88, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000010470550876, guid: ce611ebabf8eb0f4683c660f008c8b88, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000010470550876, guid: ce611ebabf8eb0f4683c660f008c8b88, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000010470550876, guid: ce611ebabf8eb0f4683c660f008c8b88, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000010470550876, guid: ce611ebabf8eb0f4683c660f008c8b88, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000010470550876, guid: ce611ebabf8eb0f4683c660f008c8b88, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: ce611ebabf8eb0f4683c660f008c8b88, type: 3}
--- !u!1001 &269881935
PrefabInstance:
m_ObjectHideFlags: 0
@ -1935,6 +1992,63 @@ BoxCollider2D:
m_AutoTiling: 0
m_Size: {x: 1, y: 1}
m_EdgeRadius: 0
--- !u!1001 &348531057
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 2292326756536553419, guid: 2476b7fff96627f439721703c5d2e9a3, type: 3}
propertyPath: m_Name
value: Enemy_Crab
objectReference: {fileID: 0}
- target: {fileID: 7794497313669146320, guid: 2476b7fff96627f439721703c5d2e9a3, type: 3}
propertyPath: m_LocalPosition.x
value: 77.525826
objectReference: {fileID: 0}
- target: {fileID: 7794497313669146320, guid: 2476b7fff96627f439721703c5d2e9a3, type: 3}
propertyPath: m_LocalPosition.y
value: 63.135784
objectReference: {fileID: 0}
- target: {fileID: 7794497313669146320, guid: 2476b7fff96627f439721703c5d2e9a3, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7794497313669146320, guid: 2476b7fff96627f439721703c5d2e9a3, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7794497313669146320, guid: 2476b7fff96627f439721703c5d2e9a3, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7794497313669146320, guid: 2476b7fff96627f439721703c5d2e9a3, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7794497313669146320, guid: 2476b7fff96627f439721703c5d2e9a3, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7794497313669146320, guid: 2476b7fff96627f439721703c5d2e9a3, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7794497313669146320, guid: 2476b7fff96627f439721703c5d2e9a3, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7794497313669146320, guid: 2476b7fff96627f439721703c5d2e9a3, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 2476b7fff96627f439721703c5d2e9a3, type: 3}
--- !u!1 &348597427
GameObject:
m_ObjectHideFlags: 0
@ -3990,6 +4104,63 @@ Transform:
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &718857244
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 1000011821036864, guid: 93b90907e99e38a448aca4707806a9be, type: 3}
propertyPath: m_Name
value: Enemy_1
objectReference: {fileID: 0}
- target: {fileID: 4000011826580284, guid: 93b90907e99e38a448aca4707806a9be, type: 3}
propertyPath: m_LocalPosition.x
value: 44.301235
objectReference: {fileID: 0}
- target: {fileID: 4000011826580284, guid: 93b90907e99e38a448aca4707806a9be, type: 3}
propertyPath: m_LocalPosition.y
value: 64.08964
objectReference: {fileID: 0}
- target: {fileID: 4000011826580284, guid: 93b90907e99e38a448aca4707806a9be, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000011826580284, guid: 93b90907e99e38a448aca4707806a9be, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4000011826580284, guid: 93b90907e99e38a448aca4707806a9be, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000011826580284, guid: 93b90907e99e38a448aca4707806a9be, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000011826580284, guid: 93b90907e99e38a448aca4707806a9be, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000011826580284, guid: 93b90907e99e38a448aca4707806a9be, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000011826580284, guid: 93b90907e99e38a448aca4707806a9be, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4000011826580284, guid: 93b90907e99e38a448aca4707806a9be, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 93b90907e99e38a448aca4707806a9be, type: 3}
--- !u!1 &723988265
GameObject:
m_ObjectHideFlags: 0
@ -8552,6 +8723,63 @@ PrefabInstance:
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 2476b7fff96627f439721703c5d2e9a3, type: 3}
--- !u!1001 &1553660625
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 5850662015859581841, guid: 719adb0826e18974496b52e0c8aedb8c, type: 3}
propertyPath: m_Name
value: Enemy_2 Shooter
objectReference: {fileID: 0}
- target: {fileID: 5853556254035132809, guid: 719adb0826e18974496b52e0c8aedb8c, type: 3}
propertyPath: m_LocalPosition.x
value: 69.73631
objectReference: {fileID: 0}
- target: {fileID: 5853556254035132809, guid: 719adb0826e18974496b52e0c8aedb8c, type: 3}
propertyPath: m_LocalPosition.y
value: 64.22585
objectReference: {fileID: 0}
- target: {fileID: 5853556254035132809, guid: 719adb0826e18974496b52e0c8aedb8c, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5853556254035132809, guid: 719adb0826e18974496b52e0c8aedb8c, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5853556254035132809, guid: 719adb0826e18974496b52e0c8aedb8c, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5853556254035132809, guid: 719adb0826e18974496b52e0c8aedb8c, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5853556254035132809, guid: 719adb0826e18974496b52e0c8aedb8c, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5853556254035132809, guid: 719adb0826e18974496b52e0c8aedb8c, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5853556254035132809, guid: 719adb0826e18974496b52e0c8aedb8c, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5853556254035132809, guid: 719adb0826e18974496b52e0c8aedb8c, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 719adb0826e18974496b52e0c8aedb8c, type: 3}
--- !u!1001 &1560726197
PrefabInstance:
m_ObjectHideFlags: 0
@ -10847,6 +11075,63 @@ SpriteRenderer:
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_SpriteSortPoint: 0
--- !u!1001 &2033907137
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 5189545345688893226, guid: c346682d3752a69418079e320cffea54, type: 3}
propertyPath: m_LocalPosition.x
value: 61.992237
objectReference: {fileID: 0}
- target: {fileID: 5189545345688893226, guid: c346682d3752a69418079e320cffea54, type: 3}
propertyPath: m_LocalPosition.y
value: 64.27127
objectReference: {fileID: 0}
- target: {fileID: 5189545345688893226, guid: c346682d3752a69418079e320cffea54, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5189545345688893226, guid: c346682d3752a69418079e320cffea54, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5189545345688893226, guid: c346682d3752a69418079e320cffea54, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5189545345688893226, guid: c346682d3752a69418079e320cffea54, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5189545345688893226, guid: c346682d3752a69418079e320cffea54, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5189545345688893226, guid: c346682d3752a69418079e320cffea54, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5189545345688893226, guid: c346682d3752a69418079e320cffea54, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5189545345688893226, guid: c346682d3752a69418079e320cffea54, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5190767470298335574, guid: c346682d3752a69418079e320cffea54, type: 3}
propertyPath: m_Name
value: Enemy_1 Shooter
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: c346682d3752a69418079e320cffea54, type: 3}
--- !u!4 &2060164271 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 7794497313669146320, guid: 2476b7fff96627f439721703c5d2e9a3, type: 3}
@ -289001,3 +289286,8 @@ SceneRoots:
- {fileID: 573629650}
- {fileID: 2072045122}
- {fileID: 717095140}
- {fileID: 718857244}
- {fileID: 267442482}
- {fileID: 2033907137}
- {fileID: 1553660625}
- {fileID: 348531057}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
using System;
using System.Collections;
using System.Text;
using System;
using System.Collections;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using RR.Game2D.Core.Managers;

View File

@ -0,0 +1,280 @@
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using RR.Common.Settings;
namespace RR.Common.InspectorOverrides
{
[CustomPropertyDrawer(typeof(SettingEntry))]
public class SettingEntryDrawer : PropertyDrawer
{
private const float Pad = 6f;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
// Чтоб выглядело стабильнее в узких инспекторах
bool prevWide = EditorGUIUtility.wideMode;
float prevLabelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.wideMode = true;
EditorGUIUtility.labelWidth = 110f;
EditorGUI.BeginProperty(position, label, property);
var keyProp = property.FindPropertyRelative("key");
var nameProp = property.FindPropertyRelative("displayName");
var descProp = property.FindPropertyRelative("description");
var groupProp = property.FindPropertyRelative("group");
var typeProp = property.FindPropertyRelative("valueType");
var defBoolProp = property.FindPropertyRelative("defaultBool");
var defIntProp = property.FindPropertyRelative("defaultInt");
var defFloatProp = property.FindPropertyRelative("defaultFloat");
var defStringProp = property.FindPropertyRelative("defaultString");
var minIntProp = property.FindPropertyRelative("minInt");
var maxIntProp = property.FindPropertyRelative("maxInt");
var minFloatProp = property.FindPropertyRelative("minFloat");
var maxFloatProp = property.FindPropertyRelative("maxFloat");
var applyProp = property.FindPropertyRelative("applyTarget");
var mixerProp = property.FindPropertyRelative("mixer");
var mixerParamProp = property.FindPropertyRelative("mixerParameter");
var minDbProp = property.FindPropertyRelative("minDb");
var maxDbProp = property.FindPropertyRelative("maxDb");
float line = EditorGUIUtility.singleLineHeight;
float space = EditorGUIUtility.standardVerticalSpacing;
// Card
var box = new Rect(position.x, position.y, position.width, position.height);
GUI.Box(box, GUIContent.none, EditorStyles.helpBox);
var r = new Rect(position.x + Pad, position.y + Pad, position.width - Pad * 2, line);
// Header foldout
string header = BuildHeader(nameProp.stringValue, keyProp.stringValue);
property.isExpanded = EditorGUI.Foldout(r, property.isExpanded, header, true);
r.y += line + space;
if (!property.isExpanded)
{
EditorGUI.EndProperty();
EditorGUIUtility.wideMode = prevWide;
EditorGUIUtility.labelWidth = prevLabelWidth;
return;
}
DrawSectionTitle(ref r, "Meta");
DrawProp(ref r, nameProp, "Display Name");
DrawProp(ref r, keyProp, "Key");
DrawProp(ref r, groupProp, "Group");
DrawProp(ref r, descProp, "Description", includeChildren: true);
DrawSectionTitle(ref r, "Value");
DrawProp(ref r, typeProp, "Value Type");
var t = (SettingValueType)typeProp.enumValueIndex;
switch (t)
{
case SettingValueType.Bool:
DrawProp(ref r, defBoolProp, "Default");
break;
case SettingValueType.Int:
DrawProp(ref r, defIntProp, "Default");
DrawMinMaxRow(ref r, minIntProp, maxIntProp, "Min", "Max");
break;
case SettingValueType.Float:
DrawProp(ref r, defFloatProp, "Default");
DrawMinMaxRow(ref r, minFloatProp, maxFloatProp, "Min", "Max");
break;
case SettingValueType.String:
DrawProp(ref r, defStringProp, "Default");
break;
case SettingValueType.Button:
DrawSectionTitle(ref r, "Button Settings");
var buttonTextProp = property.FindPropertyRelative("buttonText");
var buttonDataProp = property.FindPropertyRelative("buttonData");
var buttonColorProp = property.FindPropertyRelative("buttonColor");
var buttonSpriteProp = property.FindPropertyRelative("buttonSprite");
DrawProp(ref r, buttonTextProp, "Button Text");
DrawProp(ref r, buttonDataProp, "Button Data");
DrawProp(ref r, buttonColorProp, "Button Color");
DrawProp(ref r, buttonSpriteProp, "Button Sprite");
break;
case SettingValueType.OptionPicker:
DrawSectionTitle(ref r, "Option Picker Settings");
var optionsProp = property.FindPropertyRelative("options");
var defOptionIndexProp = property.FindPropertyRelative("defaultOptionIndex");
DrawProp(ref r, optionsProp, "Options", includeChildren: true);
DrawProp(ref r, defOptionIndexProp, "Default Index");
break;
}
DrawSectionTitle(ref r, "Apply");
DrawProp(ref r, applyProp, "Apply Target");
var apply = (ApplyTarget)applyProp.enumValueIndex;
if (apply == ApplyTarget.AudioMixerFloat01ToDb)
{
DrawProp(ref r, mixerProp, "Audio Mixer");
DrawProp(ref r, mixerParamProp, "Exposed Param");
DrawMinMaxRow(ref r, minDbProp, maxDbProp, "Min dB", "Max dB");
}
// Warning
if (string.IsNullOrWhiteSpace(keyProp.stringValue))
{
var warnH = line * 1.4f;
var warn = new Rect(r.x, r.y, r.width, warnH);
EditorGUI.HelpBox(warn, "Key is empty - setting won't work.", MessageType.Warning);
r.y += warnH + space;
}
EditorGUI.EndProperty();
// restore
EditorGUIUtility.wideMode = prevWide;
EditorGUIUtility.labelWidth = prevLabelWidth;
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
float line = EditorGUIUtility.singleLineHeight;
float space = EditorGUIUtility.standardVerticalSpacing;
float h = 0f;
// padding + foldout
h += Pad * 2;
h += line + space;
if (!property.isExpanded)
return h + 2f;
SerializedProperty keyProp = property.FindPropertyRelative("key");
SerializedProperty nameProp = property.FindPropertyRelative("displayName");
SerializedProperty groupProp = property.FindPropertyRelative("group");
SerializedProperty descProp = property.FindPropertyRelative("description");
SerializedProperty typeProp = property.FindPropertyRelative("valueType");
SerializedProperty applyProp = property.FindPropertyRelative("applyTarget");
// Meta section title
h += line + space;
h += HeightOf(nameProp) + space;
h += HeightOf(keyProp) + space;
h += HeightOf(groupProp) + space;
h += HeightOf(descProp, true) + space;
// Value section title
h += line + space;
h += HeightOf(typeProp) + space;
// Default + optional range row
SettingValueType t = (SettingValueType)typeProp.enumValueIndex;
switch (t)
{
case SettingValueType.Bool:
case SettingValueType.String:
h += line + space; // Default
break;
case SettingValueType.Int:
case SettingValueType.Float:
h += line + space; // Default
h += line + space; // range row
break;
case SettingValueType.Button:
h += line + space; // section title
h += line + space; // buttonText
h += line + space; // buttonData
h += line + space; // buttonColor
h += line + space; // buttonSprite
break;
case SettingValueType.OptionPicker:
h += line + space; // section title
var optionsProp = property.FindPropertyRelative("options");
h += HeightOf(optionsProp, true) + space; // options list
h += line + space; // defaultOptionIndex
break;
}
// Apply section title
h += line + space;
h += HeightOf(applyProp) + space;
ApplyTarget apply = (ApplyTarget)applyProp.enumValueIndex;
if (apply == ApplyTarget.AudioMixerFloat01ToDb)
{
h += line + space; // mixer
h += line + space; // param
h += line + space; // db row
}
if (string.IsNullOrWhiteSpace(keyProp.stringValue))
h += line * 1.4f + space;
return h + 6f;
}
private static float HeightOf(SerializedProperty prop, bool includeChildren = false)
=> EditorGUI.GetPropertyHeight(prop, includeChildren);
private static void DrawProp(ref Rect r, SerializedProperty prop, string label, bool includeChildren = false)
{
float space = EditorGUIUtility.standardVerticalSpacing;
GUIContent gc = new(label);
float h = EditorGUI.GetPropertyHeight(prop, gc, includeChildren);
Rect rect = new(r.x, r.y, r.width, h);
EditorGUI.PropertyField(rect, prop, gc, includeChildren);
r.y += h + space;
}
private static void DrawSectionTitle(ref Rect r, string title)
{
float line = EditorGUIUtility.singleLineHeight;
float space = EditorGUIUtility.standardVerticalSpacing;
Rect rect = new(r.x, r.y, r.width, line);
EditorGUI.LabelField(rect, title, EditorStyles.boldLabel);
r.y += line + space;
}
private static void DrawMinMaxRow(ref Rect r, SerializedProperty leftProp, SerializedProperty rightProp, string leftLabel, string rightLabel)
{
float line = EditorGUIUtility.singleLineHeight;
float space = EditorGUIUtility.standardVerticalSpacing;
float gap = 10f;
float half = (r.width - gap) * 0.5f;
Rect left = new(r.x, r.y, half, line);
Rect right = new(r.x + half + gap, r.y, half, line);
EditorGUI.PropertyField(left, leftProp, new GUIContent(leftLabel));
EditorGUI.PropertyField(right, rightProp, new GUIContent(rightLabel));
r.y += line + space;
}
private static string BuildHeader(string displayName, string key)
{
if (!string.IsNullOrWhiteSpace(displayName) && !string.IsNullOrWhiteSpace(key))
return $"{displayName} ({key})";
if (!string.IsNullOrWhiteSpace(displayName)) return displayName;
return !string.IsNullOrWhiteSpace(key) ? key : "Setting";
}
}
}
#endif

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2541f840ce6c4e0db3740977d32335d8
timeCreated: 1770121968

View File

@ -0,0 +1,45 @@
#if UNITY_EDITOR
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using RR.Common.Settings;
namespace RR.Common.InspectorOverrides
{
[CustomEditor(typeof(SettingsDatabase))]
public class SettingsDatabaseEditor : Editor
{
private ReorderableList _list;
private void OnEnable()
{
var entriesProp = serializedObject.FindProperty("entries");
_list = new ReorderableList(serializedObject, entriesProp, true, true, true, true);
_list.drawHeaderCallback = rect => EditorGUI.LabelField(rect, "Settings Entries");
_list.elementHeightCallback = index =>
{
var element = entriesProp.GetArrayElementAtIndex(index);
return EditorGUI.GetPropertyHeight(element, true) + 8f;
};
_list.drawElementCallback = (rect, index, isActive, isFocused) =>
{
var element = entriesProp.GetArrayElementAtIndex(index);
rect.y += 4f;
rect.height -= 4f;
EditorGUI.PropertyField(rect, element, GUIContent.none, true);
};
}
public override void OnInspectorGUI()
{
serializedObject.Update();
_list.DoLayoutList();
serializedObject.ApplyModifiedProperties();
}
}
}
#endif

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 473b42186f4c40d7803588b115a0d53c
timeCreated: 1770122325

View File

@ -1,4 +1,4 @@
using System.Collections;
using System.Collections;
using System.Linq;
using RR.Game2D.Core;
using UnityEngine;

View File

@ -6,6 +6,7 @@ using Random = UnityEngine.Random;
using RR.Common.Audio;
using RR.Game2D.Core.Managers;
using RR.Common.Settings;
namespace RR.Common.Managers
{
@ -45,6 +46,10 @@ namespace RR.Common.Managers
private float storedMusicVolumeBeforePause = 1f;
private bool isPausedFaded = false;
// Текущая громкость для применения к источникам
private float currentMusicVolume = 1f;
private float currentSfxVolume = 1f;
#region Unity Lifetime
public void Initialize(AudioMixer mixer = null)
@ -69,7 +74,9 @@ namespace RR.Common.Managers
EnsureMusicSources();
EnsureSfxPool();
// Загружаем громкость из настроек при инициализации
LoadVolumeFromSettings();
}
//private void Awake()
//{
@ -179,16 +186,24 @@ namespace RR.Common.Managers
public void SetMusicVolume(float newVolume)
{
float vol = Mathf.Clamp01(newVolume);
vol = DbFrom01_Log(vol);
musicMixerGroup.audioMixer.SetFloat("MusicVolume", vol);
currentMusicVolume = Mathf.Clamp01(newVolume);
float db = DbFrom01_Log(currentMusicVolume);
if (musicMixerGroup?.audioMixer != null)
{
musicMixerGroup.audioMixer.SetFloat("MusicVolume", db);
}
}
public void SetSfxVolume(float newVolume)
{
float vol = Mathf.Clamp01(newVolume);
vol = DbFrom01_Log(vol);
sfxMixerGroup.audioMixer.SetFloat("SFXVolume", vol);
currentSfxVolume = Mathf.Clamp01(newVolume);
float db = DbFrom01_Log(currentSfxVolume);
if (sfxMixerGroup?.audioMixer != null)
{
sfxMixerGroup.audioMixer.SetFloat("SFXVolume", db);
}
}
/// <summary>
@ -244,8 +259,10 @@ namespace RR.Common.Managers
if (!isPausedFaded) return;
StopCrossfadeAndFade();
musicSource.UnPause();
// Используем сохранённую громкость или текущую из AudioManager
float targetVolume = currentMusicVolume;
musicFadeCoroutine =
StartCoroutine(Fade(musicSource, from: 0f, to: Mathf.Clamp01(GameManager.Instance.Settings.GetCurrentGameSettings().musicVolume), d));
StartCoroutine(Fade(musicSource, from: 0f, to: Mathf.Clamp01(targetVolume), d));
isPausedFaded = false;
}
}
@ -414,5 +431,22 @@ namespace RR.Common.Managers
float amp = Mathf.Lerp(minAmp, maxAmp, t); // линейная интерполяция по усилению
return 20f * Mathf.Log10(Mathf.Max(1e-6f, amp));
}
/// <summary>
/// Загружает громкость из SettingsManager и применяет её
/// </summary>
private void LoadVolumeFromSettings()
{
var settings = SettingsManager.Instance;
if (settings == null) return;
// Загружаем и применяем громкость музыки
float musicVol = settings.GetFloat("volume.music");
SetMusicVolume(musicVol);
// Загружаем и применяем громкость звуков
float sfxVol = settings.GetFloat("volume.sounds");
SetSfxVolume(sfxVol);
}
}
}

View File

@ -1,12 +1,12 @@
using System;
using System.IO;
using RR.Common.Behaviour.ScriptableObjects;
using RR.Common.Controls;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.SceneManagement;
using RR.Common.Managers;
using RR.Common.Settings;
using RR.Common.Utility;
using RR.Game2D.Behaviour;
using RR.Game2D.Entities;
@ -20,7 +20,7 @@ namespace RR.Game2D.Core.Managers
public static GameManager Instance { get; private set; }
// Logger
public static CompositeLogger Logger { get; private set; }
// Game settings
// Game settings (новая система)
public SettingsManager Settings { get; private set; }
// Audio control for game
public AudioManager Audio {get; private set;}
@ -120,23 +120,31 @@ namespace RR.Game2D.Core.Managers
GameObject prefab = Resources.Load<GameObject>(globalsPrefabResourcePath);
if (prefab != null)
{
Debug.Log($"[GameManager] Loading Globals prefab from {globalsPrefabResourcePath}");
globals = Instantiate(prefab);
DontDestroyOnLoad(globals);
Debug.Log($"[GameManager] Globals instantiated. SettingsManager.Instance = {(SettingsManager.Instance != null ? "exists" : "null")}");
}
else
{
Debug.LogError($"[GameManager] Failed to load Globals prefab from {globalsPrefabResourcePath}");
}
}
// Initialize Settings Manager from Globals
// Initialize Settings Manager (новая система) from Globals
if (Settings == null) Settings = globals.GetComponent<SettingsManager>();
if (Settings == null) Settings = SettingsManager.Instance;
Settings.OnSettingsLoaded += OnSettingsChanged;
Settings.OnSettingsSaved += OnSettingsChanged;
if (Settings != null)
{
Settings.OnSettingsLoaded += OnSettingsChanged;
Settings.OnSettingsSaved += OnSettingsChanged;
}
// Initialize Payment control
if (Payment == null) Payment = globals.GetComponent<PaymentManager>();
// Apply loaded settings
Settings.LoadSettings();
// Apply loaded settings (new system applies automatically in Awake)
if (Plate == null) Plate = globals.GetComponent<ComWrapper>();
@ -207,11 +215,14 @@ namespace RR.Game2D.Core.Managers
private void OnSettingsChanged()
{
GameSettings newSettings = Settings.GetCurrentGameSettings();
StartingLives = newSettings.startLivesCount;
int currentCredits = Payment.CreditsCount;
if (Settings == null) return;
// Получаем настройки из нового SettingsManager
StartingLives = Settings.GetInt("gameplay.startLives");
LivesIncrement = Settings.GetInt("gameplay.additionalLives");
int currentCredits = Payment?.CreditsCount ?? 0;
MaxLives = currentCredits > 1 ? StartingLives + (currentCredits - 1) * LivesIncrement : StartingLives;
LivesIncrement = newSettings.livesIncreasedByCredits;
MaxLivesChanged?.Invoke(MaxLives);
}

View File

@ -1,8 +1,7 @@
using System;
using RR.Common.Controls;
using RR.Common.Settings;
using RR.Game2D.Core.Managers;
using UnityEngine;
using UnityEngine.InputSystem;
namespace RR.Common.Managers
{
@ -27,7 +26,7 @@ namespace RR.Common.Managers
_paymentManager = GetComponent<PaymentManager>();
_adapter = GetComponent<ComInputToInputSystemAdapter>();
if (_settingsManager == null) gameObject.AddComponent<SettingsManager>();
if (_settingsManager == null) _settingsManager = gameObject.AddComponent<SettingsManager>();
if (_comWrapper == null) gameObject.AddComponent<ComWrapper>();
if (_in == null) gameObject.AddComponent<In>();
if (_prizeSystem == null) gameObject.AddComponent<PrizeSystem>();

View File

@ -1,4 +1,3 @@
using RR.Common.Behaviour.ScriptableObjects;
using RR.Common.Controls;
using RR.Game2D.Core.Managers;
using UnityEngine;
@ -66,7 +65,7 @@ namespace RR.Common.Managers
addCreditAction.action.Enable();
}
SettingsManager manager = SettingsManager.Instance;
RR.Common.Settings.SettingsManager manager = RR.Common.Settings.SettingsManager.Instance;
if (manager != null)
{
manager.OnSettingsLoaded += SetFreePlay;
@ -93,7 +92,7 @@ namespace RR.Common.Managers
addCreditAction.action.performed -= AddCreditsManually;
addCreditAction.action.Disable();
SettingsManager manager = SettingsManager.Instance;
RR.Common.Settings.SettingsManager manager = RR.Common.Settings.SettingsManager.Instance;
if (manager == null) return;
manager.OnSettingsLoaded -= SetFreePlay;
manager.OnSettingsSaved -= SetFreePlay;
@ -129,9 +128,9 @@ namespace RR.Common.Managers
private void SetFreePlay()
{
if (SettingsManager.Instance == null) return;
GameSettings currentSettings = SettingsManager.Instance.GetCurrentGameSettings();
enableFreeGame = currentSettings.isFreeGame;
var settings = RR.Common.Settings.SettingsManager.Instance;
if (settings == null) return;
enableFreeGame = settings.GetBool("payment.freeGame");
Debug.Log($"Бесплатная игра установлена из настроек: {enableFreeGame}", this);
}
#endregion

View File

@ -1,11 +1,8 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using RR.Common.Controls;
using RR.Common.Managers;
using UnityEngine;
using RR.Common.Utility;
using RR.Game2D.Core.Managers;
using RR.Common.Settings;
namespace RR.Common.Managers
{
@ -44,7 +41,9 @@ namespace RR.Common.Managers
Debug.Log(enableHopper ? "Hopper is enabled for prize dispensing." : "Hopper is disabled.");
_phoneNumber = SettingsManager.Instance.GetCurrentGameSettings().phoneNumber;
// Получаем номер телефона из новой системы настроек (если он есть)
var settings = SettingsManager.Instance;
_phoneNumber = settings?.GetString("phoneNumber") ?? string.Empty;
_phoneNumber = PhoneNumberUtils.ValidatePhoneNumber(_phoneNumber);
_phoneNumber = PhoneNumberUtils.ApplyPhoneMask(_phoneNumber, _phoneNumberMask);

View File

@ -1,165 +0,0 @@
using System;
using System.IO;
using System.Text;
using UnityEngine;
using RR.Game2D.Core.Managers;
using RR.Common.Behaviour.ScriptableObjects;
namespace RR.Common.Managers
{
public class SettingsManager : MonoBehaviour
{
public static SettingsManager Instance { get; private set; }
[SerializeField] private GameSettings gameSettings;
private const string SETTINGS_FILE_NAME = "settings.json";
private static string SettingsFilePath => Path.Combine(Application.persistentDataPath, SETTINGS_FILE_NAME);
public event Action OnSettingsLoaded;
public event Action OnSettingsSaved;
public void Initialize()
{
// ---- Singleton ----
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
// -------------------
// Loading and applying game settings
if (gameSettings == null)
{
GameManager.Logger.Log($"{name}: gameSettings is null. Устанавливаю gameSettings по умолчанию.");
gameSettings = ScriptableObject.CreateInstance<GameSettings>();
}
LoadSettings();
gameSettings.ApplySettings();
}
// Если не инициализируется в GameManager, инициализировать тут
// private void Awake()
// {
// Initialize();
// }
private void OnApplicationQuit()
{
SaveSettings();
}
public void LoadSettings()
{
if (gameSettings == null)
{
Debug.LogError($"{name}: gameSettings is null. Невозможно загрузить настройки.");
}
if (File.Exists(SettingsFilePath))
{
try
{
string json = File.ReadAllText(SettingsFilePath);
Debug.Log($"{name}: Пытаюсь загрузить настройки из: {SettingsFilePath}");
Debug.Log($"{name}: Загруженный JSON: {json}");
GameSettings tempSettings = ScriptableObject.CreateInstance<GameSettings>();
JsonUtility.FromJsonOverwrite(json, tempSettings);
tempSettings.ValidateSettings();
JsonUtility.FromJsonOverwrite(json, gameSettings);
Debug.Log($"{name}: Настройки загружены и проверены успешно.");
Destroy(tempSettings);
}
catch (Exception e)
{
Debug.LogError($"{name}: Ошибка при загрузке настроек: {e.Message}. Применяю настройки по умолчанию.");
gameSettings.SetDefaultValues();
}
}
else
{
Debug.Log($"{name}: Настройки не найдены по пути: {SettingsFilePath}. Применяю настройки по умолчанию.");
gameSettings.SetDefaultValues();
}
gameSettings.ApplySettings();
OnSettingsLoaded?.Invoke();
}
public void SaveSettings()
{
if (gameSettings == null)
{
Debug.LogError($"{name}: gameSettings is null. Невозможно сохранить настройки.");
return;
}
gameSettings.ValidateSettings();
try
{
string json = JsonUtility.ToJson(gameSettings, true);
File.WriteAllText(SettingsFilePath, json, Encoding.UTF8);
Debug.Log($"{name}: Настройки сохранены по пути: {SettingsFilePath}.");
Debug.Log($"{name}: Сохраненный JSON: {json}");
OnSettingsSaved?.Invoke();
}
catch (Exception e)
{
Debug.LogError($"{name}: Ошибка при сохранении настроек: {e.Message}.");
}
}
public void SetFullscreen(bool newFullscreen)
{
gameSettings.isFullscreen = newFullscreen;
Debug.Log($"{name}: Установлен режим: {(newFullscreen ? "полноэкранный" : "оконный")}.");
}
public void SetMusicVolume(float newVolume)
{
gameSettings.musicVolume = newVolume;
Debug.Log($"{name}: Установлена громкость музыки: {newVolume}.");
}
public void SetSfxVolume(float newVolume)
{
gameSettings.sfxVolume = newVolume;
Debug.Log($"{name}: Установлена громкость звуков: {newVolume}.");
}
public void SetIsFreeGame(bool newIsFreeGame)
{
gameSettings.isFreeGame = newIsFreeGame;
Debug.Log($"{name}: Установлена флаг 'free game': {newIsFreeGame}.");
}
public void SetIsGivingPrizes(bool newIsGivingPrizes)
{
gameSettings.isGivingPrizes = newIsGivingPrizes;
Debug.Log($"{name}: Установлена флаг 'give prizes': {newIsGivingPrizes}.");
}
public void SetStartLivesCount(int newStartLivesCount)
{
gameSettings.startLivesCount = newStartLivesCount;
Debug.Log($"{name}: Установлен количество жизней: {newStartLivesCount}.");
}
public void SetLivesIncreasedByCredits(int newLivesIncreasedByCredits)
{
gameSettings.livesIncreasedByCredits = newLivesIncreasedByCredits;
Debug.Log($"{name}: Установлены жизни при пополнении баланса: {newLivesIncreasedByCredits}.");
}
public GameSettings GetCurrentGameSettings() => gameSettings;
}
}

View File

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

View File

@ -1,69 +0,0 @@
using RR.Common.UI;
using RR.Common.Utility;
using RR.Game2D.Core.Managers;
using UnityEngine;
namespace RR.Common.Behaviour.ScriptableObjects
{
[CreateAssetMenu(fileName = "GameSettings", menuName = "Game/GameSettings")]
public class GameSettings : ScriptableObject
{
// General settings
public bool isFullscreen;
// ATTENTION: Music between 0f and 1f
public float musicVolume;
public float sfxVolume;
// Payment/prizing settings
public bool isFreeGame;
public bool isGivingPrizes;
public string phoneNumber;
// Player settings
public int startLivesCount;
public int livesIncreasedByCredits;
public void SetDefaultValues()
{
isFullscreen = true;
musicVolume = 1f;
sfxVolume = 1f;
isFreeGame = false;
isGivingPrizes = true;
phoneNumber = "9123456789";
startLivesCount = 3;
livesIncreasedByCredits = 1;
}
public void ValidateSettings()
{
if (musicVolume is < 0f or > 1f)
musicVolume = Mathf.Clamp01(musicVolume);
if (sfxVolume is < 0f or > 1f)
sfxVolume = Mathf.Clamp01(sfxVolume);
if (startLivesCount < 1)
startLivesCount = 3;
if (livesIncreasedByCredits < 0)
livesIncreasedByCredits = 0;
phoneNumber = PhoneNumberUtils.ValidatePhoneNumber(phoneNumber);
}
public void ApplySettings()
{
if (isFullscreen)
FullscreenToggle.SetFullscreen(isFullscreen);
if (GameManager.Instance != null)
{
GameManager.Instance.Audio.SetMusicVolume(musicVolume);
GameManager.Instance.Audio.SetSfxVolume(sfxVolume);
}
}
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 72dfd8e4297157e468c4edf1a3b4808b

View File

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

View File

@ -0,0 +1,110 @@
using UnityEngine;
using RR.Game2D.Core.Managers;
namespace RR.Common.Settings
{
public static class SettingsApplier
{
public static void Apply(SettingEntry def, SettingValue v)
{
switch (def.applyTarget)
{
case ApplyTarget.None:
return;
case ApplyTarget.AudioMixerFloat01ToDb:
ApplyAudioMixer(def, v);
return;
case ApplyTarget.QualityLevel:
ApplyQuality(v.i);
return;
case ApplyTarget.VSync:
ApplyVSync(v.b);
return;
case ApplyTarget.TargetFps:
ApplyTargetFps(v.i);
return;
case ApplyTarget.Fullscreen:
ApplyFullscreen(v.b);
return;
case ApplyTarget.FullscreenMode:
ApplyFullscreenMode(v.i);
return;
case ApplyTarget.ResolutionIndex:
ApplyResolutionIndex(v.i);
return;
}
}
private static void ApplyAudioMixer(SettingEntry def, SettingValue v)
{
if (string.IsNullOrWhiteSpace(def.mixerParameter)) return;
float volume = Mathf.Clamp01(v.f);
// Применяем через AudioManager
if (GameManager.Instance?.Audio != null)
{
// Определяем тип звука по имени параметра
string param = def.mixerParameter.ToLower();
if (param.Contains("music"))
{
GameManager.Instance.Audio.SetMusicVolume(volume);
}
else if (param.Contains("sfx") || param.Contains("sound") || param.Contains("effect"))
{
GameManager.Instance.Audio.SetSfxVolume(volume);
}
}
}
private static void ApplyQuality(int level)
{
var names = QualitySettings.names;
if (names == null || names.Length == 0) return;
level = Mathf.Clamp(level, 0, names.Length - 1);
QualitySettings.SetQualityLevel(level, true);
}
private static void ApplyVSync(bool enabled)
{
QualitySettings.vSyncCount = enabled ? 1 : 0;
}
private static void ApplyTargetFps(int fps)
{
Application.targetFrameRate = fps > 0 ? fps : -1;
}
private static void ApplyFullscreen(bool fullscreen)
{
Screen.fullScreen = fullscreen;
}
private static void ApplyFullscreenMode(int idx)
{
// FullScreenMode: 0..3 (ExclusiveFullScreen, FullScreenWindow, MaximizedWindow, Windowed)
idx = Mathf.Clamp(idx, 0, 3);
Screen.fullScreenMode = (FullScreenMode)idx;
}
private static void ApplyResolutionIndex(int index)
{
var rs = Screen.resolutions;
if (rs == null || rs.Length == 0) return;
index = Mathf.Clamp(index, 0, rs.Length - 1);
var r = rs[index];
// без герцовки — самый совместимый вариант
Screen.SetResolution(r.width, r.height, Screen.fullScreenMode);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9eccd642fdc549442b779fe9d2987650
timeCreated: 1769693984

View File

@ -0,0 +1,116 @@
using UnityEngine;
using UnityEngine.SceneManagement;
namespace RR.Common.Settings
{
/// <summary>
/// Готовые методы для кнопок настроек.
/// Эти методы можно вызывать из UnityEvent в SettingsDatabase через Inspector.
/// </summary>
public class SettingsButtonActions : MonoBehaviour
{
public static SettingsButtonActions Instance { get; private set; }
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
/// <summary>
/// Сбросить все настройки к значениям по умолчанию
/// </summary>
public void ResetAllSettings()
{
if (SettingsManager.Instance)
{
SettingsManager.Instance.ResetAllToDefaults();
Debug.Log("[SettingsButtonActions] Настройки сброшены");
}
}
/// <summary>
/// Выход из игры
/// </summary>
public void QuitGame()
{
Debug.Log("[SettingsButtonActions] Выход из игры");
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
/// <summary>
/// Загрузить главное меню
/// </summary>
public void LoadMainMenu()
{
LoadScene("MainMenu");
}
/// <summary>
/// Загрузить сцену по имени
/// </summary>
public void LoadScene(string sceneName)
{
if (!string.IsNullOrEmpty(sceneName))
{
Debug.Log($"[SettingsButtonActions] Загрузка сцены: {sceneName}");
SceneManager.LoadScene(sceneName);
}
}
/// <summary>
/// Открыть URL в браузере
/// </summary>
public void OpenURL(string url)
{
if (!string.IsNullOrEmpty(url))
{
Debug.Log($"[SettingsButtonActions] Открытие URL: {url}");
Application.OpenURL(url);
}
}
/// <summary>
/// Открыть папку с сохранениями
/// </summary>
public void OpenSavesFolder()
{
string path = Application.persistentDataPath;
Debug.Log($"[SettingsButtonActions] Открытие папки: {path}");
Application.OpenURL($"file://{path}");
}
/// <summary>
/// Перезагрузить текущую сцену
/// </summary>
public void ReloadCurrentScene()
{
Scene currentScene = SceneManager.GetActiveScene();
Debug.Log($"[SettingsButtonActions] Перезагрузка сцены: {currentScene.name}");
SceneManager.LoadScene(currentScene.name);
}
/// <summary>
/// Применить все настройки заново
/// </summary>
public void ApplyAllSettings()
{
if (SettingsManager.Instance)
{
SettingsManager.Instance.ApplyAll();
Debug.Log("[SettingsButtonActions] Настройки применены");
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3e5a0ffd9d083d949b68f8fabc7c319a
timeCreated: 1770037455

View File

@ -0,0 +1,123 @@
using System.Collections.Generic;
using RR.Common.UI;
using UnityEngine;
namespace RR.Common.Settings
{
/// <summary>
/// Диспетчер для связи кнопок настроек с объектами на сцене.
/// Позволяет объектам сцены подписываться на нажатия кнопок по ключу.
/// </summary>
public static class SettingsButtonDispatcher
{
private static readonly Dictionary<string, List<SettingsButtonBinder>> bindings = new();
/// <summary>
/// Регистрирует биндер для указанного ключа кнопки
/// </summary>
public static void Register(string buttonKey, SettingsButtonBinder binder)
{
if (string.IsNullOrWhiteSpace(buttonKey) || binder == null) return;
if (!bindings.TryGetValue(buttonKey, out var list))
{
list = new List<SettingsButtonBinder>();
bindings[buttonKey] = list;
}
if (!list.Contains(binder))
{
list.Add(binder);
Debug.Log($"[SettingsButtonDispatcher] Registered binder for key: {buttonKey} on {binder.gameObject.name}");
}
}
/// <summary>
/// Удаляет биндер для указанного ключа кнопки
/// </summary>
public static void Unregister(string buttonKey, SettingsButtonBinder binder)
{
if (string.IsNullOrWhiteSpace(buttonKey) || binder == null) return;
if (bindings.TryGetValue(buttonKey, out var list))
{
list.Remove(binder);
if (list.Count == 0)
{
bindings.Remove(buttonKey);
}
}
}
/// <summary>
/// Вызывает все зарегистрированные биндеры для указанного ключа кнопки
/// </summary>
/// <returns>True если хотя бы один биндер был вызван</returns>
public static bool Dispatch(string buttonKey)
{
if (string.IsNullOrWhiteSpace(buttonKey))
{
Debug.LogWarning("[SettingsButtonDispatcher] Dispatch called with empty key");
return false;
}
// Пробуем найти в зарегистрированных биндерах
if (bindings.TryGetValue(buttonKey, out var list) && list.Count > 0)
{
Debug.Log($"[SettingsButtonDispatcher] Dispatching key: {buttonKey}, registered binders: {list.Count}");
return InvokeBinders(list);
}
// Fallback: ищем все биндеры в сцене (включая неактивные)
var allBinders = Object.FindObjectsByType<SettingsButtonBinder>(FindObjectsInactive.Include, FindObjectsSortMode.None);
var matchingBinders = new List<SettingsButtonBinder>();
foreach (var binder in allBinders)
{
if (binder.Key == buttonKey)
{
matchingBinders.Add(binder);
// Регистрируем для будущих вызовов
Register(buttonKey, binder);
}
}
if (matchingBinders.Count > 0)
{
Debug.Log($"[SettingsButtonDispatcher] Found {matchingBinders.Count} binders in scene for key: {buttonKey}");
return InvokeBinders(matchingBinders);
}
Debug.Log($"[SettingsButtonDispatcher] No binders found for key: {buttonKey}");
return false;
}
private static bool InvokeBinders(List<SettingsButtonBinder> binders)
{
bool anyInvoked = false;
// Копируем список чтобы избежать проблем при модификации во время итерации
var copy = new List<SettingsButtonBinder>(binders);
foreach (var binder in copy)
{
if (binder != null)
{
Debug.Log($"[SettingsButtonDispatcher] Invoking binder on: {binder.gameObject.name}");
binder.Invoke();
anyInvoked = true;
}
}
return anyInvoked;
}
/// <summary>
/// Очищает все регистрации (вызывать при смене сцены если нужно)
/// </summary>
public static void Clear()
{
bindings.Clear();
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fe5a488118484bd5a41972f36ec0cbcc
timeCreated: 1770184610

View File

@ -0,0 +1,162 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
namespace RR.Common.Settings
{
public enum SettingValueType
{
Bool,
Int,
Float,
String,
Button, // Кнопка - не хранит значение, только вызывает действие
OptionPicker // Выбор из списка опций (enum-like)
}
// "Куда применять" — расширяется редко (не под каждую настройку)
public enum ApplyTarget
{
None,
// Audio
AudioMixerFloat01ToDb, // float 0..1 -> dB и в AudioMixer parameter
// Graphics / Performance
QualityLevel, // int -> QualitySettings.SetQualityLevel
VSync, // bool -> QualitySettings.vSyncCount
TargetFps, // int -> Application.targetFrameRate
Fullscreen, // bool -> Screen.fullScreen
FullscreenMode, // int 0..3 -> Screen.fullScreenMode
ResolutionIndex // int -> индекс в Screen.resolutions
}
[Serializable]
public struct SettingValue
{
public SettingValueType type;
public bool b;
public int i;
public float f;
public string s;
public static SettingValue Bool(bool v) => new() { type = SettingValueType.Bool, b = v };
public static SettingValue Int(int v) => new() { type = SettingValueType.Int, i = v };
public static SettingValue Float(float v) => new() { type = SettingValueType.Float, f = v };
public static SettingValue String(string v) => new() { type = SettingValueType.String, s = v };
}
[Serializable]
public class SettingEntry
{
public string key;
public string displayName;
[TextArea] public string description;
public string group = "General";
public SettingValueType valueType;
// Defaults
public bool defaultBool = true;
public int defaultInt = 0;
public float defaultFloat = 1f;
public string defaultString = "";
// Ranges (used for Int/Float)
public int minInt = 0;
public int maxInt = 10;
public float minFloat = 0f;
public float maxFloat = 1f;
public ApplyTarget applyTarget = ApplyTarget.None;
// AudioMixer params (used only for AudioMixerFloat01ToDb)
public AudioMixer mixer;
public string mixerParameter = "MasterVolumeDb";
public float minDb = -80f;
public float maxDb = 0f;
// Button params (для типа Button)
[Header("Button Settings")]
[Tooltip("Текст на кнопке (если не задан displayName)")]
public string buttonText;
[Tooltip("Дополнительные данные для кнопки (URL, имя сцены и т.д.)")]
public string buttonData;
[Tooltip("Цвет кнопки")]
public Color buttonColor = Color.white;
[Tooltip("Текстура/спрайт кнопки")]
public Sprite buttonSprite;
// OptionPicker params (для типа OptionPicker)
[Header("Option Picker Settings")]
[Tooltip("Список вариантов выбора")]
public List<string> options;
[Tooltip("Индекс варианта по умолчанию")]
public int defaultOptionIndex;
public SettingValue DefaultValue => valueType switch
{
SettingValueType.Bool => SettingValue.Bool(defaultBool),
SettingValueType.Int => SettingValue.Int(defaultInt),
SettingValueType.Float => SettingValue.Float(defaultFloat),
SettingValueType.String => SettingValue.String(defaultString ?? ""),
SettingValueType.Button => default, // Кнопки не хранят значение
SettingValueType.OptionPicker => SettingValue.Int(options != null && options.Count > 0
? Mathf.Clamp(defaultOptionIndex, 0, options.Count - 1)
: 0),
_ => default
};
public SettingValue Sanitize(SettingValue v)
{
if (v.type != valueType) return DefaultValue;
// защита от кривых min/max
int iMin = Mathf.Min(minInt, maxInt);
int iMax = Mathf.Max(minInt, maxInt);
float fMin = Mathf.Min(minFloat, maxFloat);
float fMax = Mathf.Max(minFloat, maxFloat);
return valueType switch
{
SettingValueType.Bool => SettingValue.Bool(v.b),
SettingValueType.Int => SettingValue.Int(Mathf.Clamp(v.i, iMin, iMax)),
SettingValueType.Float => SettingValue.Float(Mathf.Clamp(v.f, fMin, fMax)),
SettingValueType.String => SettingValue.String(v.s ?? ""),
SettingValueType.Button => default,
SettingValueType.OptionPicker => SettingValue.Int(options != null && options.Count > 0
? Mathf.Clamp(v.i, 0, options.Count - 1)
: 0),
_ => DefaultValue
};
}
}
[CreateAssetMenu(menuName = "Settings/Database")]
public class SettingsDatabase : ScriptableObject
{
public List<SettingEntry> entries = new();
public SettingEntry Find(string key)
=> entries.Find(e => string.Equals(e.key, key, StringComparison.Ordinal));
private void OnValidate()
{
var set = new HashSet<string>();
foreach (var e in entries)
{
if (e == null) continue;
if (string.IsNullOrWhiteSpace(e.key))
Debug.LogWarning($"[SettingsDatabase] Empty key in {name}", this);
else if (!set.Add(e.key))
Debug.LogWarning($"[SettingsDatabase] Duplicate key '{e.key}' in {name}", this);
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e990a23dd7f692842827a7b9adce645c
timeCreated: 1769693917

View File

@ -0,0 +1,295 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace RR.Common.Settings
{
[Serializable]
public class SettingsSaveData
{
public int version = 1;
public List<Entry> entries = new();
[Serializable]
public class Entry
{
public string key;
public SettingValue value;
}
}
[DefaultExecutionOrder(-900)]
public class SettingsManager : MonoBehaviour
{
[SerializeField] private SettingsDatabase database;
public static SettingsManager Instance { get; private set; }
private readonly Dictionary<string, SettingValue> map = new();
private string path;
private Coroutine saveRoutine;
// События для совместимости со старым кодом
public event Action OnSettingsLoaded;
public event Action OnSettingsSaved;
public event Action<string, SettingValue> OnSettingChanged;
private void Awake()
{
Debug.Log($"[SettingsManager] Awake called. Instance = {(Instance != null ? Instance.name : "null")}");
if (Instance)
{
Debug.Log("[SettingsManager] Instance already exists, destroying this one.");
Destroy(gameObject);
return;
}
Instance = this;
Debug.Log($"[SettingsManager] Instance set to {name}");
DontDestroyOnLoad(gameObject);
path = Path.Combine(Application.persistentDataPath, "settings.json");
if (!database)
{
Debug.LogError("[SettingsManager] Database is not assigned! Settings will not work.");
}
else
{
Debug.Log($"[SettingsManager] Initialized with database containing {database.entries.Count} entries.");
}
LoadOrDefaults();
ApplyAll();
}
/// <summary>
/// Инициализация из GameManager (альтернатива Awake)
/// </summary>
public void Initialize()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
// Если database не назначена - пытаемся загрузить из Resources
if (!database)
{
database = Resources.Load<SettingsDatabase>("SettingsDatabase");
if (!database)
{
// Пытаемся найти л<><D0BB>бую SettingsDatabase в проекте
var databases = Resources.FindObjectsOfTypeAll<SettingsDatabase>();
if (databases.Length > 0)
{
database = databases[0];
}
}
}
if (!database)
{
Debug.LogError("[SettingsManager] Database is not assigned and not found in Resources! Settings will not work.");
}
else
{
Debug.Log($"[SettingsManager] Initialized with database containing {database.entries.Count} entries.");
}
path = Path.Combine(Application.persistentDataPath, "settings.json");
LoadOrDefaults();
ApplyAll();
}
public SettingEntry Define(string key)
{
if (!database)
{
Debug.LogWarning($"[SettingsManager] Database is null, cannot define key '{key}'");
return null;
}
return database.Find(key);
}
public SettingValue Get(string key)
{
if (map.TryGetValue(key, out SettingValue v)) return v;
SettingEntry def = Define(key);
return def?.DefaultValue ?? default;
}
// Удобные типизированные геттеры
public bool GetBool(string key) => Get(key).b;
public int GetInt(string key) => Get(key).i;
public float GetFloat(string key) => Get(key).f;
public string GetString(string key) => Get(key).s;
public void Set(string key, SettingValue value)
{
// Проверяем, что объект не уничтожен
if (this == null) return;
SettingEntry def = Define(key);
if (def == null)
{
Debug.LogWarning($"[SettingsManager] No definition found for key '{key}'. Check that SettingsDatabase has this entry.");
return;
}
SettingValue clean = def.Sanitize(value);
map[key] = clean;
Debug.Log($"[SettingsManager] Set '{key}' = {value.type}: b={value.b}, i={value.i}, f={value.f}, s={value.s}");
// применяем СРАЗУ
SettingsApplier.Apply(def, clean);
// оповещаем подписчиков
OnSettingChanged?.Invoke(key, clean);
// сохраняем с небольшой задержкой (удобно для слайдеров)
ScheduleSave(0.25f);
}
// Удобные типизированные сеттеры
public void SetBool(string key, bool value) => Set(key, SettingValue.Bool(value));
public void SetInt(string key, int value) => Set(key, SettingValue.Int(value));
public void SetFloat(string key, float value) => Set(key, SettingValue.Float(value));
public void SetString(string key, string value) => Set(key, SettingValue.String(value));
/// <summary>
/// Немедленное сохранение настроек
/// </summary>
public void SaveSettings()
{
SaveNow();
}
public void ApplyAll()
{
if (!database) return;
foreach (SettingEntry def in database.entries)
{
if (def == null || string.IsNullOrWhiteSpace(def.key)) continue;
SettingsApplier.Apply(def, Get(def.key));
}
}
public void ResetAllToDefaults()
{
if (!database) return;
foreach (SettingEntry def in database.entries)
{
if (def == null || string.IsNullOrWhiteSpace(def.key)) continue;
map[def.key] = def.DefaultValue;
SettingsApplier.Apply(def, def.DefaultValue);
}
ScheduleSave(0.05f);
}
/// <summary>
/// Сбрасывает настройки указанной группы к значениям по умолчанию
/// </summary>
/// <param name="groupName">Имя группы настроек</param>
public void ResetGroupToDefaults(string groupName)
{
if (!database || string.IsNullOrWhiteSpace(groupName)) return;
foreach (SettingEntry def in database.entries)
{
if (def == null || string.IsNullOrWhiteSpace(def.key)) continue;
if (!string.Equals(def.group, groupName, System.StringComparison.OrdinalIgnoreCase)) continue;
map[def.key] = def.DefaultValue;
SettingsApplier.Apply(def, def.DefaultValue);
}
ScheduleSave(0.05f);
}
private void LoadOrDefaults()
{
map.Clear();
if (File.Exists(path))
{
try
{
string json = File.ReadAllText(path);
SettingsSaveData data = JsonUtility.FromJson<SettingsSaveData>(json);
if (data != null)
{
foreach (SettingsSaveData.Entry e in data.entries)
if (!string.IsNullOrWhiteSpace(e.key))
map[e.key] = e.value;
}
}
catch
{
// если файл битый — просто упадём на дефолты ниже
}
}
if (!database) return;
foreach (SettingEntry def in database.entries)
{
if (def == null || string.IsNullOrWhiteSpace(def.key)) continue;
if (!map.ContainsKey(def.key))
map[def.key] = def.DefaultValue;
else
map[def.key] = def.Sanitize(map[def.key]);
}
OnSettingsLoaded?.Invoke();
}
private void ScheduleSave(float delay)
{
// Проверяем, что объект не уничтожен
if (this == null || !gameObject) return;
if (saveRoutine != null) StopCoroutine(saveRoutine);
saveRoutine = StartCoroutine(SaveDelayed(delay));
}
private IEnumerator SaveDelayed(float delay)
{
yield return new WaitForSecondsRealtime(delay);
SaveNow();
saveRoutine = null;
}
private void SaveNow()
{
SettingsSaveData data = new();
foreach (var kv in map)
data.entries.Add(new SettingsSaveData.Entry { key = kv.Key, value = kv.Value });
try
{
File.WriteAllText(path, JsonUtility.ToJson(data, true));
OnSettingsSaved?.Invoke();
}
catch (Exception e)
{
Debug.LogWarning($"[SettingsManager] Save failed: {e.Message}");
}
}
private void OnApplicationQuit() => SaveNow();
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2c4a3f878fc0c59429e24e6f7f80ed2a
timeCreated: 1769694036

View File

@ -0,0 +1,185 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e990a23dd7f692842827a7b9adce645c, type: 3}
m_Name: MainSettingsDatabase
m_EditorClassIdentifier: Assembly-CSharp::RR.Common.Settings.SettingsDatabase
entries:
- key: volume.music
displayName: "\u0413\u0440\u043E\u043C\u043A\u043E\u0441\u0442\u044C \u043C\u0443\u0437\u044B\u043A\u0438"
description:
group: "\u041C\u0443\u0437\u044B\u043A\u0430 \u0438 \u0437\u0432\u0443\u043A\u0438"
valueType: 2
defaultBool: 0
defaultInt: 0
defaultFloat: 0
defaultString:
minInt: 0
maxInt: 0
minFloat: 0
maxFloat: 1
applyTarget: 1
mixer: {fileID: 24100000, guid: 4f44de6a220ee7d4b8179285074ead2d, type: 2}
mixerParameter: MusicVolume
minDb: -80
maxDb: 0
buttonText:
buttonData:
buttonColor: {r: 0, g: 0, b: 0, a: 0}
buttonSprite: {fileID: 0}
options: []
defaultOptionIndex: 0
- key: volume.sounds
displayName: "\u0413\u0440\u043E\u043C\u043A\u043E\u0441\u0442\u044C \u0437\u0432\u0443\u043A\u043E\u0432"
description:
group: "\u041C\u0443\u0437\u044B\u043A\u0430 \u0438 \u0437\u0432\u0443\u043A\u0438"
valueType: 2
defaultBool: 0
defaultInt: 0
defaultFloat: 0
defaultString:
minInt: 0
maxInt: 0
minFloat: 0
maxFloat: 1
applyTarget: 1
mixer: {fileID: 24100000, guid: 4f44de6a220ee7d4b8179285074ead2d, type: 2}
mixerParameter: SFXVolume
minDb: -80
maxDb: 0
buttonText:
buttonData:
buttonColor: {r: 0, g: 0, b: 0, a: 0}
buttonSprite: {fileID: 0}
options: []
defaultOptionIndex: 0
- key: payment.freeGame
displayName: "\u0411\u0435\u0441\u043F\u043B\u0430\u0442\u043D\u0430\u044F \u0438\u0433\u0440\u0430"
description:
group: "\u041E\u043F\u043B\u0430\u0442\u0430 \u0438 \u0441\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C"
valueType: 0
defaultBool: 0
defaultInt: 0
defaultFloat: 0
defaultString:
minInt: 0
maxInt: 0
minFloat: 0
maxFloat: 1
applyTarget: 0
mixer: {fileID: 24100000, guid: 4f44de6a220ee7d4b8179285074ead2d, type: 2}
mixerParameter: SFXVolume
minDb: -80
maxDb: 0
buttonText:
buttonData:
buttonColor: {r: 0, g: 0, b: 0, a: 0}
buttonSprite: {fileID: 0}
options: []
defaultOptionIndex: 0
- key: payment.smallPrize
displayName: "\u0412\u044B\u0434\u0430\u0432\u0430\u0442\u044C \u043C\u0430\u043B\u0435\u043D\u044C\u043A\u0438\u0439
\u043F\u0440\u0438\u0437"
description:
group: "\u041F\u0440\u0438\u0437\u044B \u0438 \u0432\u044B\u0434\u0430\u0447\u0430"
valueType: 0
defaultBool: 0
defaultInt: 0
defaultFloat: 0
defaultString:
minInt: 0
maxInt: 0
minFloat: 0
maxFloat: 1
applyTarget: 0
mixer: {fileID: 24100000, guid: 4f44de6a220ee7d4b8179285074ead2d, type: 2}
mixerParameter: SFXVolume
minDb: -80
maxDb: 0
buttonText:
buttonData:
buttonColor: {r: 0, g: 0, b: 0, a: 0}
buttonSprite: {fileID: 0}
options: []
defaultOptionIndex: 0
- key: gameplay.startLives
displayName: "\u041D\u0430\u0447\u0430\u043B\u044C\u043D\u044B\u0435 \u0436\u0438\u0437\u043D\u0438"
description:
group: "\u0418\u0433\u0440\u043E\u0432\u043E\u0439 \u043F\u0440\u043E\u0446\u0435\u0441\u0441"
valueType: 1
defaultBool: 0
defaultInt: 3
defaultFloat: 0
defaultString:
minInt: 1
maxInt: 20
minFloat: 0
maxFloat: 1
applyTarget: 0
mixer: {fileID: 24100000, guid: 4f44de6a220ee7d4b8179285074ead2d, type: 2}
mixerParameter: SFXVolume
minDb: -80
maxDb: 0
buttonText:
buttonData:
buttonColor: {r: 0, g: 0, b: 0, a: 0}
buttonSprite: {fileID: 0}
options: []
defaultOptionIndex: 0
- key: gameplay.additionalLives
displayName: "\u0416\u0438\u0437\u043D\u0438 \u0437\u0430 \u0434\u043E\u043F.
\u043C\u043E\u043D\u0435\u0442\u044B"
description:
group: "\u0418\u0433\u0440\u043E\u0432\u043E\u0439 \u043F\u0440\u043E\u0446\u0435\u0441\u0441"
valueType: 1
defaultBool: 0
defaultInt: 1
defaultFloat: 0
defaultString:
minInt: 0
maxInt: 20
minFloat: 0
maxFloat: 1
applyTarget: 0
mixer: {fileID: 24100000, guid: 4f44de6a220ee7d4b8179285074ead2d, type: 2}
mixerParameter: SFXVolume
minDb: -80
maxDb: 0
buttonText:
buttonData:
buttonColor: {r: 0, g: 0, b: 0, a: 0}
buttonSprite: {fileID: 0}
options: []
defaultOptionIndex: 0
- key: btn.statistics
displayName: "\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0430"
description:
group: "\u041E\u043F\u043B\u0430\u0442\u0430 \u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0430"
valueType: 4
defaultBool: 0
defaultInt: 1
defaultFloat: 0
defaultString:
minInt: 0
maxInt: 20
minFloat: 0
maxFloat: 1
applyTarget: 0
mixer: {fileID: 24100000, guid: 4f44de6a220ee7d4b8179285074ead2d, type: 2}
mixerParameter: SFXVolume
minDb: -80
maxDb: 0
buttonText: "\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0430"
buttonData:
buttonColor: {r: 0.8490566, g: 0.40749258, b: 0.13216448, a: 1}
buttonSprite: {fileID: 0}
options: []
defaultOptionIndex: 0

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 29cc91230b52fab4494eb90856f51c2c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1,45 @@
using System.Collections.Generic;
using RR.Common.Settings;
using TMPro;
using UnityEngine;
namespace RR.Common.UI
{
public class SettingDropdownResolutionBinder : MonoBehaviour
{
[SerializeField] private string key;
[SerializeField] private TMP_Dropdown dropdown;
[SerializeField] private TMP_Text label;
private SettingEntry def;
private void Start()
{
def = SettingsManager.Instance.Define(key);
if (def == null)
{
gameObject.SetActive(false);
return;
}
if (label) label.text = def.displayName;
var rs = Screen.resolutions;
var options = new List<string>();
for (int i = 0; i < rs.Length; i++)
options.Add($"{rs[i].width} x {rs[i].height}");
dropdown.ClearOptions();
dropdown.AddOptions(options);
int current = SettingsManager.Instance.Get(key).i;
current = Mathf.Clamp(current, 0, dropdown.options.Count - 1);
dropdown.SetValueWithoutNotify(current);
dropdown.onValueChanged.AddListener(idx =>
SettingsManager.Instance.Set(key, SettingValue.Int(idx))
);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f55d4221dcc965f46969c63faf9038b6
timeCreated: 1769694125

View File

@ -0,0 +1,351 @@
using System;
using System.Collections.Generic;
using System.Linq;
using RR.Common.Settings;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace RR.Common.UI
{
public class SettingUIItem : MonoBehaviour
{
[Header("Common")] public TMP_Text titleText;
public TMP_Text descriptionText;
[Header("Controls")] public Toggle toggle;
public Slider slider;
public TMP_Dropdown dropdown;
public TMP_InputField input;
public Button button;
[Header("Option Picker")]
public Button prevButton;
public Button nextButton;
public TMP_Text optionValueText;
[Header("Optional")] public TMP_Text sliderValueText; // например справа от слайдера
private SettingEntry entry;
private bool showDescription;
/// <summary>
/// Безопасно устанавливает значение настройки с проверкой на уничтоженный SettingsManager
/// </summary>
private void SetSafe(string key, SettingValue value)
{
var manager = SettingsManager.Instance;
if (!manager)
{
Debug.LogWarning($"[SettingUIItem] SettingsManager.Instance is null, cannot set {key}");
return;
}
manager.Set(key, value);
}
public void Bind(SettingEntry entryToBind, bool showDescriptionOption)
{
this.entry = entryToBind;
this.showDescription = showDescriptionOption;
if (titleText)
titleText.text = string.IsNullOrWhiteSpace(entryToBind.displayName)
? entryToBind.key
: entryToBind.displayName;
if (descriptionText)
{
bool hasDesc = showDescriptionOption && !string.IsNullOrWhiteSpace(entryToBind.description);
descriptionText.gameObject.SetActive(hasDesc);
if (hasDesc) descriptionText.text = entryToBind.description;
}
// Отключаем все контролы, включим нужный
if (toggle) toggle.gameObject.SetActive(false);
if (slider) slider.gameObject.SetActive(false);
if (dropdown) dropdown.gameObject.SetActive(false);
if (input) input.gameObject.SetActive(false);
if (button) button.gameObject.SetActive(false);
if (prevButton) prevButton.gameObject.SetActive(false);
if (nextButton) nextButton.gameObject.SetActive(false);
if (optionValueText) optionValueText.gameObject.SetActive(false);
// Биндим по applyTarget/valueType
SetupControl();
RefreshFromSettings();
}
public void RefreshFromSettings()
{
if (entry == null) return;
SettingsManager manager = SettingsManager.Instance;
if (!manager) return;
var v = manager.Get(entry.key);
if (toggle && toggle.gameObject.activeSelf)
toggle.SetIsOnWithoutNotify(v.b);
if (slider && slider.gameObject.activeSelf)
slider.SetValueWithoutNotify(slider.wholeNumbers ? v.i : v.f);
if (dropdown && dropdown.gameObject.activeSelf)
dropdown.SetValueWithoutNotify(Mathf.Clamp(v.i, 0, dropdown.options.Count - 1));
if (input && input.gameObject.activeSelf)
input.SetTextWithoutNotify(v.s ?? "");
if (optionValueText && optionValueText.gameObject.activeSelf && entry.valueType == SettingValueType.OptionPicker)
UpdateOptionPickerDisplay(entry.options);
UpdateSliderValueText();
}
private void SetupControl()
{
if (entry == null) return;
// Спец-случаи с Dropdown
if (entry.applyTarget == ApplyTarget.QualityLevel)
{
UseDropdown(QualitySettings.names.ToList(), onChanged: idx =>
SetSafe(entry.key, SettingValue.Int(idx)));
return;
}
if (entry.applyTarget == ApplyTarget.ResolutionIndex)
{
Resolution[] rs = Screen.resolutions;
List<string> options = rs.Select(t => $"{t.width} x {t.height}").ToList();
UseDropdown(options, onChanged: idx =>
SetSafe(entry.key, SettingValue.Int(idx)));
return;
}
if (entry.applyTarget == ApplyTarget.FullscreenMode)
{
// индексы 0..3 как в твоём SettingsApplier
List<string> options = new()
{
"Exclusive Fullscreen",
"Fullscreen Window",
"Maximized Window",
"Windowed"
};
UseDropdown(options, onChanged: idx =>
SetSafe(entry.key, SettingValue.Int(idx)));
return;
}
// Обычные по типу
switch (entry.valueType)
{
case SettingValueType.Bool:
UseToggle(v => SetSafe(entry.key, SettingValue.Bool(v)));
break;
case SettingValueType.Float:
UseSliderFloat(entry.minFloat, entry.maxFloat, v =>
SetSafe(entry.key, SettingValue.Float(v)));
break;
case SettingValueType.Int:
// Int — делаем слайдер целочисленным (лучше чем инпут)
UseSliderInt(entry.minInt, entry.maxInt, v =>
SetSafe(entry.key, SettingValue.Int(v)));
break;
case SettingValueType.String:
UseInput(s => SetSafe(entry.key, SettingValue.String(s)));
break;
case SettingValueType.Button:
UseButton(() =>
{
// Вызываем биндеры на сцене (SettingsButtonBinder)
SettingsButtonDispatcher.Dispatch(entry.key);
});
break;
case SettingValueType.OptionPicker:
UseOptionPicker(entry.options, idx =>
SetSafe(entry.key, SettingValue.Int(idx)));
break;
default:
throw new ArgumentOutOfRangeException();
}
}
private void UseToggle(UnityEngine.Events.UnityAction<bool> onChanged)
{
if (!toggle) return;
toggle.gameObject.SetActive(true);
toggle.onValueChanged.RemoveAllListeners();
toggle.onValueChanged.AddListener(onChanged);
}
private void UseSliderFloat(float min, float max, UnityEngine.Events.UnityAction<float> onChanged)
{
if (!slider) return;
slider.gameObject.SetActive(true);
slider.wholeNumbers = false;
slider.minValue = Mathf.Min(min, max);
slider.maxValue = Mathf.Max(min, max);
slider.onValueChanged.RemoveAllListeners();
slider.onValueChanged.AddListener(v =>
{
onChanged(v);
UpdateSliderValueText();
});
}
private void UseSliderInt(int min, int max, System.Action<int> onChanged)
{
if (!slider) return;
slider.gameObject.SetActive(true);
slider.wholeNumbers = true;
slider.minValue = Mathf.Min(min, max);
slider.maxValue = Mathf.Max(min, max);
slider.onValueChanged.RemoveAllListeners();
slider.onValueChanged.AddListener(v =>
{
onChanged(Mathf.RoundToInt(v));
UpdateSliderValueText();
});
}
private void UseDropdown(List<string> options, System.Action<int> onChanged)
{
if (!dropdown) return;
dropdown.gameObject.SetActive(true);
dropdown.ClearOptions();
dropdown.AddOptions(options ?? new List<string>());
dropdown.onValueChanged.RemoveAllListeners();
dropdown.onValueChanged.AddListener(idx => onChanged(idx));
}
private void UseInput(System.Action<string> onEndEdit)
{
if (!input) return;
input.gameObject.SetActive(true);
input.onEndEdit.RemoveAllListeners();
input.onEndEdit.AddListener(text => onEndEdit(text));
}
private void UseButton(System.Action onClick)
{
if (!button) return;
button.gameObject.SetActive(true);
// Убеждаемся что кнопка интерактивна
button.interactable = true;
// Навигация настраивается централизованно в SettingsUI.SetupExplicitNavigation()
// Устанавливаем текст кнопки
var buttonText = button.GetComponentInChildren<TMP_Text>();
if (buttonText && entry != null)
{
string text = !string.IsNullOrEmpty(entry.buttonText) ? entry.buttonText : entry.displayName;
if (string.IsNullOrEmpty(text)) text = entry.key;
buttonText.text = text;
}
// Устанавливаем цвет и спрайт кнопки
if (entry != null)
{
var image = button.GetComponent<UnityEngine.UI.Image>();
if (image)
{
// Устанавливаем цвет напрямую на Image
image.color = entry.buttonColor;
// Устанавливаем спрайт
if (entry.buttonSprite != null)
{
image.sprite = entry.buttonSprite;
}
}
}
button.onClick.RemoveAllListeners();
button.onClick.AddListener(() => onClick());
}
private void UseOptionPicker(List<string> options, System.Action<int> onChanged)
{
if (options == null || options.Count == 0) return;
// Если есть dropdown - используем его
if (dropdown)
{
UseDropdown(options, onChanged);
return;
}
// Иначе используем кнопки prev/next
if (!prevButton || !nextButton || !optionValueText) return;
prevButton.gameObject.SetActive(true);
nextButton.gameObject.SetActive(true);
optionValueText.gameObject.SetActive(true);
prevButton.onClick.RemoveAllListeners();
nextButton.onClick.RemoveAllListeners();
prevButton.onClick.AddListener(() =>
{
if (entry == null) return;
int current = SettingsManager.Instance.Get(entry.key).i;
int newIndex = current - 1;
if (newIndex < 0) newIndex = options.Count - 1; // Wrap around
onChanged(newIndex);
UpdateOptionPickerDisplay(options);
});
nextButton.onClick.AddListener(() =>
{
if (entry == null) return;
int current = SettingsManager.Instance.Get(entry.key).i;
int newIndex = (current + 1) % options.Count; // Wrap around
onChanged(newIndex);
UpdateOptionPickerDisplay(options);
});
UpdateOptionPickerDisplay(options);
}
private void UpdateOptionPickerDisplay(List<string> options)
{
if (!optionValueText || entry == null) return;
int currentIndex = SettingsManager.Instance.Get(entry.key).i;
if (currentIndex >= 0 && currentIndex < options.Count)
optionValueText.text = options[currentIndex];
}
private void UpdateSliderValueText()
{
if (!sliderValueText || !slider || !slider.gameObject.activeSelf) return;
sliderValueText.text = slider.wholeNumbers
? Mathf.RoundToInt(slider.value).ToString()
: slider.value.ToString("0.##");
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4c856f3cf51e81642a471d0300e1cdea
timeCreated: 1769757759

View File

@ -0,0 +1,103 @@
using RR.Common.Settings;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace RR.Common.UI
{
/// <summary>
/// Биндер для кнопок в настройках.
/// Позволяет назначать действия кнопки настроек прямо на объекты сцены.
/// </summary>
public class SettingsButtonBinder : MonoBehaviour
{
[Header("Binding")]
[Tooltip("Ключ кнопки из SettingsDatabase")]
[SerializeField] private string key;
/// <summary>
/// Ключ кнопки для диспетчера
/// </summary>
public string Key => key;
[Header("UI Elements (опционально)")]
[SerializeField] private Button button;
[SerializeField] private TMP_Text label;
[Header("Action")]
[Tooltip("Действие, выполняемое при нажатии кнопки")]
[SerializeField] private UnityEvent onButtonClick;
private SettingEntry def;
private bool isRegistered;
private void Awake()
{
// Регистрируемся сразу при создании (даже если объект неактивен)
RegisterIfNeeded();
}
private void Start()
{
if (string.IsNullOrWhiteSpace(key)) return;
if (SettingsManager.Instance)
{
def = SettingsManager.Instance.Define(key);
}
// Установка текста кнопки если есть
if (label && def != null)
{
string text = !string.IsNullOrEmpty(def.buttonText) ? def.buttonText : def.displayName;
if (string.IsNullOrEmpty(text)) text = key;
label.text = text;
}
// Привязка действия к локальной кнопке если есть
if (button)
{
button.onClick.RemoveAllListeners();
button.onClick.AddListener(OnButtonClick);
}
}
private void OnEnable()
{
// На случай если Awake не был вызван (объект был неактивен при загрузке сцены)
RegisterIfNeeded();
}
private void OnDestroy()
{
// Отписываемся только при уничтожении
if (isRegistered)
{
SettingsButtonDispatcher.Unregister(key, this);
isRegistered = false;
}
}
private void RegisterIfNeeded()
{
if (isRegistered || string.IsNullOrWhiteSpace(key)) return;
SettingsButtonDispatcher.Register(key, this);
isRegistered = true;
}
private void OnButtonClick()
{
Invoke();
}
/// <summary>
/// Вызывается при нажатии кнопки (из диспетчера или напрямую)
/// </summary>
public void Invoke()
{
onButtonClick?.Invoke();
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 48cc9934c948ec44eacf006814bf813e
timeCreated: 1770036630

View File

@ -0,0 +1,39 @@
using System.Collections.Generic;
using RR.Common.Settings;
using TMPro;
using UnityEngine;
namespace RR.Common.UI
{
public class SettingDropdownQualityBinder : MonoBehaviour
{
[SerializeField] private string key;
[SerializeField] private TMP_Dropdown dropdown;
[SerializeField] private TMP_Text label;
private SettingEntry def;
private void Start()
{
def = SettingsManager.Instance.Define(key);
if (def == null)
{
gameObject.SetActive(false);
return;
}
if (label) label.text = def.displayName;
dropdown.ClearOptions();
dropdown.AddOptions(new List<string>(QualitySettings.names));
int current = SettingsManager.Instance.Get(key).i;
current = Mathf.Clamp(current, 0, dropdown.options.Count - 1);
dropdown.SetValueWithoutNotify(current);
dropdown.onValueChanged.AddListener(idx =>
SettingsManager.Instance.Set(key, SettingValue.Int(idx))
);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0b61d7bb12f0da04aa0994f125de5137
timeCreated: 1769694114

View File

@ -0,0 +1,74 @@
using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace RR.Common.UI
{
public class SettingsGroupPanel : MonoBehaviour
{
[Header("Wiring")]
[SerializeField] private TMP_Text titleText;
[SerializeField] private Button headerButton;
[SerializeField] private GameObject contentRoot; // сюда будут инстанситься строки настроек
[Header("Optional icons")]
[SerializeField] private GameObject iconExpanded;
[SerializeField] private GameObject iconCollapsed;
public Transform ContentRoot => contentRoot ? contentRoot.transform : transform;
/// <summary>
/// Событие вызывается при сворачивании/разворачивании группы
/// </summary>
public event Action<SettingsGroupPanel, bool> OnExpandedChanged;
private bool expanded = true;
private string prefsKey;
private bool rememberState;
public void Init(string title, string prefsKey, bool defaultExpanded, bool rememberState)
{
this.prefsKey = prefsKey;
this.rememberState = rememberState;
if (titleText) titleText.text = title;
bool startExpanded = defaultExpanded;
if (this.rememberState && !string.IsNullOrEmpty(this.prefsKey))
startExpanded = PlayerPrefs.GetInt(this.prefsKey, defaultExpanded ? 1 : 0) == 1;
SetExpanded(startExpanded, save: false);
if (headerButton)
{
headerButton.onClick.RemoveAllListeners();
headerButton.onClick.AddListener(Toggle);
}
}
public void Toggle() => SetExpanded(!expanded, save: true);
public void SetExpanded(bool value, bool save)
{
expanded = value;
if (contentRoot) contentRoot.SetActive(expanded);
if (iconExpanded) iconExpanded.SetActive(expanded);
if (iconCollapsed) iconCollapsed.SetActive(!expanded);
if (save && rememberState && !string.IsNullOrEmpty(prefsKey))
{
PlayerPrefs.SetInt(prefsKey, expanded ? 1 : 0);
PlayerPrefs.Save();
}
// Чтобы лэйаут сразу пересчитался
var rt = transform as RectTransform;
if (rt) LayoutRebuilder.ForceRebuildLayoutImmediate(rt);
// Уведомляем подписчиков об изменении состояния
OnExpandedChanged?.Invoke(this, expanded);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 128f5ee47aca9f446aa436d617fa5dcf
timeCreated: 1769758290

View File

@ -0,0 +1,130 @@
using System.Collections.Generic;
using RR.Common.Settings;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace RR.Common.UI
{
/// <summary>
/// Биндер для выбора из списка опций (как enum или список строк).
/// Использует Dropdown или кнопки влево/вправо для переключения.
/// </summary>
public class SettingsOptionPickerBinder : MonoBehaviour
{
[SerializeField] private string key;
[SerializeField] private TMP_Dropdown dropdown;
[SerializeField] private TMP_Text label;
// Альтернативный вариант: кнопки влево/вправо + текст текущего значения
[Header("Alternative: Buttons")]
[SerializeField] private Button prevButton;
[SerializeField] private Button nextButton;
[SerializeField] private TMP_Text valueText;
private SettingEntry def;
private bool useDropdown = true;
private void Start()
{
if (!SettingsManager.Instance)
{
Debug.LogError("[SettingsOptionPickerBinder] SettingsManager.Instance not found!");
gameObject.SetActive(false);
return;
}
def = SettingsManager.Instance.Define(key);
if (def == null)
{
Debug.LogWarning($"[SettingsOptionPickerBinder] Setting '{key}' not found in database.");
gameObject.SetActive(false);
return;
}
if (def.valueType != SettingValueType.OptionPicker)
{
Debug.LogWarning($"[SettingsOptionPickerBinder] Setting '{key}' is not an OptionPicker type!");
gameObject.SetActive(false);
return;
}
if (def.options == null || def.options.Count == 0)
{
Debug.LogWarning($"[SettingsOptionPickerBinder] Setting '{key}' has no options!");
gameObject.SetActive(false);
return;
}
// Определяем режим работы
useDropdown = dropdown != null;
if (label)
label.text = def.displayName ?? key;
if (useDropdown)
InitDropdown();
else
InitButtons();
}
private void InitDropdown()
{
if (!dropdown) return;
// Заполняем dropdown опциями
dropdown.ClearOptions();
dropdown.AddOptions(def.options);
// Устанавливаем текущее значение
int currentIndex = SettingsManager.Instance.Get(key).i;
dropdown.SetValueWithoutNotify(currentIndex);
// Подписываемся на изменения
dropdown.onValueChanged.AddListener(OnDropdownChanged);
}
private void InitButtons()
{
if (!prevButton || !nextButton) return;
prevButton.onClick.AddListener(OnPrevClicked);
nextButton.onClick.AddListener(OnNextClicked);
UpdateButtonsDisplay();
}
private void OnDropdownChanged(int newIndex)
{
SettingsManager.Instance.Set(key, SettingValue.Int(newIndex));
}
private void OnPrevClicked()
{
int current = SettingsManager.Instance.Get(key).i;
int newIndex = current - 1;
if (newIndex < 0) newIndex = def.options.Count - 1; // Wrap around
SettingsManager.Instance.Set(key, SettingValue.Int(newIndex));
UpdateButtonsDisplay();
}
private void OnNextClicked()
{
int current = SettingsManager.Instance.Get(key).i;
int newIndex = (current + 1) % def.options.Count; // Wrap around
SettingsManager.Instance.Set(key, SettingValue.Int(newIndex));
UpdateButtonsDisplay();
}
private void UpdateButtonsDisplay()
{
if (!valueText) return;
int currentIndex = SettingsManager.Instance.Get(key).i;
if (currentIndex >= 0 && currentIndex < def.options.Count)
valueText.text = def.options[currentIndex];
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 394f6cfda759af84b91230395cf850d8
timeCreated: 1770036652

View File

@ -0,0 +1,47 @@
using RR.Common.Settings;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace RR.Common.UI
{
public class SettingSliderBinder : MonoBehaviour
{
[SerializeField] private string key;
[SerializeField] private Slider slider;
[SerializeField] private TMP_Text label;
[SerializeField] private TMP_Text valueText; // optional
private SettingEntry def;
private void Start()
{
def = SettingsManager.Instance.Define(key);
if (def == null)
{
gameObject.SetActive(false);
return;
}
if (label) label.text = def.displayName;
slider.minValue = def.minFloat;
slider.maxValue = def.maxFloat;
float v = SettingsManager.Instance.Get(key).f;
slider.SetValueWithoutNotify(v);
UpdateValueText(v);
slider.onValueChanged.AddListener(val =>
{
SettingsManager.Instance.Set(key, SettingValue.Float(val));
UpdateValueText(val);
});
}
private void UpdateValueText(float v)
{
if (valueText) valueText.text = v.ToString("0.##");
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 67b64895a4e8922498cb58af503307eb
timeCreated: 1769694096

View File

@ -0,0 +1,33 @@
using RR.Common.Settings;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace RR.Common.UI
{
public class SettingToggleBinder : MonoBehaviour
{
[SerializeField] private string key;
[SerializeField] private Toggle toggle;
[SerializeField] private TMP_Text label;
private SettingEntry def;
private void Start()
{
def = SettingsManager.Instance.Define(key);
if (def == null)
{
gameObject.SetActive(false);
return;
}
if (label) label.text = def.displayName;
toggle.SetIsOnWithoutNotify(SettingsManager.Instance.Get(key).b);
toggle.onValueChanged.AddListener(v =>
SettingsManager.Instance.Set(key, SettingValue.Bool(v))
);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: edf37612015ad7a4c8684ddee29e3c10
timeCreated: 1769694073

View File

@ -0,0 +1,294 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using RR.Common.Settings;
using TMPro;
using UnityEngine;
namespace RR.Common.UI
{
public class SettingsUIGenerator : MonoBehaviour
{
[Header("Source")] [SerializeField] private SettingsDatabase database;
[Header("Layout")] [SerializeField] private Transform contentRoot;
/// <summary>
/// Корневой Transform для контента настроек
/// </summary>
public Transform ContentRoot => contentRoot;
[Header("Grouping")] [SerializeField] private bool groupByGroup = true;
[SerializeField] private bool collapsibleGroups = true;
[SerializeField] private SettingsGroupPanel groupPanelPrefab; // префаб группы (foldout)
[SerializeField] private bool defaultGroupsExpanded = true;
[SerializeField] private bool rememberGroupFoldout = true;
[Tooltip("Если заполнить — группы будут идти в этом порядке, остальные добавятся в конец по алфавиту.")]
[SerializeField]
private List<string> groupOrder = new();
[Header("Sorting")] [SerializeField] private bool sortByNameInsideGroup = true;
[Header("Prefabs (rows)")] [SerializeField]
private SettingUIItem toggleRowPrefab;
[SerializeField] private SettingUIItem sliderRowPrefab;
[SerializeField] private SettingUIItem dropdownRowPrefab;
[SerializeField] private SettingUIItem inputRowPrefab;
[SerializeField] private SettingUIItem buttonRowPrefab;
[SerializeField] private SettingUIItem optionPickerRowPrefab;
[Header("Behaviour")] [SerializeField] private bool buildOnEnable = true;
[SerializeField] private bool clearBeforeBuild = true;
[SerializeField] private bool showDescription = true;
private readonly List<SettingUIItem> spawnedItems = new();
private readonly List<SettingsGroupPanel> spawnedGroups = new();
private Coroutine _buildCoroutine;
/// <summary>
/// Событие вызывается когда построение UI завершено
/// </summary>
public event Action OnBuildComplete;
/// <summary>
/// Событие вызывается при сворачивании/разворачивании любой группы настроек
/// </summary>
public event Action OnGroupExpandedChanged;
/// <summary>
/// Первый созданный Selectable элемент
/// </summary>
public UnityEngine.UI.Selectable FirstSelectable { get; private set; }
private void OnEnable()
{
if (buildOnEnable)
{
// Запускаем корутину, которая ждёт SettingsManager
if (_buildCoroutine != null) StopCoroutine(_buildCoroutine);
_buildCoroutine = StartCoroutine(BuildWhenReady());
}
else
{
RefreshValues();
}
}
private void OnDisable()
{
if (_buildCoroutine != null)
{
StopCoroutine(_buildCoroutine);
_buildCoroutine = null;
}
}
private IEnumerator BuildWhenReady()
{
// Ждём пока SettingsManager инициализируется (максимум 2 секунды)
float timeout = 2f;
float elapsed = 0f;
while (!SettingsManager.Instance && elapsed < timeout)
{
elapsed += Time.unscaledDeltaTime;
yield return null;
}
if (!SettingsManager.Instance)
{
Debug.LogError("[SettingsUIGenerator] SettingsManager.Instance not found after waiting. Make sure SettingsManager is in scene.");
yield break;
}
Build();
// Ждём кадр чтобы layout обновился
yield return null;
// Принудительно обновляем layout для корректной навигации
UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(contentRoot as RectTransform);
// Ещё кадр для применения layout
yield return null;
// Находим первый Selectable элемент
FirstSelectable = contentRoot.GetComponentInChildren<UnityEngine.UI.Selectable>();
// Оповещаем о завершении
OnBuildComplete?.Invoke();
_buildCoroutine = null;
}
public void Build()
{
if (!database || !contentRoot)
{
Debug.LogWarning("[SettingsUIGenerator] database/contentRoot not set.");
return;
}
if (!SettingsManager.Instance)
{
Debug.LogWarning("[SettingsUIGenerator] SettingsManager.Instance not found in scene.");
return;
}
if (clearBeforeBuild) Clear();
spawnedItems.Clear();
List<SettingEntry> entries = database.entries
.Where(e => e != null && !string.IsNullOrWhiteSpace(e.key))
.ToList();
if (!groupByGroup)
{
// Без групп — просто одним списком
if (sortByNameInsideGroup)
entries = entries.OrderBy(e => e.displayName ?? e.key).ToList();
foreach (SettingEntry entry in entries)
SpawnSettingRow(entry, contentRoot);
return;
}
// Группировка по e.group
Dictionary<string, List<SettingEntry>> groups = entries
.GroupBy(e => string.IsNullOrWhiteSpace(e.group) ? "General" : e.group)
.ToDictionary(g => g.Key, g => g.ToList());
// Порядок групп: сначала заданные, потом остальные по алфавиту
List<string> orderedGroupNames = new();
if (groupOrder != null && groupOrder.Count > 0)
{
orderedGroupNames.AddRange(
groupOrder.Where(g => !string.IsNullOrWhiteSpace(g) && groups.ContainsKey(g)));
}
List<string> rest = groups.Keys
.Except(orderedGroupNames)
.OrderBy(x => x)
.ToList();
orderedGroupNames.AddRange(rest);
foreach (string groupName in orderedGroupNames)
{
List<SettingEntry> list = groups[groupName];
if (sortByNameInsideGroup)
list = list.OrderBy(e => e.displayName ?? e.key).ToList();
Transform parentForRows = contentRoot;
// Создаём UI группы (foldout) если включено
if (collapsibleGroups && groupPanelPrefab)
{
SettingsGroupPanel panel = Instantiate(groupPanelPrefab, contentRoot);
panel.name = $"Group_{groupName}";
string prefsKey = $"settings.ui.group.{groupName}";
panel.Init(groupName, prefsKey, defaultGroupsExpanded, rememberGroupFoldout);
// Подписываемся на изменение состояния группы
panel.OnExpandedChanged += OnGroupPanelExpandedChanged;
spawnedGroups.Add(panel);
parentForRows = panel.ContentRoot;
}
else
{
// Если не используем foldout — можно хотя бы заголовок простым текстом
// (не обязательно; если не надо — удали блок)
GameObject headerGO = new GameObject($"Header_{groupName}", typeof(RectTransform),
typeof(TextMeshProUGUI));
headerGO.transform.SetParent(contentRoot, false);
TextMeshProUGUI text = headerGO.GetComponent<TextMeshProUGUI>();
text.text = groupName;
text.fontSize = 28;
text.fontStyle = FontStyles.Bold;
}
foreach (var entry in list)
SpawnSettingRow(entry, parentForRows);
}
}
private void SpawnSettingRow(SettingEntry entry, Transform parent)
{
SettingUIItem prefab = PickPrefab(entry);
if (!prefab)
{
Debug.LogWarning(
$"[SettingsUIGenerator] No prefab for '{entry.key}' ({entry.valueType}/{entry.applyTarget})");
return;
}
SettingUIItem item = Instantiate(prefab, parent);
item.name = $"Setting_{entry.key}";
item.Bind(entry, showDescription);
spawnedItems.Add(item);
}
private SettingUIItem PickPrefab(SettingEntry e)
{
return e.applyTarget switch
{
// Спец-UI по ApplyTarget
ApplyTarget.QualityLevel => dropdownRowPrefab,
ApplyTarget.ResolutionIndex => dropdownRowPrefab,
ApplyTarget.FullscreenMode => dropdownRowPrefab,
_ => e.valueType switch
{
// По типу
SettingValueType.Bool => toggleRowPrefab,
SettingValueType.Float => sliderRowPrefab,
SettingValueType.Int => sliderRowPrefab ? sliderRowPrefab : dropdownRowPrefab,
SettingValueType.String => inputRowPrefab,
SettingValueType.Button => buttonRowPrefab,
SettingValueType.OptionPicker => optionPickerRowPrefab ? optionPickerRowPrefab : dropdownRowPrefab,
_ => null
}
};
}
public void RefreshValues()
{
for (int i = 0; i < spawnedItems.Count; i++)
if (spawnedItems[i])
spawnedItems[i].RefreshFromSettings();
}
private void OnGroupPanelExpandedChanged(SettingsGroupPanel panel, bool expanded)
{
Debug.Log($"[SettingsUIGenerator] Group '{panel.name}' expanded: {expanded}");
// Уведомляем подписчиков (например SettingsUI) об изменении состояния группы
OnGroupExpandedChanged?.Invoke();
}
public void Clear()
{
// Отписываемся от событий групп
foreach (var group in spawnedGroups)
{
if (group != null)
group.OnExpandedChanged -= OnGroupPanelExpandedChanged;
}
spawnedGroups.Clear();
for (int i = contentRoot.childCount - 1; i >= 0; i--)
Destroy(contentRoot.GetChild(i).gameObject);
spawnedItems.Clear();
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2bec3b41f31ece6499468cf44ed8ed4e
timeCreated: 1769756230

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 8822d9ad6616481f9c86e4c709221bd4
timeCreated: 1762348485

View File

@ -1,12 +0,0 @@
using System.Collections.Generic;
// [System.Serializable]
// public class GameSettings
// {
// public List<SettingOption> settings;
// public int hash;
// public SettingOption GetSetting(string settingName)
// {
// return settings.Find(s => s.settingName == settingName);
// }
// }

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: de80d69f0b559a94c8ec18aeba347d12
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,20 +0,0 @@
using System.Collections.Generic;
[System.Serializable]
public class SettingOption
{
public string settingName;
public List<string> options;
public int chosenIndex;
public int defaultIndex;
public SettingOption(string settingName, List<string> options, int defaultIndex)
{
this.settingName = settingName;
this.options = options;
this.defaultIndex = defaultIndex;
this.chosenIndex = defaultIndex;
}
public string ChosenOption => options[chosenIndex];
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 07644b6c546b12047a530b34680101a8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,159 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using RR.Common.Controls;
using RR.Game2D.Core.Managers;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class SettingsCombination : MonoBehaviour
{
GameManager gm;
float resetStartsTimer = 0;
float resetGivenPrizesTimer = 0;
float setNumber = 0;
float telegram = 0;
float timeToReset = 5;
string PRIZE_BASE = "Счетчик призов ";
string STARTS_BASE = "Внесено монет ";
string NULLABLE = "(обнуляемый)";
string UNNULLABLE = "(глобальный)";
public TextMeshProUGUI starts, startsNul, prize, prizeNul;
public Image startsTimerImage, prizeTimerImage, numberImage, telegramImage;
private void OnEnable()
{
gm = GameManager.Instance;
RefreshUI();
}
void Update()
{
//сброс монет
bool condition = In.GetButton(ButtonPinMapping.left1) &&
In.GetButton(ButtonPinMapping.right1) &&
In.GetButton(ButtonPinMapping.left2) &&
In.GetButton(ButtonPinMapping.right2);
if (condition)
{
resetStartsTimer += Time.deltaTime;
startsTimerImage.fillAmount = resetStartsTimer / timeToReset;
if (resetStartsTimer >= timeToReset)
{
ResetStarts();
resetStartsTimer = 0;
}
return;
}
else
{
resetStartsTimer -= Time.deltaTime;
resetStartsTimer = Mathf.Clamp(resetStartsTimer, 0, 5);
startsTimerImage.fillAmount = 0;
}
//телега
condition = In.GetButton(ButtonPinMapping.left1) &&
In.GetButton(ButtonPinMapping.right1) &&
/*In.GetButton(ButtonPinMapping.left2) &&*/
In.GetButton(ButtonPinMapping.right2);
if (condition)
{
telegram += Time.deltaTime;
telegramImage.fillAmount = telegram / timeToReset;
if (telegram >= timeToReset)
{
//Тут надо зайти в ввод номера
telegram = 0;
// gm.stateMachine.ChangeState(new EnterTelegramState());
//GetNumber();
}
return;
}
else
{
telegram -= Time.deltaTime;
telegram = Mathf.Clamp(setNumber, 0, 5);
telegramImage.fillAmount = 0;
}
//выданные призы
condition = In.GetButton(ButtonPinMapping.left1) &&
In.GetButton(ButtonPinMapping.left2);
if (condition)
{
resetGivenPrizesTimer += Time.deltaTime;
prizeTimerImage.fillAmount = resetGivenPrizesTimer / timeToReset;
if (resetGivenPrizesTimer >= timeToReset)
{
ResetPrizes();
resetGivenPrizesTimer = 0;
}
return;
}
else
{
resetGivenPrizesTimer -= Time.deltaTime;
resetGivenPrizesTimer = Mathf.Clamp(resetGivenPrizesTimer, 0, 5);
prizeTimerImage.fillAmount = 0;
}
//условие захода в ввод номера
condition = In.GetButton(ButtonPinMapping.right1) &&
In.GetButton(ButtonPinMapping.right2);
if (condition)
{
setNumber += Time.deltaTime;
numberImage.fillAmount = setNumber / timeToReset;
if (setNumber >= timeToReset)
{
//Тут надо зайти в ввод номера
setNumber = 0;
GetNumber();
}
return;
}
else
{
setNumber -= Time.deltaTime;
setNumber = Mathf.Clamp(setNumber, 0, 5);
numberImage.fillAmount = 0;
}
}
void ResetStarts()
{
PlayerPrefs.SetInt(PrizeSystem.key_startsNul, 0);
RefreshUI();
}
void ResetPrizes()
{
PlayerPrefs.SetInt(PrizeSystem.key_prizesgivenNul, 0);
RefreshUI();
}
void GetNumber()
{
// GameManager.instance.stateMachine.ChangeState(new GetNumberState());
}
void RefreshUI()
{
starts.text = STARTS_BASE + UNNULLABLE + ": " + PlayerPrefs.GetInt(PrizeSystem.key_starts);
startsNul.text = STARTS_BASE + NULLABLE + ": " + PlayerPrefs.GetInt(PrizeSystem.key_startsNul);
prize.text = PRIZE_BASE + UNNULLABLE + ": " + PlayerPrefs.GetInt(PrizeSystem.key_prizesgiven);
prizeNul.text = PRIZE_BASE + NULLABLE + ": " + PlayerPrefs.GetInt(PrizeSystem.key_prizesgivenNul);
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 61414424e8ee73b4cbc8b75b1c0216d9

View File

@ -1,137 +0,0 @@
// using System.Text;
// using System.Collections.Generic;
// using UnityEngine;
// using UnityEngine.Events;
//
// using RR.Common.Behaviour.ScriptableObjects;
//
// public class SettingsManager : MonoBehaviour
// {
// public static SettingsManager instance;
// public GameSettings gameSettings;
// const string SETTINGS_PREFS_KEY = "SETTINGS";
// int ActualHash => settingsHash(getDefaultSettings());
//
// public UnityEvent OnSettingsChanged;
//
// private void Awake()
// {
// instance ??= this;
// OnSettingsChanged = new UnityEvent();
//
// LoadOrCreateSettings();
// }
// private void LoadOrCreateSettings()
// {
// bool shouldLoadDefault = !PlayerPrefs.HasKey(SETTINGS_PREFS_KEY) || !IsSavedSettingsValid();
//
// if (shouldLoadDefault)
// {
// LoadDefaultSettings();
// }
// else
// {
// LoadSettings();
// }
//
// bool IsSavedSettingsValid()
// {
// LoadSettings();
// return gameSettings.hash == ActualHash;
// }
// }
//
// public void ChangeSetting(string settingName, int newIndex)
// {
// var setting = gameSettings.GetSetting(settingName);
// if (setting != null && newIndex >= 0 && newIndex < setting.options.Count)
// {
// setting.chosenIndex = newIndex;
// SaveSettings();
// }
// }
// public void SaveSettings()
// {
// string json = JsonUtility.ToJson(gameSettings);
//
// PlayerPrefs.SetString(SETTINGS_PREFS_KEY, json);
// PlayerPrefs.Save();
// OnSettingsChanged?.Invoke();
// }
//
// public string GetSettingValue(string settingName)
// => gameSettings.GetSetting(settingName).ChosenOption;
//
//
// int settingsHash(List<SettingOption> settings)
// {
// StringBuilder sb = new StringBuilder();
// foreach (SettingOption settingOption in settings)
// {
// sb.Append(settingOption.settingName);
// foreach (string option in settingOption.options)
// {
// sb.Append(option);
// }
// }
//
// int hash = sb.ToString().GetHashCode();
// return hash;
// }
//
// void LoadDefaultSettings()
// {
// //print("Загрузка стандартных настроек");
//
// gameSettings.settings = getDefaultSettings();
// gameSettings.hash = settingsHash(gameSettings.settings);
//
// SaveSettings();
// }
//
// List<SettingOption> getDefaultSettings()
// {
// List<SettingOption> settings = new List<SettingOption>();
//
// settings.Add(new SettingOption(settingName: "Громкость музыки",
// options: new List<string>() { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" },
// defaultIndex: 1));
//
// settings.Add(new SettingOption(settingName: "Громкость эффектов",
// options: new List<string>() { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" },
// defaultIndex: 8));
//
// settings.Add(new SettingOption(settingName: "Выдача призов при игре с ботом",
// options: new List<string>() { "Выдавать", "Не выдавать" },
// defaultIndex: 0));
//
// settings.Add(new SettingOption(settingName: "Озвучка персонажей",
// options: new List<string>() { "Вкл", "Выкл" },
// defaultIndex: 0));
//
// settings.Add(new SettingOption(settingName: "Сложность ботов",
// options: new List<string>() { "Легкая", "Средняя", "Сложная" },
// defaultIndex: 1));
//
// settings.Add(new SettingOption(settingName: "Бесплатная игра",
// options: new List<string>() { "Вкл", "Выкл" },
// defaultIndex: 1));
//
// settings.Add(new SettingOption(settingName: "Показывать контакты администрации",
// options: new List<string>() { "Вкл", "Выкл" },
// defaultIndex: 0));
// return settings;
// }
//
//
// void LoadSettings()
// {
// string json = PlayerPrefs.GetString(SETTINGS_PREFS_KEY);
// gameSettings = JsonUtility.FromJson<GameSettings>(json);
//
// SaveSettings();
// }
//
//
//
// }

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 896b3b244e3f8db4c8a6f4591ca9c68f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: -60
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,241 +0,0 @@
// using System.Collections;
// using System.Collections.Generic;
// using System.Reflection;
// using TMPro;
// using UnityEngine;
//
// public class SettingsScreen : MonoBehaviour
// {
// [Header("Панель с опциями")]
// [SerializeField] RectTransform OptionsRect;
//
// [Header("Панель с вариантами опций")]
// [SerializeField] RectTransform ValuesRect;
//
// [Header("Указатель опций")]
// [SerializeField] RectTransform PointerRect;
//
// [Header("Префаб текста настройки")]
// [SerializeField] GameObject SettingPrefab;
//
// [Header("Префаб текста опции")]
// [SerializeField] GameObject OptionPrefab;
//
//
// List<GameObject> settingsLabels;
// List<GameObject> optionsLabels;
//
// substate currentState;
//
// List<SettingOption> gameSettings => SettingsManager.instance.gameSettings.settings;
// int settingsAmount => SettingsManager.instance.gameSettings.settings.Count;
// List<string> chosenSettingOptions => SettingsManager.instance.gameSettings.settings[currentSettingIndex].options;
// int chosenSettingOptionsAmount => chosenSettingOptions.Count;
//
//
// public int currentSettingIndex = 0;
// int currentOptionIndex = 0;
//
//
// float startx = 50;
// float starty = -50;
//
// //float offsetx = 100;
// float offsetx = 0;
// float offsety = 70;
//
// Coroutine chooseOption;
//
// [SerializeField] float optionsPadding = 20;
//
// public void Open()
// {
// optionsLabels = new();
// settingsLabels = new();
// PointerRect.gameObject.SetActive(true);
// currentState = substate.SettingChoosing;
// currentSettingIndex = 0;
// CreateSettingsLabels();
// }
//
// public void Close()
// {
// ClearOptionsPanel();
// ClearSettingsPanel();
// if (chooseOption != null) StopCoroutine(chooseOption);
// }
//
// public void Switch(int direction)
// {
// switch (currentState)
// {
// case substate.SettingChoosing:
// currentSettingIndex = (currentSettingIndex + settingsAmount + direction) % settingsAmount;
// PointerRect.anchoredPosition = new Vector2(startx + currentSettingIndex * offsetx, starty - currentSettingIndex * offsety);
// break;
// case substate.OptionChoosing:
// currentOptionIndex = (currentOptionIndex + chosenSettingOptionsAmount + direction) % chosenSettingOptionsAmount;//ТУТ НАДО КОЛИЧЕСТВО ОПЦИЙ НАСТРОЙКИ ПОЛУЧИТЬ
// break;
// }
// //SoundManager.instance.playSwitch();
// }
//
// //менять состояние, сохранять данные
// public void Accept()
// {
// if (currentState == substate.SettingChoosing)
// {
// createOptionsLabels(gameSettings[currentSettingIndex]);
// currentState = substate.OptionChoosing;
// PointerRect.gameObject.SetActive(false);
//
// StartCoroutine(DisplayChosenOption());
// }
//
// else if (currentState == substate.OptionChoosing)
// {
// SettingsManager.instance.ChangeSetting(settingName: gameSettings[currentSettingIndex].settingName,
// newIndex: currentOptionIndex);
//
// PointerRect.gameObject.SetActive(true);
// ClearOptionsPanel();
// //Обновляем для учета изменений
// ClearSettingsPanel();
// CreateSettingsLabels();
//
// if (chooseOption != null) StopCoroutine(chooseOption);
//
// currentState = substate.SettingChoosing;
// }
//
// //SoundManager.instance.playChoose();
//
// }
//
//
//
// //Шерстим все существующие настройки
// //Создаем для каждой настройки текстовое поле
// private void CreateSettingsLabels()
// {
// settingsLabels = new List<GameObject>();
// //currentSettingIndex = 0;
// for (int i = 0; i < SettingsManager.instance.gameSettings.settings.Count; i++)
// {
// createLabelFromSettingOption(SettingsManager.instance.gameSettings.settings[i], i);
// //currentSettingIndex++;
// }
// //currentSettingIndex = 0;
// PointerRect.anchoredPosition = new Vector2(startx + currentSettingIndex * offsetx, starty - currentSettingIndex * offsety);
//
// //Процедура которая собственно создает лейблы
// void createLabelFromSettingOption(SettingOption option, int index)
// {
// GameObject label = Instantiate(SettingPrefab, OptionsRect);
// label.name = option.settingName + " Setting";
// settingsLabels.Add(label);
// RectTransform rt = label.GetComponent<RectTransform>();
// rt.anchoredPosition = new Vector2(startx + offsetx * index, starty - offsety * index);
//
// //Звгоняем название настройки
// TextMeshProUGUI text = rt.gameObject.GetComponent<TextMeshProUGUI>();
// text.text = option.settingName;
//
// //Текущая включенная опция
// GameObject label2 = Instantiate(OptionPrefab, rt);
// label2.name = option.settingName + " Value";
// RectTransform option_rt = label2.GetComponent<RectTransform>();
//
// option_rt.anchoredPosition = new Vector2(rt.sizeDelta.x, 0);
//
// text = option_rt.gameObject.GetComponent<TextMeshProUGUI>();
// text.text = option.ChosenOption;
// }
//
//
// }
//
// // Опции настроек
// void createOptionsLabels(SettingOption option)
// {
//
// currentOptionIndex = 0;
//
// float labelWidth = (ValuesRect.sizeDelta.x - optionsPadding * 2) / option.options.Count;
// float labelHeight = ValuesRect.sizeDelta.y - optionsPadding * 2;
// print(ValuesRect.sizeDelta);
//
// foreach (string optionName in option.options)
// {
// GameObject label = Instantiate(OptionPrefab, ValuesRect);
// optionsLabels.Add(label);
//
// RectTransform rt = label.GetComponent<RectTransform>();
// rt.pivot = new Vector2(0, 1f);
// rt.sizeDelta = new Vector2(labelWidth, labelHeight);
// rt.anchoredPosition = new Vector2(optionsPadding + labelWidth * currentOptionIndex, optionsPadding);
//
//
// TextMeshProUGUI text = label.GetComponent<TextMeshProUGUI>();
// text.text = optionName;
// text.alignment = TextAlignmentOptions.Center;
// text.color = Color.gray;
// currentOptionIndex++;
// }
// currentOptionIndex = option.chosenIndex;
// }
// void ClearSettingsPanel()
// {
// foreach (GameObject label in settingsLabels)
// {
// Object.Destroy(label);
// }
// settingsLabels.Clear();
// }
// void ClearOptionsPanel()
// {
// foreach (GameObject label in optionsLabels)
// {
// Object.Destroy(label);
// }
// optionsLabels?.Clear();
// }
//
// IEnumerator DisplayChosenOption()
// {
// Color normalColor = Color.gray;
// Color highlightedColor = Color.white;
//
// int normalSize = 26;
// int chosenSize = 40;
//
// List<TextMeshProUGUI> options = new List<TextMeshProUGUI>();
// foreach (GameObject label in optionsLabels)
// {
// options.Add(label.GetComponent<TextMeshProUGUI>());
// }
//
// while (true)
// {
// for (int i = 0; i < options.Count; i++)
// {
// if (i == currentOptionIndex)
// {
// options[i].color = Vector4.MoveTowards(options[i].color, highlightedColor, Time.deltaTime * 5);
// options[i].fontSize = Mathf.MoveTowards(options[i].fontSize, chosenSize, Time.deltaTime * 140);
// }
// else
// {
// options[i].color = Vector4.MoveTowards(options[i].color, normalColor, Time.deltaTime * 5);
// options[i].fontSize = Mathf.MoveTowards(options[i].fontSize, normalSize, Time.deltaTime * 140);
// }
// }
// yield return null;
// }
//
//
//
// }
//
// enum substate { SettingChoosing, OptionChoosing }
// }

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: c0343bffc1f51dc4ea7c7d3dc9fc25bf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,6 +1,5 @@
using System;
using System;
using System.Collections;
using RR.Common.Managers;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
@ -25,7 +24,7 @@ namespace RR.Common.UI
[Header("Тексты")]
[SerializeField] private string creditTextFormat = "У вас осталось: {0}";
private PaymentManager _paymentManager;
private RR.Common.Managers.PaymentManager _paymentManager;
private Coroutine _continueCountdownCoroutine;
/// <summary>
@ -90,7 +89,7 @@ namespace RR.Common.UI
if (creditText && _paymentManager != null)
{
creditText.text = string.Format(creditTextFormat, _paymentManager.CreditsCount);
creditText.text = string.Format(creditTextFormat, (object)_paymentManager.CreditsCount);
}
if (continueButtonCountdown <= 0f)
@ -104,7 +103,8 @@ namespace RR.Common.UI
if (continueButton)
{
continueButton.gameObject.SetActive(true);
continueButton.interactable = SettingsManager.Instance.GetCurrentGameSettings().isFreeGame || (_paymentManager != null && _paymentManager.CreditsCount > 0);
var settings = RR.Common.Settings.SettingsManager.Instance;
continueButton.interactable = (settings != null && settings.GetBool("payment.freeGame")) || (_paymentManager != null && _paymentManager.CreditsCount > 0);
}
Open();
@ -164,7 +164,8 @@ namespace RR.Common.UI
{
if (_paymentManager == null) return;
if (_paymentManager.IsFreePlayEnabled() || SettingsManager.Instance.GetCurrentGameSettings().isFreeGame)
var settings = RR.Common.Settings.SettingsManager.Instance;
if (_paymentManager.IsFreePlayEnabled() || (settings != null && settings.GetBool("payment.freeGame")))
{
if (continueButton)
{

View File

@ -1,9 +1,9 @@
using RR.Common.Managers;
using UnityEngine;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using RR.Game2D.Core.Managers;
using TMPro;
using RR.Common.Settings;
namespace RR.Common.UI
{
@ -13,13 +13,16 @@ namespace RR.Common.UI
[SerializeField] private Button newGameButton;
[SerializeField] private Button quitButton;
[Header("Тексты")] [SerializeField] private TextMeshProUGUI paymentText;
[Header("Тексты")]
[SerializeField] private TextMeshProUGUI paymentText;
private PaymentManager _paymentManager;
private RR.Common.Managers.PaymentManager _paymentManager;
private RR.Common.Settings.SettingsManager _settingsManager;
private void Start()
{
_paymentManager = PaymentManager.Instance;
_paymentManager = RR.Common.Managers.PaymentManager.Instance;
_settingsManager = RR.Common.Settings.SettingsManager.Instance;
Bootstrap();
@ -28,20 +31,26 @@ namespace RR.Common.UI
quitButton.gameObject.SetActive(false);
}
if (_paymentManager != null) _paymentManager.OnCreditsChanged.AddListener(ChangePlayButtonInteractable);
if (_paymentManager != null)
_paymentManager.OnCreditsChanged.AddListener(OnCreditsChanged);
if (SettingsManager.Instance == null) return;
SettingsManager.Instance.OnSettingsLoaded += ChangePlayButtonInteractable;
SettingsManager.Instance.OnSettingsSaved += ChangePlayButtonInteractable;
if (_settingsManager != null)
{
_settingsManager.OnSettingsLoaded += OnSettingsChanged;
_settingsManager.OnSettingsSaved += OnSettingsChanged;
}
}
private void OnDestroy()
{
if (_paymentManager != null) _paymentManager.OnCreditsChanged.RemoveListener(ChangePlayButtonInteractable);
if (_paymentManager != null)
_paymentManager.OnCreditsChanged.RemoveListener(OnCreditsChanged);
if (SettingsManager.Instance == null) return;
SettingsManager.Instance.OnSettingsLoaded -= ChangePlayButtonInteractable;
SettingsManager.Instance.OnSettingsSaved -= ChangePlayButtonInteractable;
if (_settingsManager != null)
{
_settingsManager.OnSettingsLoaded -= OnSettingsChanged;
_settingsManager.OnSettingsSaved -= OnSettingsChanged;
}
}
/// <summary>
@ -54,7 +63,7 @@ namespace RR.Common.UI
{
newGameButton.onClick.AddListener(OnNewGame);
// Устанавливаем начальное состояние кнопки
ChangePlayButtonInteractable();
UpdatePlayButtonState();
}
if (quitButton) quitButton.onClick.AddListener(OnQuit);
}
@ -75,28 +84,35 @@ namespace RR.Common.UI
Application.Quit();
}
private void ChangePlayButtonInteractable(int credits)
private void OnCreditsChanged(int credits)
{
UpdatePlayButtonState(credits);
}
private void OnSettingsChanged()
{
UpdatePlayButtonState();
}
private void UpdatePlayButtonState(int credits = -1)
{
if (credits < 0)
credits = _paymentManager?.CreditsCount ?? 0;
// Проверяем только через SettingsManager, так как PaymentManager обновляется с задержкой
if (SettingsManager.Instance.GetCurrentGameSettings().isFreeGame)
if (_settingsManager != null && _settingsManager.GetBool("payment.freeGame"))
{
newGameButton.interactable = true;
newGameButton.interactable = true;
paymentText.gameObject.SetActive(false);
return;
}
else paymentText.gameObject.SetActive(true);
paymentText.gameObject.SetActive(true);
if (!newGameButton) return;
bool canStartGame = credits >= 1;
newGameButton.interactable = canStartGame;
newGameButton.interactable = canStartGame;
paymentText.gameObject.SetActive(!canStartGame);
}
private void ChangePlayButtonInteractable()
{
ChangePlayButtonInteractable(_paymentManager.CreditsCount);
}
}
}

View File

@ -88,7 +88,7 @@ namespace RR.Common.UI
}
// Если canvasGroup не указан или указан на родительском объекте,
// создаём/получаем CanvasGroup на самом модальном окне
// создаем/получаем CanvasGroup на самом модальном окне
if (!canvasGroup || canvasGroup.gameObject != gameObject)
{
canvasGroup = GetComponent<CanvasGroup>();

View File

@ -85,6 +85,14 @@ namespace RR.Common.UI
DontDestroyOnLoad(gameObject);
}
private void OnDestroy()
{
if (_instance == this)
{
_instance = null;
}
}
private void Update()
{
// Следим за тем, чтобы фокус оставался внутри текущего модального окна

View File

@ -1,14 +1,15 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.InputSystem;
using RR.Common.Managers;
using UnityEngine.EventSystems;
using RR.Game2D.Core.Managers;
using RR.Common.Settings;
namespace RR.Common.UI
{
/// <summary>
/// Модальное окно настроек игры.
/// Управляет отображением и сохранением настроек через SettingsManager.
/// Управляет отображением и сохранением настроек через новый SettingsManager.
/// </summary>
[RequireComponent(typeof(CanvasGroup))]
public class SettingsUI : Modal
@ -19,8 +20,12 @@ namespace RR.Common.UI
[Header("Контент настроек")]
[SerializeField] private Transform content;
[SerializeField] private SettingsUIGenerator settingsGenerator;
[Header("Навигация")]
[Tooltip("Первый элемент для фокуса при открытии. Если не задан - ищется автоматически.")]
[SerializeField] private Selectable firstSelectable;
private SettingsUIList settingsUIList;
private SettingsManager settingsManager;
protected override void Awake()
@ -34,23 +39,67 @@ namespace RR.Common.UI
if (settingsManager == null)
{
GameManager.Logger.LogError(name, "SettingsManager is null!");
return;
GameManager.Logger?.LogError(name, "SettingsManager is null!");
// Не выходим - подпишемся позже когда SettingsManager появится
}
else
{
settingsManager.OnSettingsLoaded += OnSettingsLoaded;
settingsManager.OnSettingsSaved += OnSettingsSaved;
}
settingsManager.OnSettingsLoaded += UpdateSettings;
settingsManager.OnSettingsSaved += SaveSettingsHandler;
if (saveButton)
saveButton.onClick.AddListener(SaveAndClose);
// Подписываемся на события settingsGenerator сразу (даже если неактивен)
SubscribeToGenerator();
}
private bool _subscribedToGenerator = false;
private void SubscribeToGenerator()
{
if (_subscribedToGenerator) return;
// Если не назначен - пробуем найти в детях
if (settingsGenerator == null)
{
settingsGenerator = GetComponentInChildren<SettingsUIGenerator>(true);
}
if (settingsGenerator != null)
{
Debug.Log($"[SettingsUI] Subscribing to settingsGenerator events: {settingsGenerator.name}");
settingsGenerator.OnBuildComplete += OnGeneratorBuildComplete;
settingsGenerator.OnGroupExpandedChanged += OnGroupExpandedChanged;
_subscribedToGenerator = true;
}
else
{
Debug.LogWarning("[SettingsUI] settingsGenerator is NULL - cannot subscribe to events! Make sure to assign it in Inspector or add SettingsUIGenerator as a child.");
}
}
protected override void OnEnable()
{
base.OnEnable();
// Пробуем подписаться снова если не удалось в Awake
SubscribeToGenerator();
}
private void OnDestroy()
{
if (settingsManager != null)
{
settingsManager.OnSettingsLoaded -= UpdateSettings;
settingsManager.OnSettingsSaved -= SaveSettingsHandler;
settingsManager.OnSettingsLoaded -= OnSettingsLoaded;
settingsManager.OnSettingsSaved -= OnSettingsSaved;
}
if (_subscribedToGenerator && settingsGenerator != null)
{
settingsGenerator.OnBuildComplete -= OnGeneratorBuildComplete;
settingsGenerator.OnGroupExpandedChanged -= OnGroupExpandedChanged;
}
if (triggerKey != null)
@ -59,6 +108,182 @@ namespace RR.Common.UI
if (saveButton)
saveButton.onClick.RemoveListener(SaveAndClose);
}
private void OnGeneratorBuildComplete()
{
// Настраиваем навигацию после построения
SetupExplicitNavigation();
// Выбираем первый элемент
if (settingsGenerator != null && settingsGenerator.FirstSelectable != null)
{
if (EventSystem.current != null)
{
EventSystem.current.SetSelectedGameObject(settingsGenerator.FirstSelectable.gameObject);
Debug.Log($"[SettingsUI] Selected first element from generator: {settingsGenerator.FirstSelectable.name}");
}
}
}
private void OnGroupExpandedChanged()
{
Debug.Log("[SettingsUI] OnGroupExpandedChanged called - rebuilding navigation");
// При сворачивании/разворачивании группы - перестраиваем навигацию
StartCoroutine(RebuildNavigationOnGroupChange());
}
private System.Collections.IEnumerator RebuildNavigationOnGroupChange()
{
Debug.Log("[SettingsUI] RebuildNavigationOnGroupChange started");
// Запоминаем текущий выбранный объект
GameObject currentSelected = EventSystem.current?.currentSelectedGameObject;
// Ждём кадр чтобы layout обновился
yield return null;
Debug.Log("[SettingsUI] Calling SetupExplicitNavigation after group change");
// Перестраиваем навигацию
SetupExplicitNavigation();
// Проверяем, активен ли текущий выбранный объект
if (currentSelected == null || !currentSelected.activeInHierarchy)
{
Debug.Log("[SettingsUI] Current selected is inactive, reselecting first element");
// Текущий элемент стал неактивен (свёрнут) - выбираем первый активный
var allSelectables = new System.Collections.Generic.List<Selectable>();
Transform searchRoot = settingsGenerator != null && settingsGenerator.ContentRoot != null
? settingsGenerator.ContentRoot
: content;
if (searchRoot != null)
{
CollectActiveSelectables(searchRoot, allSelectables);
if (allSelectables.Count > 0 && EventSystem.current != null)
{
EventSystem.current.SetSelectedGameObject(allSelectables[0].gameObject);
Debug.Log($"[SettingsUI] Reselected first element after group change: {allSelectables[0].name}");
}
}
}
}
/// <summary>
/// Настраивает явную (Explicit) навигацию между всеми элементами настроек и кнопкой сохранения
/// </summary>
private void SetupExplicitNavigation()
{
// Собираем все активные Selectable элементы
var allSelectables = new System.Collections.Generic.List<Selectable>();
// Ищем в ContentRoot из settingsGenerator или в content
Transform searchRoot = null;
if (settingsGenerator != null && settingsGenerator.ContentRoot != null)
{
searchRoot = settingsGenerator.ContentRoot;
}
else if (content != null)
{
searchRoot = content;
}
if (searchRoot == null)
{
Debug.LogWarning("[SettingsUI] No content root found for navigation setup");
return;
}
Debug.Log($"[SettingsUI] Setting up navigation, searchRoot: {searchRoot.name}");
// Получаем все Selectable в порядке иерархии (только активные)
CollectActiveSelectables(searchRoot, allSelectables);
Debug.Log($"[SettingsUI] Found {allSelectables.Count} selectables");
if (allSelectables.Count == 0)
{
Debug.LogWarning("[SettingsUI] No active selectables found for navigation setup");
return;
}
// Настраиваем вертикальную навигацию для каждого элемента
for (int i = 0; i < allSelectables.Count; i++)
{
var current = allSelectables[i];
var nav = new Navigation();
nav.mode = Navigation.Mode.Explicit;
// Вверх - предыдущий элемент или saveButton (для первого)
if (i == 0)
{
nav.selectOnUp = saveButton;
}
else
{
nav.selectOnUp = allSelectables[i - 1];
}
// Вниз - следующий элемент или saveButton (для последнего)
if (i == allSelectables.Count - 1)
{
nav.selectOnDown = saveButton;
}
else
{
nav.selectOnDown = allSelectables[i + 1];
}
// Горизонтальная навигация - оставляем null (не переходим влево/вправо на другие элементы)
nav.selectOnLeft = null;
nav.selectOnRight = null;
current.navigation = nav;
Debug.Log($"[SettingsUI] Set Explicit nav for: {current.name}, mode: {current.navigation.mode}");
}
// Настраиваем кнопку с<><D181>хранения
if (saveButton != null)
{
var saveNav = new Navigation();
saveNav.mode = Navigation.Mode.Explicit;
saveNav.selectOnUp = allSelectables[allSelectables.Count - 1]; // Последний элемент
saveNav.selectOnDown = allSelectables[0]; // Первый элемент (циклическая)
saveNav.selectOnLeft = null;
saveNav.selectOnRight = null;
saveButton.navigation = saveNav;
}
Debug.Log($"[SettingsUI] Explicit navigation setup complete. Elements: {allSelectables.Count}");
}
/// <summary>
/// Рекурсивно собирает все активные Selectable элементы в порядке иерархии
/// </summary>
private void CollectActiveSelectables(Transform parent, System.Collections.Generic.List<Selectable> result)
{
for (int i = 0; i < parent.childCount; i++)
{
var child = parent.GetChild(i);
// Пропускаем неактивные объекты
if (!child.gameObject.activeInHierarchy) continue;
// Проверяем, есть ли Selectable на этом объекте
var selectable = child.GetComponent<Selectable>();
if (selectable != null && selectable.interactable)
{
result.Add(selectable);
}
// Рекурсивно ищем в детях
CollectActiveSelectables(child, result);
}
}
private void OnTriggerKey(InputAction.CallbackContext ctx)
{
@ -77,17 +302,75 @@ namespace RR.Common.UI
/// </summary>
public override void Open()
{
UpdateSettings();
RefreshSettings();
base.Open();
// Выбираем первый элемент для навигации
SelectFirstElement();
}
private void SelectFirstElement()
{
// Запускаем корутину с задержкой, чтобы UI успел построиться
StartCoroutine(SelectFirstElementDelayed());
}
private System.Collections.IEnumerator SelectFirstElementDelayed()
{
// Ждём несколько кадров чтобы SettingsUIGenerator успел построить элементы
yield return null;
yield return null;
yield return new WaitForSecondsRealtime(0.1f);
// Настраиваем явную навигацию
SetupExplicitNavigation();
Selectable target = firstSelectable;
// Если не задан явно - ищем первый интерактивный элемент в content
if (target == null && content != null)
{
target = content.GetComponentInChildren<Selectable>();
}
// Если всё ещё не нашли - ищем в settingsGenerator
if (target == null && settingsGenerator != null)
{
target = settingsGenerator.GetComponentInChildren<Selectable>();
}
// Последняя попытка - ищем во всём объекте
if (target == null)
{
target = GetComponentInChildren<Selectable>();
}
if (target != null && EventSystem.current != null)
{
EventSystem.current.SetSelectedGameObject(target.gameObject);
Debug.Log($"[SettingsUI] Selected first element: {target.name}");
}
else
{
Debug.LogWarning("[SettingsUI] Could not find any selectable element for focus");
}
}
private void RefreshSettings()
{
// Если используется новый генератор
if (settingsGenerator != null)
{
settingsGenerator.RefreshValues();
}
}
private void Save()
{
if (settingsUIList == null)
settingsUIList = content.GetComponent<SettingsUIList>();
if (settingsUIList != null)
settingsUIList.SaveSettings();
if (settingsManager != null)
{
settingsManager.SaveSettings();
}
}
public void SaveAndClose()
@ -96,18 +379,14 @@ namespace RR.Common.UI
Close();
}
private void UpdateSettings()
private void OnSettingsLoaded()
{
if (settingsUIList == null)
settingsUIList = content.GetComponent<SettingsUIList>();
if (settingsUIList != null)
settingsUIList.UpdateSettings(settingsManager.GetCurrentGameSettings());
RefreshSettings();
}
private void SaveSettingsHandler()
private void OnSettingsSaved()
{
GameManager.Logger.Log(name, "Saved settings");
GameManager.Logger?.Log(name, "Saved settings");
}
}
}

View File

@ -1,211 +0,0 @@
using System;
using System.Collections.Generic;
using RR.Common.Behaviour.ScriptableObjects;
using RR.Common.Managers;
using RR.Game2D.Core.Managers;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace RR.Common.UI
{
public class SettingsUIList : MonoBehaviour
{
public List<Selectable> settingsList = new();
[Header("Настройки")]
// Volume
[SerializeField] private Slider musicVolumeSlider;
[SerializeField] private Slider sfxVolumeSlider;
// Payment
[SerializeField] private Toggle freeGameToggle;
[SerializeField] private Toggle givingPrizesToggle;
// Player
[SerializeField] private Slider startLivesSlider;
[SerializeField] private Slider increasedLivesSlider;
// Buttons
[SerializeField] private Button statsButton;
[Header("Текст в UI")]
// Text
[SerializeField] private TextMeshProUGUI volumePercentageText;
[SerializeField] private TextMeshProUGUI sfxVolumePercentageText;
[SerializeField] private TextMeshProUGUI startLivesCountText;
[SerializeField] private TextMeshProUGUI increasedLivesCountText;
private SettingsManager settingsManager;
private GameSettings currentSettings;
private void Awake()
{
settingsManager = SettingsManager.Instance;
if (settingsManager == null)
{
GameManager.Logger.LogError(name, "SettingsManager is null!");
return;
}
settingsList.Add(musicVolumeSlider);
settingsList.Add(sfxVolumeSlider);
settingsList.Add(freeGameToggle);
settingsList.Add(givingPrizesToggle);
settingsList.Add(startLivesSlider);
settingsList.Add(increasedLivesSlider);
settingsList.Add(statsButton);
currentSettings = settingsManager.GetCurrentGameSettings();
AddListeners();
UpdateSettings(currentSettings);
}
private void OnDestroy()
{
RemoveListeners();
}
public void UpdateSettings(GameSettings newSettings = null)
{
if (newSettings != null) currentSettings = newSettings;
RemoveListeners();
musicVolumeSlider.value = currentSettings.musicVolume;
sfxVolumeSlider.value = currentSettings.sfxVolume;
freeGameToggle.isOn = currentSettings.isFreeGame;
givingPrizesToggle.isOn = currentSettings.isGivingPrizes;
startLivesSlider.value = currentSettings.startLivesCount;
increasedLivesSlider.value = currentSettings.livesIncreasedByCredits;
AddListeners();
}
public void SaveSettings()
{
settingsManager.SaveSettings();
}
private void AddListeners()
{
// Music Volume
if (musicVolumeSlider != null)
{
musicVolumeSlider.onValueChanged.AddListener(settingsManager.SetMusicVolume);
musicVolumeSlider.onValueChanged.AddListener(SetMusicVolumePercentage);
musicVolumeSlider.onValueChanged.AddListener(GameManager.Instance.Audio.SetMusicVolume);
}
// SFX Volume
if (sfxVolumeSlider != null)
{
sfxVolumeSlider.onValueChanged.AddListener(settingsManager.SetSfxVolume);
sfxVolumeSlider.onValueChanged.AddListener(SetSfxVolumePercentage);
sfxVolumeSlider.onValueChanged.AddListener(GameManager.Instance.Audio.SetSfxVolume);
}
// Free game
if (freeGameToggle != null)
{
freeGameToggle.onValueChanged.AddListener(settingsManager.SetIsFreeGame);
}
// Giving prizes
if (givingPrizesToggle != null)
{
givingPrizesToggle.onValueChanged.AddListener(settingsManager.SetIsGivingPrizes);
}
// Start lives
if (startLivesSlider != null)
{
startLivesSlider.onValueChanged.AddListener(value =>
settingsManager.SetStartLivesCount((int)value));
startLivesSlider.onValueChanged.AddListener(SetStartLivesCountText);
}
// Increased lives
if (increasedLivesSlider != null)
{
increasedLivesSlider.onValueChanged.AddListener(value =>
settingsManager.SetLivesIncreasedByCredits((int)value));
increasedLivesSlider.onValueChanged.AddListener(SetIncreasedLivesCountText);
}
}
private void RemoveListeners()
{
// Music Volume
if (musicVolumeSlider != null)
{
musicVolumeSlider.onValueChanged.RemoveListener(settingsManager.SetMusicVolume);
musicVolumeSlider.onValueChanged.AddListener(SetMusicVolumePercentage);
}
// SFX Volume
if (sfxVolumeSlider != null)
{
sfxVolumeSlider.onValueChanged.RemoveListener(settingsManager.SetSfxVolume);
sfxVolumeSlider.onValueChanged.AddListener(SetSfxVolumePercentage);
}
// Free game
if (freeGameToggle != null)
{
freeGameToggle.onValueChanged.RemoveListener(settingsManager.SetIsFreeGame);
}
// Giving prizes
if (givingPrizesToggle != null)
{
givingPrizesToggle.onValueChanged.RemoveListener(settingsManager.SetIsGivingPrizes);
}
// Start lives
if (startLivesSlider != null)
{
startLivesSlider.onValueChanged.RemoveListener(value =>
settingsManager.SetStartLivesCount((int)value));
startLivesSlider.onValueChanged.AddListener(SetStartLivesCountText);
}
// Increased lives
if (increasedLivesSlider != null)
{
increasedLivesSlider.onValueChanged.RemoveListener(value =>
settingsManager.SetLivesIncreasedByCredits((int)value));
increasedLivesSlider.onValueChanged.AddListener(SetIncreasedLivesCountText);
}
}
private void SetMusicVolumePercentage(float value)
{
if (volumePercentageText == null) return;
int volumePercent = Mathf.RoundToInt(value * 100);
volumePercentageText.text = $"{volumePercent}%";
}
private void SetSfxVolumePercentage(float value)
{
if (sfxVolumePercentageText == null) return;
int sfxVolumePercent = Mathf.RoundToInt(value * 100);
sfxVolumePercentageText.text = $"{sfxVolumePercent}%";
}
private void SetStartLivesCountText(float value)
{
if (startLivesCountText == null) return;
startLivesCountText.text = $"{(int)value}";
}
private void SetIncreasedLivesCountText(float value)
{
if (increasedLivesCountText == null) return;
increasedLivesCountText.text = $"{(int)value}";
}
}
}

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 98f414c07d2f47e794d25468e8519ba7
timeCreated: 1762519929

View File

@ -1,6 +1,5 @@
using System;
using RR.Common.Managers;
using RR.Game2D.Core.Managers;
using RR.Game2D.Core.Managers;
using RR.Common.Settings;
using TMPro;
using UnityEngine;
@ -32,9 +31,12 @@ namespace RR.Common.UI
UpdateLivesText(_gameManager.MaxLives);
UpdateLivesIncreaseText();
_gameManager.MaxLivesChanged += (UpdateLivesText);
_gameManager.Settings.OnSettingsLoaded += UpdateLivesIncreaseText;
_gameManager.Settings.OnSettingsSaved += UpdateLivesIncreaseText;
_gameManager.MaxLivesChanged += UpdateLivesText;
if (_settingsManager != null)
{
_settingsManager.OnSettingsLoaded += UpdateLivesIncreaseText;
_settingsManager.OnSettingsSaved += UpdateLivesIncreaseText;
}
}
private void OnDestroy()
@ -42,16 +44,23 @@ namespace RR.Common.UI
if (_gameManager == null) _gameManager = GameManager.Instance;
if (_gameManager != null) _gameManager.MaxLivesChanged -= UpdateLivesText;
if (_settingsManager != null)
{
_settingsManager.OnSettingsLoaded -= UpdateLivesIncreaseText;
_settingsManager.OnSettingsSaved -= UpdateLivesIncreaseText;
}
}
private void UpdateLivesIncreaseText()
{
livesIncreaseText.text = string.Format(livesIncreaseString, _settingsManager.GetCurrentGameSettings().livesIncreasedByCredits);
if (_settingsManager != null)
livesIncreaseText.text = string.Format(livesIncreaseString, _settingsManager.GetInt("gameplay.additionalLives"));
}
private void UpdateLivesText(int newLives)
{
livesText.text = string.Format(livesString, newLives);
livesText.text = string.Format(livesString, (object)newLives);
}
}
}

View File

@ -1,4 +1,5 @@
using UnityEngine;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
namespace RR.Common.UI
@ -10,8 +11,21 @@ namespace RR.Common.UI
[SerializeField] private RectTransform content; // Content ScrollView, где находятся элементы
[SerializeField] private float smoothSpeed = 10f; // Скорость перемещения указателя
[SerializeField] private Vector2 offset = Vector2.zero; // Смещение указателя относительно элемента
[Header("Поведение")]
[Tooltip("Не скрывать указатель при отсутствии выбора (оставаться на последней позиции)")]
[SerializeField] private bool keepVisibleWhenNoSelection = true;
[Tooltip("Задержка перед скрытием указателя (в секундах)")]
[SerializeField] private float hideDelay = 0.5f;
[Header("Исключения")]
[Tooltip("Элементы, при выборе которых курсор скрывается")]
[SerializeField] private List<GameObject> hideOnSelectElements = new();
private RectTransform pointerRect;
private float hideTimer;
private bool hasEverSelected; // Был ли когда-либо выбран элемент
private void Start()
{
@ -33,6 +47,8 @@ namespace RR.Common.UI
{
content = GetComponent<RectTransform>();
}
hideTimer = hideDelay;
}
private void LateUpdate()
@ -42,11 +58,17 @@ namespace RR.Common.UI
// Получаем текущий выбранный элемент из EventSystem
GameObject selected = EventSystem.current?.currentSelectedGameObject;
// Если ничего не выбрано, скрываем указатель
// Если ничего не выбрано
if (selected == null)
{
if (pointer.activeSelf)
pointer.SetActive(false);
HandleNoSelection();
return;
}
// Проверяем, находится ли выбранный элемент в списке исключений
if (IsInHideList(selected))
{
HidePointer();
return;
}
@ -54,11 +76,14 @@ namespace RR.Common.UI
RectTransform selectedRect = selected.GetComponent<RectTransform>();
if (!selectedRect || !selectedRect.IsChildOf(content))
{
if (pointer.activeSelf)
pointer.SetActive(false);
HandleNoSelection();
return;
}
// Сбрасываем таймер и отмечаем что был выбор
hideTimer = hideDelay;
hasEverSelected = true;
// Показываем указатель, если он был скрыт
if (!pointer.activeSelf)
pointer.SetActive(true);
@ -80,6 +105,52 @@ namespace RR.Common.UI
pointerRect.anchoredPosition = targetPos;
}
}
private void HandleNoSelection()
{
// Если включено сохранение видимости или ещё не было выбора - не скрываем
if (keepVisibleWhenNoSelection || !hasEverSelected)
return;
// Уменьшаем таймер
hideTimer -= Time.unscaledDeltaTime;
if (hideTimer <= 0 && pointer.activeSelf)
{
pointer.SetActive(false);
}
}
/// <summary>
/// Проверяет, находится ли элемент в списке исключений или является его дочерним элементом
/// </summary>
private bool IsInHideList(GameObject obj)
{
if (hideOnSelectElements == null || hideOnSelectElements.Count == 0)
return false;
foreach (var hideElement in hideOnSelectElements)
{
if (hideElement == null) continue;
// Проверяем сам элемент или его родителей
if (obj == hideElement || obj.transform.IsChildOf(hideElement.transform))
return true;
}
return false;
}
/// <summary>
/// Немедленно скрывает указатель
/// </summary>
private void HidePointer()
{
if (pointer != null && pointer.activeSelf)
{
pointer.SetActive(false);
}
}
private Vector2 GetTargetPosition(RectTransform target)
{

View File

@ -14,6 +14,12 @@ EditorBuildSettings:
- enabled: 1
path: Assets/Scenes/Levels/1-1.unity
guid: 8c9cfa26abfee488c85f1582747f6a02
- enabled: 1
path: Assets/Scenes/Levels/1-2.unity
guid: 86bb899abf617614ea731dfb70ed822e
- enabled: 1
path: Assets/Scenes/Levels/1-3.unity
guid: 970503f52fc318443aa802884a95f012
- enabled: 0
path: Assets/Scenes/Levels/Old/1-2.unity
guid: 9336a368292b6644db1e12e6521b3734
@ -26,12 +32,6 @@ EditorBuildSettings:
- enabled: 0
path: Assets/Scenes/Levels/Old/1-5.unity
guid: b63c94138b89518459c618e66e063850
- enabled: 1
path: Assets/Scenes/Levels/1-2.unity
guid: 86bb899abf617614ea731dfb70ed822e
- enabled: 1
path: Assets/Scenes/Levels/1-3.unity
guid: 970503f52fc318443aa802884a95f012
m_configObjects:
com.unity.addressableassets: {fileID: 11400000, guid: 40a4d2dfb24d5af4d8277c2c4cdffcc3, type: 2}
com.unity.dt.app-ui: {fileID: 11400000, guid: 1b1c20d82303e4b5781c3ef50ac1449f, type: 2}

View File

@ -311,6 +311,9 @@ PlayerSettings:
- m_BuildTarget: WindowsStandaloneSupport
m_APIs: 0200000012000000
m_Automatic: 0
- m_BuildTarget: LinuxStandaloneSupport
m_APIs: 1500000011000000
m_Automatic: 0
m_BuildTargetVRSettings: []
m_DefaultShaderChunkSizeInMB: 16
m_DefaultShaderChunkCount: 0