Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
- завершен спринт 24 марта - 2 апреля с опережением плана и закрытием задач раньше срока - расширена и стабилизирована система призов: добавлены и доработаны QR-tier конфиги, новые типы и модели данных, сохранение `qrCodes` в `prizes.json`, fallback-логика и синхронизация через `PrizeSystemManager`, `PrizeDatabase` и `LevelPrizeConfig` - переработан flow настройки QR-призов: добавлены `QRCodeSettingsModal` и связанный UI-код, разнесены короткий текст приза и полный текст сообщения, добавлены шаблоны форматирования, корректная подстановка текста в QR и в UI-модалках, а также сохранение конфигурации между запусками - доработан flow суперприза и текстовых настроек: добавлены fallback-правила показа, корректная обработка пустых строк и строк из одних пробелов, обновлены binders и показ текста в меню - реализована и обновлена отдельная настройка витрины: добавлена `PrizeStandSettingsModal`, обновлена навигация строк, логика выбора ячейки и порогов очков, циклический выбор ячеек, ускорение изменения значений и исправления для keyboard/gamepad UX - доработана игровая модалка витрины `PrizeStandModal`: добавлен вывод очков игрока, форматируемый текст счета, улучшено отображение ячеек и связанная логика выбора приза - исправлен подсчет очков и интеграция с prize flow: `ScoreSystem` переведен на событийное обновление текущего счета, добавлены `CurrentScore`, `CurrentScoreChanged` и корректный display score, витрина и связанные UI-элементы теперь получают актуальные очки, а не нулевые или несвоевременные preview-значения - переработаны модальные окна и навигация UI: улучшены `Modal`, `ModalManager`, `UIRowPointer`, `RulesModal`, `QRCodeModal`, `PrizeStandModal`, `LevelPrizeSettingsModal` и др., чтобы фокус, указатель и submit работали консистентно без мыши - обновлен win/prize UI: доработаны `WinBannerController`, `GameEndUIController`, `MainMenu`, `QRCodeUIController`, `TopPanelTextController` и настройки UI, улучшены тексты баннеров, отображение призов и итогового счета - обновлены сцены и ассеты под новый flow: `MainMenu`, `Level UI`, prefab'ы строк настроек и кнопок, глобальные префабы, шрифты TMP, иконки, recovery-данные и ресурсы UI - добавлены вспомогательные UI-компоненты и служебные скрипты: `ButtonTextFocusColor`, `SelectableDescriptionTarget`, `QRTier` и другие изменения, поддерживающие новый конфигурируемый prize UI
99 lines
3.8 KiB
C#
99 lines
3.8 KiB
C#
using System.Collections;
|
|
using UnityEngine;
|
|
|
|
using RR.Game2D.Behaviour;
|
|
using RR.Game2D.Behaviour.ScriptableObjects;
|
|
using RR.Game2D.Core.Managers;
|
|
using UnityEngine.VFX;
|
|
|
|
namespace RR.Game2D.Animations
|
|
{
|
|
public class EnemyAnimationEvents : MonoBehaviour, CreatureAnimationEvents
|
|
{
|
|
[SerializeField] private VisualEffectAsset deathVFX;
|
|
[SerializeField] private Vector3 deathVFXOffset = Vector3.zero;
|
|
|
|
private SFXAsset _stepSounds;
|
|
private SFXAsset _hurtSounds;
|
|
private Vector3 _vfxSpawnPoint;
|
|
private bool _deathScoreRegistered;
|
|
|
|
private void Awake()
|
|
{
|
|
// Загружаем и кэшируем звуковые эффекты из контроллера врага
|
|
UpdateSFX();
|
|
Collider2D col = GetComponent<Collider2D>();
|
|
// Учитываем поворот объекта при вычислении смещения
|
|
Vector3 rotatedOffset = transform.rotation * deathVFXOffset;
|
|
_vfxSpawnPoint = (col ? col.bounds.center : transform.position) + rotatedOffset;
|
|
}
|
|
|
|
public void UpdateSFX()
|
|
{
|
|
// Кэшируем ссылки на звуковые эффекты из контроллера врага
|
|
EnemyController controller = GetComponent<EnemyController>();
|
|
_stepSounds = controller.sfxAsset.stepSounds;
|
|
_hurtSounds = controller.sfxAsset.hurtSounds;
|
|
}
|
|
|
|
public void OnDeath() {}
|
|
|
|
public void OnJump() {}
|
|
|
|
public void OnDeathBegin()
|
|
{
|
|
// Проигрываем звук получения урона
|
|
if (_hurtSounds && _hurtSounds.soundEffects.Length > 0)
|
|
GameManager.Instance.Audio.PlayRandomSfxAt(_hurtSounds.soundEffects, transform.position);
|
|
|
|
// Переводим врага на слой "No Collision"
|
|
gameObject.layer = LayerMask.NameToLayer("No Collision");
|
|
|
|
// Получаем компоненты
|
|
Rigidbody2D rb = GetComponent<Rigidbody2D>();
|
|
Collider2D col = GetComponent<Collider2D>();
|
|
EnemyController controller = GetComponent<EnemyController>();
|
|
EnemyFireScript fireScript = GetComponent<EnemyFireScript>();
|
|
|
|
// Отключаем скрипты и коллайдер
|
|
if (controller) controller.enabled = false;
|
|
if (fireScript) fireScript.enabled = false;
|
|
if (col)
|
|
{
|
|
// Учитываем поворот объекта при вычислении смещения
|
|
Vector3 rotatedOffset = transform.rotation * deathVFXOffset;
|
|
_vfxSpawnPoint = col.bounds.center + rotatedOffset;
|
|
|
|
col.enabled = false;
|
|
}
|
|
if (!rb) return;
|
|
|
|
// Останавливаем физику
|
|
rb.linearVelocity = Vector2.zero;
|
|
rb.bodyType = RigidbodyType2D.Kinematic;
|
|
}
|
|
|
|
public void OnDeathEnd()
|
|
{
|
|
if (!_deathScoreRegistered)
|
|
{
|
|
ScoreSystem.Instance?.RegisterEnemyKilled();
|
|
_deathScoreRegistered = true;
|
|
}
|
|
|
|
// Создаем визуальный эффект смерти
|
|
if (deathVFX) VFXPool.Instance.Spawn(deathVFX, _vfxSpawnPoint, 1f);
|
|
|
|
// Уничтожаем врага
|
|
Destroy(gameObject);
|
|
}
|
|
|
|
public void OnStep()
|
|
{
|
|
// Проигрываем звук шага
|
|
if (_stepSounds && _stepSounds.soundEffects.Length > 0)
|
|
GameManager.Instance.Audio.PlayRandomSfxAt(_stepSounds.soundEffects, transform.position);
|
|
}
|
|
}
|
|
}
|