Main menu

This commit is contained in:
Dominik G.
2025-10-04 17:22:58 +02:00
parent c2173eb9b7
commit b52b3aa830
382 changed files with 118492 additions and 0 deletions

68
UI/MainMenu.uxml Normal file
View File

@@ -0,0 +1,68 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<Style src="project://database/Assets/UI/MainMenuStyles.uss?fileID=7433441132597879392&amp;guid=PLACEHOLDER&amp;type=3#MainMenuStyles" />
<!-- Main Container -->
<ui:VisualElement name="MainContainer" class="main-container">
<!-- Background Overlay -->
<ui:VisualElement name="Background" class="background-overlay" />
<!-- Menu Content -->
<ui:VisualElement name="MenuContent" class="menu-content">
<!-- Title Section -->
<ui:VisualElement name="TitleSection" class="title-section">
<ui:Label text="MEGA KOOP" name="GameTitle" class="game-title" />
<ui:Label text="CO-OP ADVENTURE" name="Subtitle" class="subtitle" />
</ui:VisualElement>
<!-- Menu Buttons Container -->
<ui:VisualElement name="ButtonsContainer" class="buttons-container">
<!-- Main Menu Buttons -->
<ui:Button text="NEW GAME" name="NewGameButton" class="menu-button primary-button" />
<ui:Button text="CONTINUE" name="ContinueButton" class="menu-button" />
<ui:Button text="MULTIPLAYER" name="MultiplayerButton" class="menu-button" />
<ui:Button text="SETTINGS" name="SettingsButton" class="menu-button" />
<ui:Button text="CREDITS" name="CreditsButton" class="menu-button" />
<ui:Button text="QUIT GAME" name="QuitButton" class="menu-button danger-button" />
</ui:VisualElement>
<!-- Version Info -->
<ui:VisualElement name="VersionInfo" class="version-info">
<ui:Label text="Version 1.0.0" name="VersionLabel" class="version-label" />
</ui:VisualElement>
</ui:VisualElement>
<!-- Settings Panel (Initially Hidden) -->
<ui:VisualElement name="SettingsPanel" class="settings-panel hidden">
<ui:VisualElement class="settings-content">
<ui:Label text="SETTINGS" class="panel-title" />
<ui:VisualElement class="settings-section">
<ui:Label text="Graphics" class="section-title" />
<ui:DropdownField label="Quality:" name="QualityDropdown" class="setting-control" />
<ui:Toggle label="Fullscreen" name="FullscreenToggle" class="setting-control" />
<ui:DropdownField label="Resolution:" name="ResolutionDropdown" class="setting-control" />
</ui:VisualElement>
<ui:VisualElement class="settings-section">
<ui:Label text="Audio" class="section-title" />
<ui:Slider label="Master Volume" high-value="100" name="MasterVolumeSlider" class="setting-control" />
<ui:Slider label="Music Volume" high-value="100" name="MusicVolumeSlider" class="setting-control" />
<ui:Slider label="SFX Volume" high-value="100" name="SFXVolumeSlider" class="setting-control" />
</ui:VisualElement>
<ui:VisualElement class="settings-buttons">
<ui:Button text="APPLY" name="ApplyButton" class="menu-button primary-button" />
<ui:Button text="BACK" name="BackButton" class="menu-button" />
</ui:VisualElement>
</ui:VisualElement>
</ui:VisualElement>
</ui:VisualElement>
</ui:UXML>

10
UI/MainMenu.uxml.meta Normal file
View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 294102ee511c39e4d8511f672dd8963f
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}

364
UI/MainMenuStyles.uss Normal file
View File

