-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathParticleSystemPlugin.cs
More file actions
130 lines (109 loc) · 5.29 KB
/
ParticleSystemPlugin.cs
File metadata and controls
130 lines (109 loc) · 5.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
using System;
using System.Collections.Generic;
using System.Threading;
using Arch.SystemGroups;
using Cysharp.Threading.Tasks;
using DCL.AssetsProvision;
using DCL.DebugUtilities;
using DCL.DebugUtilities.UIBindings;
using DCL.ECSComponents;
using DCL.Optimization.Pools;
using DCL.PluginSystem.World.Dependencies;
using DCL.ResourcesUnloading;
using DCL.SDKComponents.ParticleSystem.Systems;
using ECS.LifeCycle;
using ECS.LifeCycle.Systems;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Pool;
using Object = UnityEngine.Object;
using Utility;
namespace DCL.PluginSystem.World
{
public class ParticleSystemPlugin : IDCLWorldPlugin<ParticleSystemPlugin.ParticleSystemPluginSettings>
{
private readonly IComponentPoolsRegistry poolsRegistry;
private readonly IAssetsProvisioner assetsProvisioner;
private readonly CacheCleaner cacheCleaner;
private readonly IDebugContainerBuilder debugBuilder;
private IComponentPool<ParticleSystem>? particleSystemPool;
private IObjectPool<Material>? particleMaterialPool;
private ParticleSystemPluginSettings? pluginSettings;
private ElementBinding<string>? particleCountBinding;
private DebugWidgetVisibilityBinding? particlesVisibilityBinding;
public ParticleSystemPlugin(IComponentPoolsRegistry poolsRegistry, IAssetsProvisioner assetsProvisioner,
CacheCleaner cacheCleaner, IDebugContainerBuilder debugBuilder)
{
this.poolsRegistry = poolsRegistry;
this.assetsProvisioner = assetsProvisioner;
this.cacheCleaner = cacheCleaner;
this.debugBuilder = debugBuilder;
}
public void Dispose() { }
public void InjectToWorld(
ref ArchSystemsWorldBuilder<Arch.Core.World> builder,
in ECSWorldInstanceSharedDependencies sharedDependencies,
in PersistentEntities persistentEntities,
List<IFinalizeWorldSystem> finalizeWorldSystems,
List<ISceneIsCurrentListener> sceneIsCurrentListeners)
{
ResetDirtyFlagSystem<PBParticleSystem>.InjectToWorld(ref builder);
var lifecycleSystem = ParticleSystemLifecycleSystem.InjectToWorld(
ref builder,
sharedDependencies.SceneStateProvider,
particleSystemPool,
particleMaterialPool!);
ParticleSystemApplyPropertiesSystem.InjectToWorld(
ref builder,
sharedDependencies.SceneData,
sharedDependencies.ScenePartition,
particleMaterialPool!);
var playbackSystem = ParticleSystemPlaybackSystem.InjectToWorld(ref builder);
sceneIsCurrentListeners.Add(playbackSystem);
ParticleSystemBudgetSystem.InjectToWorld(ref builder, pluginSettings!, particleCountBinding!, particlesVisibilityBinding!);
finalizeWorldSystems.Add(lifecycleSystem);
}
public async UniTask InitializeAsync(ParticleSystemPluginSettings settings, CancellationToken ct)
{
ParticleSystem prefab = (await assetsProvisioner.ProvideMainAssetAsync(settings.ParticleSystemPrefab, ct)).Value
.GetComponent<ParticleSystem>();
particleSystemPool = poolsRegistry.AddGameObjectPool(
() => Object.Instantiate(prefab, Vector3.zero, quaternion.identity),
onRelease: OnPoolRelease);
cacheCleaner.Register(particleSystemPool);
pluginSettings = settings;
particleCountBinding = new ElementBinding<string>(string.Empty);
particlesVisibilityBinding = new DebugWidgetVisibilityBinding(true);
debugBuilder.TryAddWidget(IDebugContainerBuilder.Categories.PARTICLES)
?.SetVisibilityBinding(particlesVisibilityBinding)
.AddCustomMarker("Scene Particles:", particleCountBinding);
particleMaterialPool = new ObjectPool<Material>(
createFunc: () => new Material(settings.ParticleMaterial),
actionOnRelease: releasedMaterial => releasedMaterial.CopyPropertiesFromMaterial(settings.ParticleMaterial),
actionOnDestroy: UnityObjectUtils.SafeDestroy,
defaultCapacity: 64,
maxSize: 512);
}
private static void OnPoolRelease(ParticleSystem particleSystem)
{
particleSystem.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);
particleSystem.transform.SetParent(null);
particleSystem.gameObject.SetActive(false);
}
[Serializable]
public class ParticleSystemPluginSettings : IDCLPluginSettings
{
[field: SerializeField]
public AssetReferenceGameObject ParticleSystemPrefab { get; private set; }
/// <summary>
/// Base material for particle rendering. Should point to same Material used in MaterialWorldPlugin.
/// Kept as a direct reference (not Addressable) to ensure shader variants are compiled.
/// </summary>
[field: SerializeField]
public Material ParticleMaterial { get; private set; }
[field: SerializeField]
public int MaxSceneParticles { get; private set; } = 1000;
}
}
}