Rasagar/Library/PackageCache/com.unity.visualeffectgraph/Runtime/Utilities/PropertyBinding/VFXPropertyBinder.cs

233 lines
7.7 KiB
C#
Raw Normal View History

2024-08-26 13:07:20 -07:00
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.VFX;
namespace UnityEngine.VFX.Utility
{
/// <summary>
/// A Behaviour that controls binding between Visual Effect Properties, and other scene values, through the use of VFXBinderBase
/// </summary>
[RequireComponent(typeof(VisualEffect))]
[DefaultExecutionOrder(1)]
[DisallowMultipleComponent]
[ExecuteAlways]
public class VFXPropertyBinder : MonoBehaviour
{
/// <summary>
/// Whether the bindings should be executed in editor (as preview)
/// </summary>
[SerializeField]
protected bool m_ExecuteInEditor = true;
/// <summary>
/// The list of all Bindings attached to the binder, these bindings are managed by the VFXPropertyBinder and should be managed using the AddPropertyBinder, ClearPropertyBinders, RemovePropertyBinder, RemovePropertyBinders, and GetPropertyBinders.
/// </summary>
public List<VFXBinderBase> m_Bindings = new List<VFXBinderBase>();
/// <summary>
/// The Visual Effect component attached to the VFXPropertyBinder
/// </summary>
[SerializeField]
protected VisualEffect m_VisualEffect;
private void OnEnable()
{
Reload();
}
private void OnValidate()
{
Reload();
}
static private void SafeDestroy(Object toDelete)
{
#if UNITY_EDITOR
if (Application.isPlaying)
Destroy(toDelete); //Undo.DestroyObjectImmediate is needed only for Reset, which can't be called in play mode
else
UnityEditor.Undo.DestroyObjectImmediate(toDelete);
#else
Destroy(toDelete);
#endif
}
#if UNITY_EDITOR
List<VFXBinderBase> m_BinderToCopyPaste;
#endif
private void Reload()
{
m_VisualEffect = GetComponent<VisualEffect>();
#if UNITY_EDITOR
//Handle probable copy/paste component saving list of inappropriate entries.
m_BinderToCopyPaste = new List<VFXBinderBase>();
foreach (var bindings in m_Bindings)
{
if (bindings != null && bindings.gameObject != gameObject)
m_BinderToCopyPaste.Add(bindings);
}
if (m_BinderToCopyPaste.Count == 0)
m_BinderToCopyPaste = null;
#endif
m_Bindings = new List<VFXBinderBase>();
m_Bindings.AddRange(gameObject.GetComponents<VFXBinderBase>());
}
private void Reset()
{
Reload();
ClearPropertyBinders();
}
#if UNITY_EDITOR
void Update()
{
if (m_BinderToCopyPaste != null)
{
//We can't add a component during a OnInvalidate, restore & copy linked binders (from copy/past) here
foreach (var copyPaste in m_BinderToCopyPaste)
{
var type = copyPaste.GetType();
var newComponent = gameObject.AddComponent(type);
UnityEditor.EditorUtility.CopySerialized(copyPaste, newComponent);
}
m_BinderToCopyPaste = null;
Reload();
}
}
#endif
void LateUpdate()
{
if (!m_ExecuteInEditor && Application.isEditor && !Application.isPlaying)
return;
for (int i = 0; i < m_Bindings.Count; i++)
{
var binding = m_Bindings[i];
if (binding == null)
{
Debug.LogWarning(string.Format("Parameter binder at index {0} of GameObject {1} is null or missing", i, gameObject.name));
continue;
}
else
{
if (binding.IsValid(m_VisualEffect))
binding.UpdateBinding(m_VisualEffect);
}
}
}
/// <summary>
/// Adds a new PropertyBinder
/// </summary>
/// <typeparam name="T">the Type of Property Binder</typeparam>
/// <returns>The PropertyBinder newly Created</returns>
public T AddPropertyBinder<T>() where T : VFXBinderBase
{
return gameObject.AddComponent<T>();
}
/// <summary>
/// Adds a new PropertyBinder
/// </summary>
/// <typeparam name="T">the Type of Property Binder</typeparam>
/// <returns>The PropertyBinder newly Created</returns>
[Obsolete("Use AddPropertyBinder<T>() instead")]
public T AddParameterBinder<T>() where T : VFXBinderBase
{
return AddPropertyBinder<T>();
}
/// <summary>
/// Clears all the Property Binders
/// </summary>
public void ClearPropertyBinders()
{
var allBinders = GetComponents<VFXBinderBase>();
foreach (var binder in allBinders)
SafeDestroy(binder);
}
/// <summary>
/// Clears all the Property Binders
/// </summary>
[Obsolete("Please use ClearPropertyBinders() instead")]
public void ClearParameterBinders()
{
ClearPropertyBinders();
}
/// <summary>
/// Removes specified Property Binder
/// </summary>
/// <param name="binder">The VFXBinderBase to remove</param>
public void RemovePropertyBinder(VFXBinderBase binder)
{
if (binder.gameObject == this.gameObject)
SafeDestroy(binder);
}
/// <summary>
/// Removes specified Property Binder
/// </summary>
/// <param name="binder">The VFXBinderBase to remove</param>
[Obsolete("Please use RemovePropertyBinder() instead")]
public void RemoveParameterBinder(VFXBinderBase binder)
{
RemovePropertyBinder(binder);
}
/// <summary>
/// Remove all Property Binders of Given Type
/// </summary>
/// <typeparam name="T">Specified VFXBinderBase type</typeparam>
public void RemovePropertyBinders<T>() where T : VFXBinderBase
{
var allBinders = GetComponents<VFXBinderBase>();
foreach (var binder in allBinders)
if (binder is T)
SafeDestroy(binder);
}
/// <summary>
/// Remove all Property Binders of Given Type
/// </summary>
/// <typeparam name="T">Specified VFXBinderBase type</typeparam>
[Obsolete("Please use RemovePropertyBinders<T>() instead")]
public void RemoveParameterBinders<T>() where T : VFXBinderBase
{
RemovePropertyBinders<T>();
}
/// <summary>
/// Gets all VFXBinderBase of Given Type, attached to this VFXPropertyBinder
/// </summary>
/// <typeparam name="T">Specific VFXBinderBase type</typeparam>
/// <returns>An IEnumerable of all VFXBinderBase</returns>
public IEnumerable<T> GetPropertyBinders<T>() where T : VFXBinderBase
{
foreach (var binding in m_Bindings)
{
if (binding is T) yield return binding as T;
}
}
/// <summary>
/// Gets all VFXBinderBase of Given Type, attached to this VFXPropertyBinder
/// </summary>
/// <typeparam name="T">Specific VFXBinderBase type</typeparam>
/// <returns>An IEnumerable of all VFXBinderBase</returns>
[Obsolete("Please use GetPropertyBinders<T>() instead")]
public IEnumerable<T> GetParameterBinders<T>() where T : VFXBinderBase
{
return GetPropertyBinders<T>();
}
}
}