using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Plugins.Animate_UI_Materials
{
[ExecuteAlways]
[AddComponentMenu("UI/Animate UI Material/GraphicMaterialOverride")]
public class GraphicMaterialOverride : BufferedMaterialModifier
{
///
/// Recreate the modified material using each active IMaterialPropertyModifier on this GameObject or its children
///
public void SetMaterialDirty()
{
if (TryGetComponent(out Graphic graphic))
{
graphic.SetMaterialDirty();
}
}
///
/// A buffer list to accelerate GetComponents requests
///
[NonSerialized] List _modifiers;
///
/// Retrieves all enabled IMaterialPropertyModifiers belonging to direct children
///
/// An iterator over all enabled modifiers, avoid storing this value
public IEnumerable GetModifiers(bool includeInactive = false)
{
// Ensure the buffer list is available
_modifiers ??= new List();
// Load all IPropertyModifiers belonging the direct children of this GameObject
foreach (Transform child in transform)
{
// skip this GameObject if disabled
if (!child.gameObject.activeSelf && !includeInactive) continue;
// disabled children will be ignored
child.GetComponents(_modifiers);
// Call the children to apply their modified properties
foreach (IMaterialPropertyModifier propertyModifier in _modifiers)
{
// Check if the modifier is enabled (skip if not)
if (propertyModifier.enabled || includeInactive)
{
yield return propertyModifier;
}
}
}
// Ensure no ref is kept
_modifiers.Clear();
}
// On enable and disable, update the target graphic
void OnEnable() => SetMaterialDirty();
void OnDisable() => SetMaterialDirty();
///
/// Called by Graphic using the IMaterialModifier interface through the parent class
/// Modifies the buffered material to match all children component specifications
///
/// A copy of the Graphic base material, buffered for reuse
protected override void ModifyMaterial(Material modifiedMaterial)
{
// Iterate over all active modifiers
foreach (IMaterialPropertyModifier modifier in GetModifiers())
{
// Ignore un-init modifiers
if (!string.IsNullOrEmpty(modifier.PropertyName))
{
// Apply the property to the new material
modifier.ApplyModifiedProperty(modifiedMaterial);
}
}
}
}
}