Manager for post processing effect GameObjects. It keeps spawned prefab instances for PostProcessResource paths, tracks which are enabled, allows selecting, previewing, toggling and removing effects, and returns components from the spawned GameObjects.
public sealed class PostProcessManager : GameObjectSystem<PostProcessManager>
{
private readonly Dictionary<string, GameObject> _active = new();
private readonly HashSet<string> _enabled = new();
public string SelectedPath { get; private set; }
public IReadOnlyList<Component> GetComponents( string resourcePath )
{
if ( !_active.TryGetValue( resourcePath, out var go ) || !go.IsValid() )
return [];
return [.. go.GetComponentsInChildren<Component>( true )];
}
public IReadOnlyList<Component> GetSelectedComponents()
{
if ( SelectedPath == null ) return [];
if ( !_active.TryGetValue( SelectedPath, out var go ) || !go.IsValid() )
return [];
return [.. go.GetComponentsInChildren<Component>( true )];
}
public PostProcessManager( Scene scene ) : base( scene ) { }
public bool IsEnabled( string resourcePath ) => _enabled.Contains( resourcePath );
private void SetEnabled( string resourcePath, bool enabled )
{
if ( !_active.TryGetValue( resourcePath, out var go ) ) return;
go.Enabled = enabled;
if ( enabled ) _enabled.Add( resourcePath );
else _enabled.Remove( resourcePath );
}
private void SpawnGo( string resourcePath, bool startEnabled )
{
var resource = ResourceLibrary.Get<PostProcessResource>( resourcePath );
if ( resource?.Prefab is null ) return;
var camera = Scene.Camera?.GameObject;
if ( camera is null ) return;
// Spawn enabled so components initialize, then disable if not wanted
var go = GameObject.Clone( resource.Prefab, new CloneConfig { StartEnabled = true, Parent = camera } );
go.Flags |= GameObjectFlags.NotNetworked;
_active[resourcePath] = go;
if ( !startEnabled )
go.Enabled = false;
}
public void Select( string resourcePath )
{
SelectedPath = resourcePath;
if ( !_active.ContainsKey( resourcePath ) )
SpawnGo( resourcePath, startEnabled: false );
}
private string _previewPath;
public void Preview( string resourcePath )
{
if ( _previewPath == resourcePath ) return;
Unpreview();
_previewPath = resourcePath;
if ( IsEnabled( resourcePath ) ) return;
if ( !_active.ContainsKey( resourcePath ) )
SpawnGo( resourcePath, startEnabled: true );
else
SetEnabled( resourcePath, true );
}
public void Unpreview()
{
if ( _previewPath is null ) return;
if ( !IsEnabled( _previewPath ) )
SetEnabled( _previewPath, false );
_previewPath = null;
}
public void Deselect()
{
SelectedPath = null;
}
public void Toggle( string resourcePath )
{
SelectedPath = resourcePath;
if ( IsEnabled( resourcePath ) )
{
_enabled.Remove( resourcePath );
SetEnabled( resourcePath, false );
return;
}
_enabled.Add( resourcePath );
if ( !_active.ContainsKey( resourcePath ) )
SpawnGo( resourcePath, startEnabled: true );
else
SetEnabled( resourcePath, true );
}
public void Set( string resourcePath, bool state )
{
if ( state == IsEnabled( resourcePath ) ) return;
SetEnabled( resourcePath, state );
}
public void Remove( string resourcePath )
{
if ( _active.TryGetValue( resourcePath, out var go ) )
{
go.Destroy();
_active.Remove( resourcePath );
}
_enabled.Remove( resourcePath );
if ( SelectedPath == resourcePath )
SelectedPath = null;
}
}