@@ -0,0 +1,364 @@
/* ====================
ROOT VARIABLES
==================== */
:root {
/* Color Palette */
--color-primary: rgb(76, 175, 80);
--color-primary-hover: rgb(102, 187, 106);
--color-primary-dark: rgb(56, 142, 60);
--color-danger: rgb(244, 67, 54);
--color-danger-hover: rgb(229, 115, 115);
--color-background-dark: rgba(18, 18, 18, 0.95);
--color-background-panel: rgba(33, 33, 33, 0.98);
--color-surface: rgba(48, 48, 48, 0.9);
--color-text-primary: rgb(255, 255, 255);
--color-text-secondary: rgb(189, 189, 189);
--color-text-disabled: rgb(117, 117, 117);
/* Spacing */
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
--spacing-xxl: 48px;
/* Border Radius */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
/* Shadows */
--shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 8px rgba(0, 0, 0, 0.4);
--shadow-lg: 0 8px 16px rgba(0, 0, 0, 0.5);
/* Transitions */
--transition-fast: 0.15s;
--transition-normal: 0.3s;
--transition-slow: 0.5s;
}
/* ====================
MAIN CONTAINER
==================== */
.main-container {
width: 100%;
height: 100%;
background-color: var(--color-background-dark);
justify-content: center;
align-items: center;
}
.background-overlay {
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
}
/* ====================
MENU CONTENT
==================== */
.menu-content {
width: 500px;
padding: var(--spacing-xxl);
background-color: var(--color-background-panel);
border-radius: var(--radius-lg);
border-width: 2px;
border-color: rgba(76, 175, 80, 0.3);
align-items: center;
justify-content: space-between;
transition-duration: var(--transition-normal);
}
/* ====================
TITLE SECTION
==================== */
.title-section {
align-items: center;
margin-bottom: var(--spacing-xl);
padding-top: var(--spacing-lg);
}
.game-title {
font-size: 64px;
-unity-font-style: bold;
color: var(--color-primary);
letter-spacing: 4px;
text-shadow: 0 4px 12px rgba(76, 175, 80, 0.6);
margin-bottom: var(--spacing-sm);
-unity-text-align: middle-center;
}
.subtitle {
font-size: 16px;
color: var(--color-text-secondary);
letter-spacing: 2px;
-unity-text-align: middle-center;
opacity: 0.8;
}
/* ====================
BUTTONS CONTAINER
==================== */
.buttons-container {
width: 100%;
align-items: stretch;
margin-top: var(--spacing-lg);
margin-bottom: var(--spacing-lg);
}
/* ====================
MENU BUTTONS
==================== */
.menu-button {
height: 50px;
margin-top: var(--spacing-sm);
margin-bottom: var(--spacing-sm);
background-color: var(--color-surface);
border-radius: var(--radius-md);
border-width: 2px;
border-color: rgba(255, 255, 255, 0.1);
color: var(--color-text-primary);
font-size: 18px;
-unity-font-style: bold;
letter-spacing: 1px;
transition-duration: var(--transition-fast);
transition-property: background-color, border-color, scale;
}
.menu-button:hover {
background-color: rgba(76, 175, 80, 0.2);
border-color: var(--color-primary);
scale: 1.02 1.02;
translate: 0 -2px;
}
.menu-button:active {
background-color: rgba(76, 175, 80, 0.3);
scale: 0.98 0.98;
translate: 0 0;
}
/* Primary Button Variant */
.primary-button {
background-color: var(--color-primary);
border-color: var(--color-primary-dark);
}
.primary-button:hover {
background-color: var(--color-primary-hover);
border-color: var(--color-primary);
scale: 1.05 1.05;
}
.primary-button:active {
background-color: var(--color-primary-dark);
scale: 0.98 0.98;
}
/* Danger Button Variant */
.danger-button {
background-color: rgba(244, 67, 54, 0.2);
border-color: rgba(244, 67, 54, 0.4);
}
.danger-button:hover {
background-color: var(--color-danger);
border-color: var(--color-danger);
scale: 1.02 1.02;
}
.danger-button:active {
background-color: rgb(211, 47, 47);
scale: 0.98 0.98;
}
/* ====================
VERSION INFO
==================== */
.version-info {
width: 100%;
align-items: center;
margin-top: var(--spacing-lg);
padding-top: var(--spacing-md);
border-top-width: 1px;
border-color: rgba(255, 255, 255, 0.1);
}
.version-label {
font-size: 12px;
color: var(--color-text-secondary);
opacity: 0.6;
-unity-text-align: middle-center;
}
/* ====================
SETTINGS PANEL
==================== */
.settings-panel {
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
justify-content: center;
align-items: center;
transition-duration: var(--transition-normal);
}
.settings-panel.hidden {
display: none;
}
.settings-content {
width: 600px;
max-height: 80%;
padding: var(--spacing-xl);
background-color: var(--color-background-panel);
border-radius: var(--radius-lg);
border-width: 2px;
border-color: rgba(76, 175, 80, 0.3);
}
.panel-title {
font-size: 36px;
-unity-font-style: bold;
color: var(--color-primary);
letter-spacing: 2px;
margin-bottom: var(--spacing-xl);
-unity-text-align: middle-center;
}
/* ====================
SETTINGS SECTIONS
==================== */
.settings-section {
margin-bottom: var(--spacing-xl);
padding: var(--spacing-md);
background-color: rgba(255, 255, 255, 0.05);
border-radius: var(--radius-md);
}
.section-title {
font-size: 20px;
-unity-font-style: bold;
color: var(--color-text-primary);
margin-bottom: var(--spacing-md);
}
/* ====================
SETTING CONTROLS
==================== */
.setting-control {
margin-top: var(--spacing-sm);
margin-bottom: var(--spacing-sm);
height: 30px;
}
.setting-control Label {
min-width: 120px;
color: var(--color-text-secondary);
font-size: 14px;
}
.setting-control .unity-base-field__input {
background-color: var(--color-surface);
border-radius: var(--radius-sm);
border-width: 1px;
border-color: rgba(255, 255, 255, 0.2);
color: var(--color-text-primary);
}
/* Slider Styles */
.unity-slider {
flex-grow: 1;
}
.unity-slider__tracker {
background-color: rgba(255, 255, 255, 0.1);
border-radius: 4px;
height: 6px;
}
.unity-slider__dragger {
width: 18px;
height: 18px;
background-color: var(--color-primary);
border-radius: 50%;
border-width: 2px;
border-color: var(--color-primary-dark);
}
.unity-slider__dragger:hover {
background-color: var(--color-primary-hover);
scale: 1.2 1.2;
}
/* Toggle Styles */
.unity-toggle__input {
background-color: rgba(255, 255, 255, 0.1);
border-radius: var(--radius-sm);
}
.unity-toggle:checked .unity-toggle__input {
background-color: var(--color-primary);
}
.unity-toggle__checkmark {
background-color: white;
border-radius: 2px;
}
/* Dropdown Styles */
.unity-base-popup-field__input {
background-color: var(--color-surface);
border-radius: var(--radius-sm);
padding: var(--spacing-sm);
}
.unity-base-popup-field__input:hover {
border-color: var(--color-primary);
}
/* ====================
SETTINGS BUTTONS
==================== */
.settings-buttons {
flex-direction: row;
justify-content: space-between;
margin-top: var(--spacing-xl);
}
.settings-buttons .menu-button {
flex-grow: 1;
margin-left: var(--spacing-sm);
margin-right: var(--spacing-sm);
}
/* ====================
ANIMATIONS & EFFECTS
==================== */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideUp {
from {
opacity: 0;
translate: 0 50px;
}
to {
opacity: 1;
translate: 0 0;
}
}
/* Apply animations (Note: Unity USS doesn't support keyframe animations natively,
but you can control these via C# using transitions) */

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7d1b32ae1644e38488ff1eeb11d87da7
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0

