Skip to content

Instantly share code, notes, and snippets.

@ruccho
Last active May 29, 2021 07:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ruccho/ce620c377e7b18abe968bdd542561ef5 to your computer and use it in GitHub Desktop.
Save ruccho/ce620c377e7b18abe968bdd542561ef5 to your computer and use it in GitHub Desktop.
PostProcessingStackのVolumeのパラメータをSerializeFieldとして露出し、Animatorなどで制御可能にするやつ
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering.PostProcessing;
namespace Ruccho.Utilities
{
public abstract class PostProcessSettingsExposition
{
public abstract void Update(PostProcessProfile profile);
}
[Serializable]
public class PostProcessSettingsExposition<TSettings, TValue> : PostProcessSettingsExposition
where TSettings : PostProcessEffectSettings where TValue : IEquatable<TValue>
{
[SerializeField] private TValue value = default;
public TValue Value
{
get => value;
set => this.value = value;
}
private TValue tempProfileValue = default;
private TSettings settings = default;
private Func<TSettings, ParameterOverride<TValue>> SelectParameter { get; set; }
private TValue GetValue(TSettings settings) => SelectParameter(settings).value;
private void ApplyValue(TSettings settings, TValue value) => SelectParameter(settings).value = value;
private PostProcessProfile tempProfile;
public void Initialize(Func<TSettings, ParameterOverride<TValue>> selectParameter)
{
SelectParameter = selectParameter;
}
public override void Update(PostProcessProfile profile)
{
value = InternalUpdate(profile);
}
private TValue InternalUpdate(PostProcessProfile profile)
{
if ((!settings || tempProfile != profile) && profile)
{
tempProfile = profile;
settings = profile.GetSetting<TSettings>();
if (settings) tempProfileValue = GetValue(settings);
}
if (!settings)
{
Debug.LogWarning($"PostProcessEffectSettings ({typeof(TSettings).Name}) is missing.");
return default;
}
var profileValue = GetValue(settings);
if (!profileValue.Equals(tempProfileValue))
{
//primarily use profile value
tempProfileValue = profileValue;
return profileValue;
}
else
{
//use updated value
ApplyValue(settings, value);
tempProfileValue = GetValue(settings);
return value;
}
}
}
[ExecuteInEditMode]
public abstract class PostProcessProfileExpositionBehaviour : MonoBehaviour
{
[SerializeField] private PostProcessProfile profile = default;
protected abstract IEnumerable<PostProcessSettingsExposition> Exposition { get; }
protected virtual void OnEnable()
{
InitializeExpositions();
}
protected virtual void Reset()
{
var volume = GetComponent<PostProcessVolume>();
if (!volume) return;
profile = volume.sharedProfile;
}
protected virtual void LateUpdate()
{
UpdateExpositions();
}
protected abstract void InitializeExpositions();
protected void UpdateExpositions()
{
foreach (var exposition in Exposition)
{
exposition.Update(profile);
}
}
}
}
using System.Collections.Generic;
using Ruccho.Utilities;
using UnityEngine;
using UnityEngine.Rendering.PostProcessing;
public class PostProcessProfileExpositionSample : PostProcessProfileExpositionBehaviour
{
[SerializeField] private PostProcessSettingsExposition<Bloom, float> bloomIntensity = default;
[SerializeField] private PostProcessSettingsExposition<Bloom, float> bloomThreshold = default;
protected override IEnumerable<PostProcessSettingsExposition> Exposition
{
get
{
yield return bloomIntensity;
yield return bloomThreshold;
}
}
protected override void InitializeExpositions()
{
bloomIntensity.Initialize(bloom => bloom.intensity);
bloomThreshold.Initialize(bloom => bloom.threshold);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment