using UnityEngine;
using System.Reflection;
using System;

//그냥 쓸수 있도록 확장메소드로 만듬.
//쫌더 원하는 형식으로 호출가능하도록 바인딩플래그를 매개변수로 넘길수 있도록 만듬.
public static class CustomMessage
{
    //기본조건
    const BindingFlags defaultFlags = (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

    public static void SendMessage(this GameObject target, string methodName, BindingFlags flags , params object[] list)
    {
        MonoBehaviour[] monos = target.GetComponents<MonoBehaviour>();

        foreach (MonoBehaviour mono in monos)
        {
            Invoke(mono, methodName, flags , list);
        }
    }

    public static void SendMessage(this GameObject target , string methodName , params object[] list)
    {
        CustomMessage.SendMessage(target.gameObject, methodName , defaultFlags , list);
    }

    public static void SendMessage<T>(this T target, string methodName, BindingFlags flags, params object[] list) where T : MonoBehaviour
    {
        CustomMessage.SendMessage(target.gameObject, methodName, flags, list);
    }

    public static void SendMessage<T>(this T target, string methodName, params object[] list) where T : MonoBehaviour
    {
        CustomMessage.SendMessage(target.gameObject, methodName, list);
    }

    //함수 호출
    public static void Invoke<T>(this T target, string methodName, BindingFlags flags ,  params object[] list) where T : class
    {
        Type type = target.GetType();

        MethodInfo methodInfo = type.GetMethod(methodName, flags);

        if (methodInfo != null)
        {
            //매개변수에 상관없이 호출
            ParameterInfo[] parameters = methodInfo.GetParameters();
            methodInfo.Invoke(target, parameters.Length == 0 ? null : list);
        }
    }

    public static void Invoke<T>(this T target, string methodName, params object[] list) where T : class
    {
        CustomMessage.Invoke(target, methodName, defaultFlags, list);
    }
}

 

 

물론 유니티는 리플렉션이 아닌 룩업테이블로 되기 때문에 속도는 비교가 안될거임..

그래도 해본이유는 유니티가 아닌 다른곳에서 SendMessage를 구현하면 어떻게 해야될까라는 고민에서 한번 만들어봄..