- Добавлен асинхронный процесс аппаратной выдачи физических призов (хоппер и витрина) в GameplayHudController. - Реализована блокировка выдачи по 10-секундному таймауту датчика хоппера с гарантированной отправкой команды отключения двигателя '300'. - Реализован автоматический таймаут неактивности на экране QR-кода с последующим переходом в главное меню. - Расширен сервис статистики PrizeSessionStateService новыми долгосрочными счетчиками (сыгранные игры, очки, монеты, сбои связи COM, физ. выдачи и ошибки). - Обновлен построитель сводки статистики в меню настроек для отображения новых счетчиков и списка последних 5 сессий. - Написаны EditMode тесты для проверки инкремента счетчиков и запуска выдачи призов.
77 lines
2.3 KiB
C#
77 lines
2.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Audio;
|
|
|
|
namespace DanroJump.Audio
|
|
{
|
|
/// <summary>
|
|
/// Описывает набор клипов и параметры воспроизведения для одного игрового события.
|
|
/// </summary>
|
|
[Serializable]
|
|
public sealed class GameAudioClipBinding
|
|
{
|
|
[SerializeField] private GameAudioEvent eventId;
|
|
[SerializeField] private GameAudioChannel channel = GameAudioChannel.Sfx;
|
|
[SerializeField] private AudioMixerGroup outputGroupOverride;
|
|
[SerializeField] private AudioClip[] clips = Array.Empty<AudioClip>();
|
|
[SerializeField] [Range(0f, 1f)] private float volume = 1f;
|
|
[SerializeField] private Vector2 pitchRange = Vector2.one;
|
|
[SerializeField] private bool spatial;
|
|
|
|
public GameAudioEvent EventId => eventId;
|
|
|
|
public GameAudioChannel Channel => channel;
|
|
|
|
public AudioMixerGroup OutputGroupOverride => outputGroupOverride;
|
|
|
|
public IReadOnlyList<AudioClip> Clips => clips;
|
|
|
|
public float Volume => Mathf.Clamp01(volume);
|
|
|
|
public bool Spatial => spatial;
|
|
|
|
public bool HasClip => clips != null && clips.Length > 0 && clips[0] != null;
|
|
|
|
public float RandomPitch => Mathf.Clamp(
|
|
UnityEngine.Random.Range(Mathf.Min(pitchRange.x, pitchRange.y), Mathf.Max(pitchRange.x, pitchRange.y)),
|
|
0.05f,
|
|
3f);
|
|
|
|
public AudioClip GetRandomClip()
|
|
{
|
|
if (clips == null || clips.Length == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var firstValidClip = default(AudioClip);
|
|
for (var index = 0; index < clips.Length; index++)
|
|
{
|
|
if (clips[index] == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
firstValidClip ??= clips[index];
|
|
}
|
|
|
|
if (firstValidClip == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
for (var attempt = 0; attempt < clips.Length; attempt++)
|
|
{
|
|
var clip = clips[UnityEngine.Random.Range(0, clips.Length)];
|
|
if (clip != null)
|
|
{
|
|
return clip;
|
|
}
|
|
}
|
|
|
|
return firstValidClip;
|
|
}
|
|
}
|
|
}
|