354
UI/README.md Normal file
View File

@@ -0,0 +1,354 @@
# Main Menu UI - Unity UI Toolkit Guide
## 📋 Přehled
Tento projekt obsahuje moderní hlavní menu vytvořené pomocí **Unity UI Toolkit** (dříve UIElements) s využitím **UXML** pro strukturu a **USS** (Unity Style Sheets) pro styling.
## 📁 Struktura souborů
```
Assets/UI/
├── MainMenu.uxml # Struktura UI (HTML-like)
├── MainMenuStyles.uss # Styly (CSS-like)
├── Scripts/
│ └── MainMenuController.cs # Logika a funkčnost
└── README.md # Tento soubor
```
## 🚀 Jak začít
### 1. Nastavení scény
1. Vytvořte novou scénu (nebo použijte existující)
2. Přidejte **GameObject****UI Toolkit****UI Document**
3. V inspektoru UI Document:
- Přiřaďte `MainMenu.uxml` do pole **Source Asset**
- Panel Settings můžete vytvořit: **Assets****Create****UI Toolkit****Panel Settings Asset**
### 2. Připojení controlleru
1. Na stejný GameObject přidejte komponentu `MainMenuController`
2. Přiřaďte UIDocument komponentu do pole **UI Document**
3. Nastavte název herní scény v **Game Scene Name**
### 3. (Volitelné) Přidání zvuků
1. Přidejte **Audio Source** komponentu
2. Přiřaďte zvukové efekty pro tlačítka:
- Button Click Sound
- Button Hover Sound
## 🎨 Jak upravit styly (USS)
### Základní vlastnosti CSS/USS
USS používá syntax velmi podobnou CSS. Zde jsou nejčastější vlastnosti:
#### Layout & Spacing
```css
.my-element {
width: 300px; /* Šířka */
height: 50px; /* Výška */
margin: 10px; /* Vnější odsazení */
padding: 20px; /* Vnitřní odsazení */
flex-direction: row; /* row | column */
justify-content: center; /* center | flex-start | flex-end | space-between */
align-items: center; /* center | flex-start | flex-end | stretch */
}
```
#### Barvy & Pozadí
```css
.my-element {
background-color: rgb(76, 175, 80); /* RGB barva */
background-color: rgba(76, 175, 80, 0.5); /* RGB s průhledností */
background-image: url('project://database/Assets/Images/bg.png');
color: white; /* Barva textu */
opacity: 0.8; /* Průhlednost (0-1) */
}
```
#### Borders & Shadows
```css
.my-element {
border-width: 2px;
border-color: rgb(255, 255, 255);
border-radius: 8px; /* Zaoblené rohy */
/* Stíny v Unity - používají se přes shadow properties */
}
```
#### Typography
```css
.my-element {
font-size: 24px;
-unity-font-style: bold; /* normal | bold | italic | bold-and-italic */
-unity-text-align: middle-center; /* upper-left | upper-center | upper-right ... */
letter-spacing: 2px;
color: white;
}
```
#### Transitions & Animations
```css
.my-button {
transition-duration: 0.3s;
transition-property: background-color, scale;
}
.my-button:hover {
background-color: rgb(100, 200, 100);
scale: 1.1 1.1; /* X Y scale */
translate: 0 -5px; /* X Y translation */
rotate: 5deg; /* Rotation */
}
.my-button:active {
scale: 0.95 0.95;
}
```
### CSS Variables (Custom Properties)
V `:root` můžete definovat proměnné:
```css
:root {
--color-primary: rgb(76, 175, 80);
--spacing-md: 16px;
}
.button {
background-color: var(--color-primary);
padding: var(--spacing-md);
}
```
### Pseudo-třídy
Unity podporuje následující pseudo-třídy:
- `:hover` - Po najetí myší
- `:active` - Při kliknutí
- `:focus` - Při zaměření
- `:checked` - Pro toggle/checkbox (zaškrtnuté)
- `:disabled` - Pro zakázané elementy
### Užitečné Unity-specifické vlastnosti
```css
.element {
/* Display */
display: flex; /* flex | none */
visibility: hidden; /* visible | hidden */
/* Position */
position: absolute; /* relative | absolute */
/* Unity Text */
-unity-text-outline-width: 1px;
-unity-text-outline-color: black;
/* Background */
-unity-background-scale-mode: scale-to-fit; /* stretch-to-fill | scale-and-crop | scale-to-fit */
-unity-slice-left: 10; /* Pro 9-slice sprites */
}
```
## 💡 Tipy pro kvalitní UI
### 1. Konzistentní Design System
- Používejte **CSS proměnné** pro barvy, spacing, atd.
- Definujte paletu barev (primary, secondary, danger, success)
- Používejte konzistentní spacing (4px, 8px, 16px, 24px, ...)
### 2. Hierarchie a Layout
```
Container (flex-direction: column)
├─ Header (title, subtitle)
├─ Content (flex-grow: 1)
│ └─ Items (padding, margin)
└─ Footer (version, copyright)
```
### 3. Vizuální Feedback
- **Hover efekty**: Změna barvy, scale, shadow
- **Active stavy**: Scale down při kliknutí
- **Transitions**: Plynulé přechody (0.2-0.3s)
- **Disabled stavy**: Opacity 0.5, šedá barva
### 4. Responzivní Design
```css
.container {
width: 80%; /* Procenta z rodiče */
max-width: 800px; /* Maximální šířka */
min-width: 400px; /* Minimální šířka */
}
```
### 5. Accessibility
- Dostatečný kontrast textu (světlý text na tmavém pozadí)
- Viditelné focus stavy
- Dostatečně velké klikací oblasti (min. 44x44px)
## 🎯 Best Practices
### DO ✅
1. **Používejte třídy** místo inline stylů
2. **Organizujte styly** do sekcí s komentáři
3. **Používejte Flexbox** pro layout
4. **Testujte na různých rozlišeních**
5. **Používejte USS proměnné** pro opakující se hodnoty
### DON'T ❌
1. ❌ Nekopírujte stejné styly - použijte třídy
2. ❌ Nepřeužívejte `position: absolute`
3. ❌ Nepoužívejte pevné velikosti tam, kde není nutné
4. ❌ Nezapomeňte na hover a focus stavy
5. ❌ Nepoužívejte příliš mnoho animací najednou
## 🔧 Debugging UI
### 1. UI Debugger
V Unity editoru:
- **Window** → **UI Toolkit****Debugger**
- Vyberte váš UI Document
- Prohlížejte strukturu a živé styly
### 2. Inspector
- Klikněte na element v Debuggeru
- V pravém panelu vidíte všechny aplikované styly
- Můžete je dočasně měnit pro testování
### 3. Console Log
V C# můžete debugovat:
```csharp
var button = root.Q<Button>("MyButton");
Debug.Log($"Button found: {button != null}");
Debug.Log($"Button classes: {string.Join(", ", button.GetClasses())}");
```
## 📚 Další zdroje
### Oficiální dokumentace Unity
- [UI Toolkit Manual](https://docs.unity3d.com/Manual/UIElements.html)
- [USS Properties Reference](https://docs.unity3d.com/Manual/UIE-USS-Properties-Reference.html)
- [UXML Element Reference](https://docs.unity3d.com/Manual/UIE-ElementRef.html)
### CSS Základy
Protože USS je založeno na CSS, můžete využít:
- [MDN CSS Documentation](https://developer.mozilla.org/en-US/docs/Web/CSS)
- [CSS Flexbox Guide](https://css-tricks.com/snippets/css/a-guide-to-flexbox/)
### Unity Learn
- [UI Toolkit Tutorial](https://learn.unity.com/tutorial/ui-toolkit)
## 🎨 Doporučené Color Palettes
### Gamin Palette (Dark)
```css
--bg-dark: rgb(18, 18, 18);
--bg-medium: rgb(33, 33, 33);
--bg-light: rgb(48, 48, 48);
--accent: rgb(76, 175, 80); /* Green */
--accent-alt: rgb(33, 150, 243); /* Blue */
--danger: rgb(244, 67, 54); /* Red */
```
### Minimalist (Light)
```css
--bg-light: rgb(250, 250, 250);
--bg-medium: rgb(240, 240, 240);
--bg-dark: rgb(224, 224, 224);
--accent: rgb(96, 125, 139); /* Blue Grey */
--text-dark: rgb(33, 33, 33);
```
## 🚀 Rozšíření
### Přidání nového tlačítka
1. **V UXML**:
```xml
<ui:Button text="NEW BUTTON" name="NewButton" class="menu-button" />
```
2. **V C#**:
```csharp
private Button newButton;
private void InitializeMenuButtons()
{
newButton = root.Q<Button>("NewButton");
}
private void RegisterButtonEvents()
{
if (newButton != null)
{
newButton.clicked += OnNewButtonClicked;
AddHoverEffects(newButton);
}
}
private void OnNewButtonClicked()
{
Debug.Log("New button clicked!");
}
```
### Vlastní komponenta
Můžete vytvořit vlastní reusable komponenty v UXML:
```xml
<!-- CustomCard.uxml -->
<ui:UXML>
<ui:VisualElement class="card">
<ui:Label name="CardTitle" class="card-title" />
<ui:Label name="CardDescription" class="card-description" />
</ui:VisualElement>
</ui:UXML>
```
A použít je:
```xml
<ui:Template src="CustomCard.uxml" name="CardTemplate" />
<ui:Instance template="CardTemplate" />
```
---
## 📝 Poznámky
- USS nepodporuje všechny CSS vlastnosti (např. `box-shadow`)
- Animace jsou omezené - komplexní animace dělejte v C#
- Performance: USS je velmi rychlé, ale zbytečně neměňte styly každý frame
## 🤝 Podpora
Pokud narazíte na problém:
1. Zkontrolujte Unity Console pro chyby
2. Použijte UI Toolkit Debugger
3. Ověřte, že jsou správně přiřazené všechny reference
4. Zkontrolujte, zda jsou názvy elementů správně
---
**Vytvořeno pro Unity 2022.3+ s UI Toolkit**

7
UI/README.md.meta Normal file
View File

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

8
UI/Scripts.meta Normal file
View File

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

View File

@@ -0,0 +1,443 @@
using UnityEngine;
using UnityEngine.UIElements;
using UnityEngine.SceneManagement;
namespace MegaKoop.UI
{
/// <summary>
/// Controller pro Main Menu s UI Toolkit
/// </summary>
public class MainMenuController : MonoBehaviour
{
[Header("UI Document")]
[SerializeField] private UIDocument uiDocument;
[Header("Scene Names")]
[SerializeField] private string gameSceneName = "GameScene";
[Header("Audio")]
[SerializeField] private AudioSource audioSource;
[SerializeField] private AudioClip buttonClickSound;
[SerializeField] private AudioClip buttonHoverSound;
// Root element
private VisualElement root;
// Main Menu Elements
private Button newGameButton;
private Button continueButton;
private Button multiplayerButton;
private Button settingsButton;
private Button creditsButton;
private Button quitButton;
// Settings Panel Elements
private VisualElement settingsPanel;
private DropdownField qualityDropdown;
private Toggle fullscreenToggle;
private DropdownField resolutionDropdown;
private Slider masterVolumeSlider;
private Slider musicVolumeSlider;
private Slider sfxVolumeSlider;
private Button applyButton;
private Button backButton;
private void OnEnable()
{
// Získání UI Document
if (uiDocument == null)
uiDocument = GetComponent<UIDocument>();
root = uiDocument.rootVisualElement;
// Inicializace UI elementů
InitializeMenuButtons();
InitializeSettingsPanel();
// Registrace event handlerů
RegisterButtonEvents();
// Načtení nastavení
LoadSettings();
}
private void OnDisable()
{
// Odregistrování event handlerů
UnregisterButtonEvents();
}
#region Initialization
private void InitializeMenuButtons()
{
newGameButton = root.Q<Button>("NewGameButton");
continueButton = root.Q<Button>("ContinueButton");
multiplayerButton = root.Q<Button>("MultiplayerButton");
settingsButton = root.Q<Button>("SettingsButton");
creditsButton = root.Q<Button>("CreditsButton");
quitButton = root.Q<Button>("QuitButton");
// Kontrola, zda existuje uložená hra
continueButton.SetEnabled(HasSaveGame());
}
private void InitializeSettingsPanel()
{
settingsPanel = root.Q<VisualElement>("SettingsPanel");
// Graphics Settings
qualityDropdown = root.Q<DropdownField>("QualityDropdown");
fullscreenToggle = root.Q<Toggle>("FullscreenToggle");
resolutionDropdown = root.Q<DropdownField>("ResolutionDropdown");
// Audio Settings
masterVolumeSlider = root.Q<Slider>("MasterVolumeSlider");
musicVolumeSlider = root.Q<Slider>("MusicVolumeSlider");
sfxVolumeSlider = root.Q<Slider>("SFXVolumeSlider");
// Buttons
applyButton = root.Q<Button>("ApplyButton");
backButton = root.Q<Button>("BackButton");
// Setup dropdowns
SetupQualityDropdown();
SetupResolutionDropdown();
}
private void SetupQualityDropdown()
{
if (qualityDropdown == null) return;
var qualityNames = QualitySettings.names;
qualityDropdown.choices = new System.Collections.Generic.List<string>(qualityNames);
qualityDropdown.value = qualityNames[QualitySettings.GetQualityLevel()];
}
private void SetupResolutionDropdown()
{
if (resolutionDropdown == null) return;
var resolutions = new System.Collections.Generic.List<string>();
foreach (var resolution in Screen.resolutions)
{
resolutions.Add($"{resolution.width} x {resolution.height} @ {resolution.refreshRate}Hz");
}
resolutionDropdown.choices = resolutions;
resolutionDropdown.value = $"{Screen.currentResolution.width} x {Screen.currentResolution.height} @ {Screen.currentResolution.refreshRate}Hz";
}
#endregion
#region Event Registration
private void RegisterButtonEvents()
{
// Main Menu Buttons
if (newGameButton != null)
{
newGameButton.clicked += OnNewGameClicked;
AddHoverEffects(newGameButton);
}
if (continueButton != null)
{
continueButton.clicked += OnContinueClicked;
AddHoverEffects(continueButton);
}
if (multiplayerButton != null)
{
multiplayerButton.clicked += OnMultiplayerClicked;
AddHoverEffects(multiplayerButton);
}
if (settingsButton != null)
{
settingsButton.clicked += OnSettingsClicked;
AddHoverEffects(settingsButton);
}
if (creditsButton != null)
{
creditsButton.clicked += OnCreditsClicked;
AddHoverEffects(creditsButton);
}
if (quitButton != null)
{
quitButton.clicked += OnQuitClicked;
AddHoverEffects(quitButton);
}
// Settings Panel Buttons
if (applyButton != null)
{
applyButton.clicked += OnApplySettingsClicked;
AddHoverEffects(applyButton);
}
if (backButton != null)
{
backButton.clicked += OnBackFromSettingsClicked;
AddHoverEffects(backButton);
}
}
private void UnregisterButtonEvents()
{
if (newGameButton != null) newGameButton.clicked -= OnNewGameClicked;
if (continueButton != null) continueButton.clicked -= OnContinueClicked;
if (multiplayerButton != null) multiplayerButton.clicked -= OnMultiplayerClicked;
if (settingsButton != null) settingsButton.clicked -= OnSettingsClicked;
if (creditsButton != null) creditsButton.clicked -= OnCreditsClicked;
if (quitButton != null) quitButton.clicked -= OnQuitClicked;
if (applyButton != null) applyButton.clicked -= OnApplySettingsClicked;
if (backButton != null) backButton.clicked -= OnBackFromSettingsClicked;
}
private void AddHoverEffects(Button button)
{
button.RegisterCallback<MouseEnterEvent>(evt => OnButtonHover());
}
#endregion
#region Button Callbacks
private void OnNewGameClicked()
{
PlayButtonClickSound();
Debug.Log("Starting New Game...");
// Vymazání uložené hry
PlayerPrefs.DeleteKey("SaveGame");
// Načtení herní scény
LoadGameScene();
}
private void OnContinueClicked()
{
PlayButtonClickSound();
Debug.Log("Continuing Game...");
// Načtení uložené hry
LoadSaveGame();
// Načtení herní scény
LoadGameScene();
}
private void OnMultiplayerClicked()
{
PlayButtonClickSound();
Debug.Log("Opening Multiplayer Menu...");
// TODO: Implementovat multiplayer menu
}
private void OnSettingsClicked()
{
PlayButtonClickSound();
Debug.Log("Opening Settings...");
ShowSettingsPanel();
}
private void OnCreditsClicked()
{
PlayButtonClickSound();
Debug.Log("Showing Credits...");
// TODO: Implementovat credits screen
}
private void OnQuitClicked()
{
PlayButtonClickSound();
Debug.Log("Quitting Game...");
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
private void OnApplySettingsClicked()
{
PlayButtonClickSound();
ApplySettings();
SaveSettings();
Debug.Log("Settings Applied!");
}
private void OnBackFromSettingsClicked()
{
PlayButtonClickSound();
HideSettingsPanel();
}
private void OnButtonHover()
{
PlayButtonHoverSound();
}
#endregion
#region Settings Management
private void ShowSettingsPanel()
{
if (settingsPanel != null)
{
settingsPanel.RemoveFromClassList("hidden");
}
}
private void HideSettingsPanel()
{
if (settingsPanel != null)
{
settingsPanel.AddToClassList("hidden");
}
}
private void ApplySettings()
{
// Graphics Settings
if (qualityDropdown != null)
{
int qualityIndex = qualityDropdown.index;
QualitySettings.SetQualityLevel(qualityIndex);
}
if (fullscreenToggle != null)
{
Screen.fullScreen = fullscreenToggle.value;
}
if (resolutionDropdown != null && resolutionDropdown.index >= 0)
{
var resolution = Screen.resolutions[resolutionDropdown.index];
Screen.SetResolution(resolution.width, resolution.height, Screen.fullScreen);
}
// Audio Settings
if (masterVolumeSlider != null)
{
AudioListener.volume = masterVolumeSlider.value / 100f;
}
// TODO: Implementovat music a SFX volume přes audio mixer
}
private void SaveSettings()
{
PlayerPrefs.SetInt("QualityLevel", QualitySettings.GetQualityLevel());
PlayerPrefs.SetInt("Fullscreen", Screen.fullScreen ? 1 : 0);
PlayerPrefs.SetInt("ResolutionWidth", Screen.currentResolution.width);
PlayerPrefs.SetInt("ResolutionHeight", Screen.currentResolution.height);
if (masterVolumeSlider != null)
PlayerPrefs.SetFloat("MasterVolume", masterVolumeSlider.value);
if (musicVolumeSlider != null)
PlayerPrefs.SetFloat("MusicVolume", musicVolumeSlider.value);
if (sfxVolumeSlider != null)
PlayerPrefs.SetFloat("SFXVolume", sfxVolumeSlider.value);
PlayerPrefs.Save();
}
private void LoadSettings()
{
// Graphics Settings
if (qualityDropdown != null)
{
int qualityLevel = PlayerPrefs.GetInt("QualityLevel", QualitySettings.GetQualityLevel());
qualityDropdown.index = qualityLevel;
}
if (fullscreenToggle != null)
{
fullscreenToggle.value = PlayerPrefs.GetInt("Fullscreen", 1) == 1;
}
// Audio Settings
if (masterVolumeSlider != null)
{
float masterVolume = PlayerPrefs.GetFloat("MasterVolume", 100f);
masterVolumeSlider.value = masterVolume;
AudioListener.volume = masterVolume / 100f;
}
if (musicVolumeSlider != null)
{
musicVolumeSlider.value = PlayerPrefs.GetFloat("MusicVolume", 80f);
}
if (sfxVolumeSlider != null)
{
sfxVolumeSlider.value = PlayerPrefs.GetFloat("SFXVolume", 100f);
}
}
#endregion
#region Game Management
private bool HasSaveGame()
{
return PlayerPrefs.HasKey("SaveGame");
}
private void LoadSaveGame()
{
// TODO: Implementovat načítání save game
string saveData = PlayerPrefs.GetString("SaveGame", "");
Debug.Log($"Loading save game: {saveData}");
}
private void LoadGameScene()
{
// Načtení herní scény pomocí async loading
StartCoroutine(LoadSceneAsync(gameSceneName));
}
private System.Collections.IEnumerator LoadSceneAsync(string sceneName)
{
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);
while (!asyncLoad.isDone)
{
// Zde můžete zobrazit loading bar
float progress = Mathf.Clamp01(asyncLoad.progress / 0.9f);
Debug.Log($"Loading progress: {progress * 100}%");
yield return null;
}
}
#endregion
#region Audio
private void PlayButtonClickSound()
{
if (audioSource != null && buttonClickSound != null)
{
audioSource.PlayOneShot(buttonClickSound);
}
}
private void PlayButtonHoverSound()
{
if (audioSource != null && buttonHoverSound != null)
{
audioSource.PlayOneShot(buttonHoverSound, 0.5f);
}
}
#endregion
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 9968fc9f33c51a14292c6cac00cff4b3