using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.VFX;
namespace UnityEngine.VFX.Utility
{
///
/// A Behaviour that controls binding between Visual Effect Properties, and other scene values, through the use of VFXBinderBase
///
[RequireComponent(typeof(VisualEffect))]
[DefaultExecutionOrder(1)]
[DisallowMultipleComponent]
[ExecuteAlways]
public class VFXPropertyBinder : MonoBehaviour
{
///
/// Whether the bindings should be executed in editor (as preview)
///
[SerializeField]
protected bool m_ExecuteInEditor = true;
///
/// 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.
///
public List m_Bindings = new List();
///
/// The Visual Effect component attached to the VFXPropertyBinder
///
[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 m_BinderToCopyPaste;
#endif
private void Reload()
{
m_VisualEffect = GetComponent();
#if UNITY_EDITOR
//Handle probable copy/paste component saving list of inappropriate entries.
m_BinderToCopyPaste = new List();
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();
m_Bindings.AddRange(gameObject.GetComponents());
}
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);
}
}
}
///
/// Adds a new PropertyBinder
///
/// the Type of Property Binder
/// The PropertyBinder newly Created
public T AddPropertyBinder() where T : VFXBinderBase
{
return gameObject.AddComponent();
}
///
/// Adds a new PropertyBinder
///
/// the Type of Property Binder
/// The PropertyBinder newly Created
[Obsolete("Use AddPropertyBinder() instead")]
public T AddParameterBinder() where T : VFXBinderBase
{
return AddPropertyBinder();
}
///
/// Clears all the Property Binders
///
public void ClearPropertyBinders()
{
var allBinders = GetComponents();
foreach (var binder in allBinders)
SafeDestroy(binder);
}
///
/// Clears all the Property Binders
///
[Obsolete("Please use ClearPropertyBinders() instead")]
public void ClearParameterBinders()
{
ClearPropertyBinders();
}
///
/// Removes specified Property Binder
///
/// The VFXBinderBase to remove
public void RemovePropertyBinder(VFXBinderBase binder)
{
if (binder.gameObject == this.gameObject)
SafeDestroy(binder);
}
///
/// Removes specified Property Binder
///
/// The VFXBinderBase to remove
[Obsolete("Please use RemovePropertyBinder() instead")]
public void RemoveParameterBinder(VFXBinderBase binder)
{
RemovePropertyBinder(binder);
}
///
/// Remove all Property Binders of Given Type
///
/// Specified VFXBinderBase type
public void RemovePropertyBinders() where T : VFXBinderBase
{
var allBinders = GetComponents();
foreach (var binder in allBinders)
if (binder is T)
SafeDestroy(binder);
}
///
/// Remove all Property Binders of Given Type
///
/// Specified VFXBinderBase type
[Obsolete("Please use RemovePropertyBinders() instead")]
public void RemoveParameterBinders() where T : VFXBinderBase
{
RemovePropertyBinders();
}
///
/// Gets all VFXBinderBase of Given Type, attached to this VFXPropertyBinder
///
/// Specific VFXBinderBase type
/// An IEnumerable of all VFXBinderBase
public IEnumerable GetPropertyBinders() where T : VFXBinderBase
{
foreach (var binding in m_Bindings)
{
if (binding is T) yield return binding as T;
}
}
///
/// Gets all VFXBinderBase of Given Type, attached to this VFXPropertyBinder
///
/// Specific VFXBinderBase type
/// An IEnumerable of all VFXBinderBase
[Obsolete("Please use GetPropertyBinders() instead")]
public IEnumerable GetParameterBinders() where T : VFXBinderBase
{
return GetPropertyBinders();
}
}
}