86 lines
2.2 KiB
C#
86 lines
2.2 KiB
C#
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;
|
||
}
|
||
} |