Second commit
This commit is contained in:
commit
36840f3ad4
999 files changed
+61364
No files matched your search
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using Code.Infrastructure.Generators;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
|
||||
namespace Code.Infrastructure.Particles
|
||||
{
|
||||
[CreateAssetMenu(fileName = "ParticleInfo", menuName = "Configs/Particles/ParticleInfo")]
|
||||
[Config("Configs/Particles/ParticleInfo", true)]
|
||||
public class ParticleInfo : ScriptableObject
|
||||
{
|
||||
public AssetReference particleSystem;
|
||||
public int particleId;
|
||||
public ParticlePartition particlePartition;
|
||||
public int CountInPool;
|
||||
public ParticlePartitionIDPair PartitionIDPair;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct ParticlePartitionIDPair : IEquatable<ParticlePartitionIDPair>
|
||||
{
|
||||
public ParticlePartition ParticlePartition;
|
||||
public int ID;
|
||||
|
||||
public ParticlePartitionIDPair(ParticlePartition particlePartition, int id)
|
||||
{
|
||||
ParticlePartition = particlePartition;
|
||||
ID = id;
|
||||
}
|
||||
|
||||
public bool Equals(ParticlePartitionIDPair other)
|
||||
{
|
||||
return ParticlePartition == other.ParticlePartition && ID == other.ID;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is ParticlePartitionIDPair other && Equals(other);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine((int)ParticlePartition, ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b7578a949deb96ef808e8b285d8e68e
|
||||
@@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Code.Infrastructure.Configs;
|
||||
using Code.Infrastructure.Utils;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
|
||||
namespace Code.Infrastructure.Particles
|
||||
{
|
||||
public interface IParticleLoader
|
||||
{
|
||||
UniTask LoadParticleSystems(ParticlePartition partition);
|
||||
void ReleaseParticles(ParticlePartition partition);
|
||||
void Dispose();
|
||||
}
|
||||
|
||||
public interface IParticleLoaderInitializer
|
||||
{
|
||||
UniTask LoadConfigs();
|
||||
}
|
||||
|
||||
public class ParticleLoader : IParticleLoader, IParticleLoaderInitializer, IDisposable
|
||||
{
|
||||
private readonly string _label;
|
||||
private Dictionary<ParticlePartition, Dictionary<int, ParticleInfo>> ParticleInfos { get; } = new();
|
||||
|
||||
private readonly Dictionary<ParticlePartition, Dictionary<int, AsyncOperationHandle<GameObject>>>
|
||||
_particleSystemHandles = new();
|
||||
|
||||
private AsyncOperationHandle<IList<ParticleInfo>> _configsHandle;
|
||||
|
||||
private readonly IParticlePoolManagerForFabric _poolManagerForFabric;
|
||||
|
||||
public ParticleLoader(IConfigLocator configLocator, IParticlePoolManagerForFabric poolManagerForFabric)
|
||||
{
|
||||
_poolManagerForFabric = poolManagerForFabric;
|
||||
_label = configLocator.TryGetManyConfigAssetReferences<ParticleInfo>();
|
||||
|
||||
for (var i = 0; i < typeof(ParticlePartition).GetEnumValues().Length; i++)
|
||||
{
|
||||
ParticleInfos.Add((ParticlePartition)i, new Dictionary<int, ParticleInfo>());
|
||||
_particleSystemHandles.Add((ParticlePartition)i,
|
||||
new Dictionary<int, AsyncOperationHandle<GameObject>>());
|
||||
}
|
||||
}
|
||||
|
||||
public async UniTask LoadConfigs()
|
||||
{
|
||||
if (!await AddressablesUtilities.CheckLabelExists(_label)) return;
|
||||
|
||||
_configsHandle = Addressables.LoadAssetsAsync<ParticleInfo>(_label);
|
||||
|
||||
await _configsHandle.ToUniTask();
|
||||
|
||||
foreach (var config in _configsHandle.Result)
|
||||
ParticleInfos[config.particlePartition].Add(config.particleId, config);
|
||||
}
|
||||
|
||||
public async UniTask LoadParticleSystems(ParticlePartition partition)
|
||||
{
|
||||
foreach (var particleInfo in ParticleInfos[partition])
|
||||
if (!_particleSystemHandles[partition].ContainsKey(particleInfo.Key))
|
||||
_particleSystemHandles[partition].Add(particleInfo.Key,
|
||||
Addressables.LoadAssetAsync<GameObject>(particleInfo.Value.particleSystem));
|
||||
else
|
||||
_particleSystemHandles[partition][particleInfo.Key] =
|
||||
Addressables.LoadAssetAsync<GameObject>(particleInfo.Value.particleSystem);
|
||||
|
||||
foreach (var handle in _particleSystemHandles[partition])
|
||||
await handle.Value.ToUniTask();
|
||||
|
||||
foreach (var particleInfo in ParticleInfos[partition])
|
||||
_poolManagerForFabric.CreatePoolOfParticles(
|
||||
particleInfo.Value,
|
||||
_particleSystemHandles[partition][particleInfo.Key].Result.GetComponent<ParticleSystem>()
|
||||
);
|
||||
}
|
||||
|
||||
public void ReleaseParticles(ParticlePartition partition)
|
||||
{
|
||||
if (_particleSystemHandles[partition].Count == 0) return;
|
||||
|
||||
foreach (var handle in _particleSystemHandles[partition])
|
||||
{
|
||||
_poolManagerForFabric.DeletePoolOfParticles(partition, handle.Key);
|
||||
Addressables.Release(handle.Value);
|
||||
}
|
||||
|
||||
_particleSystemHandles[partition].Clear();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var handles in _particleSystemHandles)
|
||||
{
|
||||
foreach (var handle in handles.Value)
|
||||
{
|
||||
_poolManagerForFabric.DeletePoolOfParticles(handles.Key, handle.Key);
|
||||
handle.Value.Release();
|
||||
}
|
||||
}
|
||||
|
||||
_particleSystemHandles.Clear();
|
||||
|
||||
if (_configsHandle.IsValid()) _configsHandle.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e0558ddc52d6d69e825887b8be94f10
|
||||
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Reflex.Attributes;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Pool;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Code.Infrastructure.Particles
|
||||
{
|
||||
public class ParticlePool
|
||||
{
|
||||
public IObjectPool<ParticleSystem> Pool;
|
||||
|
||||
private ParticleInfo _particleInfoConfig;
|
||||
private ParticleSystem _particleSystemPrefab;
|
||||
|
||||
public ParticlePool(ParticleInfo particleInfoConfig, ParticleSystem particleSystemPrefab)
|
||||
{
|
||||
_particleSystemPrefab = particleSystemPrefab;
|
||||
_particleInfoConfig = particleInfoConfig;
|
||||
|
||||
Pool = new ObjectPool<ParticleSystem>(
|
||||
createFunc: CreateItem,
|
||||
// actionOnGet: OnGet,
|
||||
actionOnRelease: OnRelease,
|
||||
actionOnDestroy: OnDestroyItem,
|
||||
collectionCheck: true, // helps catch double-release mistakes
|
||||
defaultCapacity: particleInfoConfig.CountInPool,
|
||||
maxSize: 20
|
||||
);
|
||||
}
|
||||
|
||||
public ParticleSystem Get() => Pool.Get();
|
||||
public void Release(ParticleSystem particleSystem) => Pool.Release(particleSystem);
|
||||
|
||||
// Creates a new pooled GameObject the first time (and whenever the pool needs more).
|
||||
private ParticleSystem CreateItem()
|
||||
{
|
||||
var particleSystem = Object
|
||||
.Instantiate(_particleSystemPrefab) // Он уже загружен
|
||||
.GetComponent<ParticleSystem>();
|
||||
particleSystem.name = "PooledParticleSystem";
|
||||
Object.DontDestroyOnLoad(particleSystem);
|
||||
return particleSystem;
|
||||
}
|
||||
|
||||
// Called when an item is taken from the pool.
|
||||
private void OnGet(ParticleSystem source)
|
||||
{
|
||||
// Настроить если надо
|
||||
}
|
||||
|
||||
// Called when an item is returned to the pool.
|
||||
private void OnRelease(ParticleSystem particleSystem)
|
||||
{
|
||||
if (!particleSystem) return;
|
||||
|
||||
particleSystem.Stop();
|
||||
|
||||
// Настроить если надо
|
||||
|
||||
}
|
||||
|
||||
// Called when the pool decides to destroy an item (e.g., above max size).
|
||||
private void OnDestroyItem(ParticleSystem source)
|
||||
{
|
||||
Object.Destroy(source.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public interface IParticlePoolManagerForService
|
||||
{
|
||||
ParticleSystem GetParticleSystem(ParticlePartition partition, int id);
|
||||
void ReleaseParticleSystem(ParticlePartition partition, int id, ParticleSystem particleSystem);
|
||||
}
|
||||
|
||||
public interface IParticlePoolManagerForFabric
|
||||
{
|
||||
void CreatePoolOfParticles(ParticleInfo particleInfoConfig, ParticleSystem particleSystemPrefab);
|
||||
void DeletePoolOfParticles(ParticlePartition partition, int id);
|
||||
}
|
||||
|
||||
public class ParticlePoolManager : IParticlePoolManagerForService, IParticlePoolManagerForFabric
|
||||
{
|
||||
// The pool holds plain GameObjects (you can swap this for any component type).
|
||||
private Dictionary<ParticlePartition, Dictionary<int, ParticlePool>> _poolDictionary = new();
|
||||
|
||||
public void CreatePoolOfParticles(ParticleInfo particleInfoConfig, ParticleSystem particleSystemPrefab)
|
||||
{
|
||||
if(!_poolDictionary.ContainsKey(particleInfoConfig.particlePartition))
|
||||
_poolDictionary[particleInfoConfig.particlePartition] = new();
|
||||
|
||||
_poolDictionary[particleInfoConfig.particlePartition]
|
||||
.Add(particleInfoConfig.particleId, new ParticlePool(particleInfoConfig, particleSystemPrefab));
|
||||
}
|
||||
public void DeletePoolOfParticles(ParticlePartition partition, int id)
|
||||
{
|
||||
_poolDictionary[partition][id].Pool.Clear();
|
||||
_poolDictionary[partition].Remove(id);
|
||||
}
|
||||
|
||||
public ParticleSystem GetParticleSystem(ParticlePartition partition, int id)
|
||||
{
|
||||
var source = _poolDictionary[partition][id].Get();
|
||||
|
||||
// Настроить если надо
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
public void ReleaseParticleSystem(ParticlePartition partition, int id, ParticleSystem particleSystem)
|
||||
{
|
||||
if(_poolDictionary[partition].ContainsKey(id)) _poolDictionary[partition][id].Release(particleSystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21ce106fcb48566dc92ae832b09fa268
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Reflex.Attributes;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Code.Infrastructure.Particles
|
||||
{
|
||||
public interface IParticleService
|
||||
{
|
||||
UniTaskVoid EmitOneShot(ParticlePartitionIDPair pair, int particleCount, Vector3 position, Quaternion rotation);
|
||||
UniTaskVoid EmitTillCancelled(ParticlePartitionIDPair pair, CancellationToken token, Vector3 position, Quaternion rotation);
|
||||
}
|
||||
|
||||
public class ParticleService : IParticleService
|
||||
{
|
||||
[Inject] private IParticlePoolManagerForService _poolManagerForService;
|
||||
[Inject] private IParticleLoader _particleLoader;
|
||||
|
||||
public async UniTaskVoid EmitOneShot(ParticlePartitionIDPair pair, int particleCount, Vector3 position, Quaternion rotation)
|
||||
{
|
||||
var particleSystem = _poolManagerForService.GetParticleSystem(pair.ParticlePartition, pair.ID);
|
||||
|
||||
particleSystem.transform.position = position;
|
||||
particleSystem.transform.rotation = rotation;
|
||||
|
||||
particleSystem.Emit(particleCount);
|
||||
|
||||
await UniTask.WaitWhile(() => particleSystem.particleCount > 0);
|
||||
|
||||
_poolManagerForService.ReleaseParticleSystem(pair.ParticlePartition, pair.ID, particleSystem);
|
||||
}
|
||||
public async UniTaskVoid EmitTillCancelled(ParticlePartitionIDPair pair, CancellationToken token, Vector3 position, Quaternion rotation)
|
||||
{
|
||||
var particleSystem = _poolManagerForService.GetParticleSystem(pair.ParticlePartition, pair.ID);
|
||||
|
||||
particleSystem.transform.position = position;
|
||||
particleSystem.transform.rotation = rotation;
|
||||
|
||||
particleSystem.Play();
|
||||
try
|
||||
{
|
||||
await UniTask.WaitUntilCanceled(cancellationToken: token);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
particleSystem.Stop();
|
||||
|
||||
_poolManagerForService.ReleaseParticleSystem(pair.ParticlePartition, pair.ID, particleSystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a4f2bf7e8fd80581b714c3d32e47f20
|
||||
Reference in new issue
Block a user