158 lines
4.1 KiB
C#
158 lines
4.1 KiB
C#
using Cysharp.Threading.Tasks;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
public class Instruction : MonoBehaviour
|
|
{
|
|
[Header("Exit progress")]
|
|
[SerializeField] private CanvasGroup progressGroup;
|
|
[SerializeField] private Image bar;
|
|
private bool groupVisible = false;
|
|
private float progress;
|
|
private CancellationTokenSource exitBarCts;
|
|
|
|
[Header("Instruction")]
|
|
[SerializeField] TextMeshProUGUI instructionLabel;
|
|
[SerializeField] CanvasGroup UpLeft, UpRight, DownLeft, DownRight, LabelCG;
|
|
[SerializeField] List<InstructionBlock> instructions;
|
|
private CancellationTokenSource instructionCts;
|
|
private Dictionary<InSignal, CanvasGroup> buttons;
|
|
|
|
public void SetProgress(float percent) => progress = percent;
|
|
|
|
public void Init()
|
|
{
|
|
buttons = new()
|
|
{
|
|
[InSignal.UpLeft] = UpLeft,
|
|
[InSignal.UpRight] = UpRight,
|
|
[InSignal.DownLeft] = DownLeft,
|
|
[InSignal.DownRight] = DownRight
|
|
};
|
|
|
|
instructionCts = new();
|
|
StartInstructionsSequence(instructionCts.Token).Forget();
|
|
|
|
SetProgress(0);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
ProgressBarProcess();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
instructionCts?.Cancel();
|
|
instructionCts?.Dispose();
|
|
|
|
exitBarCts?.Cancel();
|
|
exitBarCts?.Dispose();
|
|
}
|
|
|
|
private void ProgressBarProcess()
|
|
{
|
|
if (!groupVisible && progress > 0)
|
|
{
|
|
exitBarCts?.Cancel();
|
|
exitBarCts?.Dispose();
|
|
exitBarCts = new();
|
|
|
|
SetVisibility(true, exitBarCts.Token).Forget();
|
|
}
|
|
if (groupVisible && progress == 0)
|
|
{
|
|
exitBarCts?.Cancel();
|
|
exitBarCts?.Dispose();
|
|
exitBarCts = new();
|
|
|
|
SetVisibility(false, exitBarCts.Token).Forget();
|
|
}
|
|
|
|
bar.fillAmount = progress;
|
|
}
|
|
|
|
private async UniTask SetVisibility(bool visible, CancellationToken token)
|
|
{
|
|
float targetAlpha = visible ? 1 : 0;
|
|
groupVisible = visible;
|
|
|
|
while (progressGroup.alpha != targetAlpha && !token.IsCancellationRequested)
|
|
{
|
|
progressGroup.alpha = Mathf.MoveTowards(progressGroup.alpha, targetAlpha, Time.deltaTime);
|
|
await UniTask.Yield(PlayerLoopTiming.Update, token);
|
|
}
|
|
}
|
|
|
|
private async UniTask StartInstructionsSequence(CancellationToken token)
|
|
{
|
|
if (instructions == null) return;
|
|
if (instructions.Count == 0) return;
|
|
|
|
int instructionIndex = 0;
|
|
while (!token.IsCancellationRequested)
|
|
{
|
|
await ShowInstruction(instructions[instructionIndex], token);
|
|
instructionIndex = (instructionIndex + 1) % instructions.Count;
|
|
}
|
|
}
|
|
|
|
private async UniTask ShowInstruction(InstructionBlock instruction, CancellationToken token)
|
|
{
|
|
HideInstruction();
|
|
instructionLabel.text = instruction.text;
|
|
|
|
|
|
float t = 0;
|
|
//Зажигаем
|
|
while (!token.IsCancellationRequested && t < 1)
|
|
{
|
|
t += Time.deltaTime;
|
|
t = Mathf.Min(t, 1);
|
|
|
|
foreach (var signal in instruction.signals)
|
|
buttons[signal].alpha = t;
|
|
LabelCG.alpha = t;
|
|
|
|
await UniTask.Yield(token);
|
|
}
|
|
|
|
await UniTask.Delay(1000, cancellationToken: token);
|
|
t = 0;
|
|
|
|
//Тушим
|
|
while (!token.IsCancellationRequested && t < 1)
|
|
{
|
|
t += Time.deltaTime;
|
|
t = Mathf.Min(t, 1);
|
|
|
|
float oneMinus = 1 - t;
|
|
foreach (var signal in instruction.signals)
|
|
buttons[signal].alpha = oneMinus;
|
|
LabelCG.alpha = oneMinus;
|
|
|
|
await UniTask.Yield(token);
|
|
}
|
|
}
|
|
|
|
private void HideInstruction()
|
|
{
|
|
UpLeft.alpha = 0;
|
|
UpRight.alpha = 0;
|
|
DownLeft.alpha = 0;
|
|
DownRight.alpha = 0;
|
|
|
|
LabelCG.alpha = 0;
|
|
}
|
|
|
|
[Serializable]
|
|
private class InstructionBlock
|
|
{
|
|
public List<InSignal> signals;
|
|
[TextArea] public string text;
|
|
}
|
|
} |