sea-battle-vr/Assets/Scripts/Gameplay/ReplicasSystem.cs

86 lines
2.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using Cysharp.Threading.Tasks;
using System.Threading;
using System;
using System.Collections.Concurrent;
public class ReplicasSystem : MonoBehaviour
{
[SerializeField] AudioSource audioSource;
[SerializeField] float delay = 0.5f;
private bool initialized = false;
private ConcurrentQueue<Replica> replicas;
public void Init()
{
if (initialized)
{
Debug.LogWarning("Попытка повторной инициализации системы", this);
return;
}
if (audioSource == null)
{
Debug.LogError("Не установлен AudioSource", this);
return;
}
replicas = new ConcurrentQueue<Replica>();
var token = this.GetCancellationTokenOnDestroy();
Process(token).Forget();
initialized = true;
}
public void EnqueueReplica(Replica replica)
{
if (!initialized) return;
var handledReplica = replica;
if (handledReplica.clip == null) return;
if (UnityEngine.Random.Range(0f, 1f) < handledReplica.probability)
return;
if (handledReplica.playParallel)
{
audioSource.PlayOneShot(handledReplica.clip);
return;
}
handledReplica.creationTime = Time.time;
replicas.Enqueue(handledReplica);
}
private async UniTask Process(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
if (replicas.TryDequeue(out Replica replica))
{
bool replicaIsFresh = Time.time - replica.creationTime <= replica.lifetime;
if (replicaIsFresh)
{
audioSource.PlayOneShot(replica.clip);
await UniTask.Delay(TimeSpan.FromSeconds(replica.clip.length + delay), cancellationToken: token);
continue;
}
}
await UniTask.Yield();
}
}
[System.Serializable]
public struct Replica
{
public AudioClip clip;
public float lifetime;
public bool playParallel;
[Range(0,1)] public float probability;
[HideInInspector] public float creationTime;
}
}