Files
BABA_YAGA/Assets/Third Parties/D.A. Assets/DA-Shared/Runtime/Extensions/ComponentExtensions.cs
2026-05-17 15:12:16 +07:00

129 lines
5.5 KiB
C#

using System;
using System.Reflection;
using UnityEngine;
namespace DA_Assets.Extensions
{
public static class ComponentExtensions
{
public static void CopySerializedFields(this Component source, Component destination)
{
FieldInfo[] fields = source.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
foreach (FieldInfo field in fields)
{
if (field.IsPublic || field.GetCustomAttribute<SerializeField>() != null)
{
field.SetValue(destination, field.GetValue(source));
}
}
}
public static bool TryGetComponentSafe<T>(this Component gameObject, out T component)
{
component = default;
if (gameObject == null)
return false;
return gameObject.TryGetComponent(out component);
}
/// <summary>
/// Destroying script of Unity GameObject, but as an extension.
/// <para>Works in Editor and Playmode.</para>
/// </summary>
public static bool Destroy(this UnityEngine.Component unityComponent)
{
try
{
if (unityComponent.IsRequiredByAnotherComponents())
return false;
#if UNITY_EDITOR
UnityEngine.Object.DestroyImmediate(unityComponent);
#else
UnityEngine.Object.Destroy(unityComponent);
#endif
return true;
}
catch
{
return false;
}
}
/// <summary>
/// Removes all components from the GameObject that have a 'RequireComponent' attribute pointing to the given component.
/// </summary>
/// <param name="component">The target component which other components might depend on.</param>
/// <returns>True if any dependent components were removed, false otherwise.</returns>
public static bool RemoveComponentsDependingOn(this UnityEngine.Component component)
{
bool removedAny = false; // Flag to indicate if we've removed any components.
Type type = component.GetType();
// Get all components present on the GameObject where the target component resides.
Component[] componentsOnObject = component.gameObject.GetComponents<Component>();
// Iterate through each component on the GameObject.
foreach (Component comp in componentsOnObject)
{
// Fetch all the RequireComponent attributes associated with the component.
object[] requireAttributes = comp.GetType().GetCustomAttributes(typeof(RequireComponent), true);
// Iterate through each RequireComponent attribute to check if our target component type is listed.
foreach (RequireComponent attribute in requireAttributes)
{
// Check if any of the required types match the type of our target component.
if (attribute.m_Type0 == type ||
attribute.m_Type1 == type ||
attribute.m_Type2 == type)
{
// Remove the component that depends on the target component.
comp.Destroy();// UnityEngine.Object.Destroy(comp);
removedAny = true; // Set the flag since we've removed a component.
break; // Exit the inner loop since we've made a modification.
}
}
}
return removedAny; // Return the flag indicating if any components were removed.
}
/// <summary>
/// Checks if the given component is required by any other components on the same GameObject via the RequireComponent attribute.
/// </summary>
/// <param name="component">The component to check for.</param>
/// <returns>True if the component is required by another component on the same GameObject, otherwise false.</returns>
public static bool IsRequiredByAnotherComponents(this UnityEngine.Component component)
{
Type type = component.GetType();
// Get all components present on the GameObject where the target component resides.
Component[] componentsOnObject = component.gameObject.GetComponents<Component>();
// Iterate through each component on the GameObject.
foreach (Component comp in componentsOnObject)
{
// Fetch all the RequireComponent attributes associated with the component.
object[] requireAttributes = comp.GetType().GetCustomAttributes(typeof(RequireComponent), true);
// Iterate through each RequireComponent attribute to check if our target component type is listed.
foreach (RequireComponent attribute in requireAttributes)
{
// Check if any of the required types match the type of our target component.
if (attribute.m_Type0 == type ||
attribute.m_Type1 == type ||
attribute.m_Type2 == type)
{
// If a match is found, return true indicating the component is required by another.
return true;
}
}
}
// If no matches were found, return false.
return false;
}
}
}