Подробный список изменений: - Добавлено файловое логирование игровых сессий в game.log и расширена диагностика COM-подключений. - Подключен native COM transport с fallback-логикой для IL2CPP и добавлен плагин ComNative.dll. - Исправлена логика one-way платформ, чтобы игрок проходил сквозь платформы при нахождении ниже их верхней точки. - Переработана компоновка gameplay HUD: верхние плашки выровнены, левая уменьшена, центральная плашка очков центрирована и масштабирована. - Добавлена общая выдача призов через хоппер с командами запуска/остановки мотора и ожиданием датчика. - Подключен сервисный тест хоппера в настройках и обновлены связанные тесты. - Добавлены скриншоты визуальной проверки HUD.
88 lines
3.1 KiB
C#
88 lines
3.1 KiB
C#
using System;
|
||
using System.Threading;
|
||
using Cysharp.Threading.Tasks;
|
||
using UnityEngine.Events;
|
||
|
||
namespace DanroJump.Hardware.Com
|
||
{
|
||
/// <summary>
|
||
/// Единая процедура выдачи капсулы через хоппер: запуск мотора, ожидание датчика и остановка.
|
||
/// </summary>
|
||
public static class ComHopperDispenser
|
||
{
|
||
public const string StartMotorCommand = "301";
|
||
public const string StopMotorCommand = "300";
|
||
public const int DefaultTimeoutSeconds = 10;
|
||
|
||
public static UniTask<ComHopperDispenseResult> DispenseAsync(
|
||
IComSystem com,
|
||
CancellationToken cancellationToken = default)
|
||
{
|
||
return DispenseAsync(com, TimeSpan.FromSeconds(DefaultTimeoutSeconds), cancellationToken);
|
||
}
|
||
|
||
public static async UniTask<ComHopperDispenseResult> DispenseAsync(
|
||
IComSystem com,
|
||
TimeSpan timeout,
|
||
CancellationToken cancellationToken = default)
|
||
{
|
||
if (com == null)
|
||
{
|
||
return ComHopperDispenseResult.Failure("COM-система недоступна.");
|
||
}
|
||
|
||
if (!com.IsRunning)
|
||
{
|
||
return ComHopperDispenseResult.Failure("COM-система не запущена.");
|
||
}
|
||
|
||
if (!com.SendToMain(StartMotorCommand))
|
||
{
|
||
return ComHopperDispenseResult.Failure("Не удалось отправить команду запуска хоппера.");
|
||
}
|
||
|
||
var sensorTriggered = new UniTaskCompletionSource();
|
||
UnityAction onTriggered = () => sensorTriggered.TrySetResult();
|
||
com.HopperSensorTriggered.AddListener(onTriggered);
|
||
|
||
try
|
||
{
|
||
var winner = await UniTask.WhenAny(
|
||
sensorTriggered.Task,
|
||
UniTask.Delay(timeout, DelayType.Realtime, PlayerLoopTiming.Update, cancellationToken));
|
||
|
||
return winner == 0
|
||
? ComHopperDispenseResult.Success("Капсула выдана успешно.")
|
||
: ComHopperDispenseResult.Failure($"Датчик хоппера не сработал за {timeout.TotalSeconds:0.#} сек.");
|
||
}
|
||
finally
|
||
{
|
||
com.HopperSensorTriggered.RemoveListener(onTriggered);
|
||
com.SendToMain(StopMotorCommand);
|
||
}
|
||
}
|
||
}
|
||
|
||
public readonly struct ComHopperDispenseResult
|
||
{
|
||
private ComHopperDispenseResult(bool isSuccess, string message)
|
||
{
|
||
IsSuccess = isSuccess;
|
||
Message = message ?? string.Empty;
|
||
}
|
||
|
||
public bool IsSuccess { get; }
|
||
public string Message { get; }
|
||
|
||
public static ComHopperDispenseResult Success(string message)
|
||
{
|
||
return new ComHopperDispenseResult(true, message);
|
||
}
|
||
|
||
public static ComHopperDispenseResult Failure(string message)
|
||
{
|
||
return new ComHopperDispenseResult(false, message);
|
||
}
|
||
}
|
||
}
|