2014-03-12 1 views
0

Unity 3D 엔진의 MonoBehaviour을 복제하려고합니다. Linux에서 monodevelop를 사용하고 있으며 대부분의 테스트는 Windows에서 수행됩니다.Type 또는 파생 된 Type에서 메서드를 호출하려면 어떻게해야합니까?

MonoBehavior.Start에 대한 추가 정보는 here입니다.

MonoBehavior에서 상속 한 모든 유형에 Start 메소드를 호출하려고합니다.

이 내가 시도 무엇 : 지금은 당신이 요구하는 무엇인지 생각으로 완전히이 답변을 다시 실행

class MonoBehaviour 
{ 
    static Type[] types = Assembly.GetExecutingAssembly().GetTypes(); 

    public static void Main() 
    { 
    foreach (Type type in types) 
    { 
     if (type.IsSubclassOf(typeof(MonoBehaviour))) 
     { 
     MethodInfo minfo = type.GetMethod ("Start"); 
     mInfo.Invoke (type, null); // This throws 
     } 
    } 
    } 
} 

class example : MonoBehaviour 
{ 
    void Start() 
    { 
    // I want this to be run from MonoBehaviour 
    Console.WriteLine ("HelloWorld"); 
    } 
} 

class example1 : MonoBehaviour 
{ 
} 

답변

1

편집.

어셈블리에서 Type의 모든 개체의 Start를 호출 할 수 있도록 코드를 제공 할 것입니다. 그러나 이것이 MonoBehavior의 작동 방식이라고 생각하지 않습니다. 고려해야 할 것이 많습니다. 예를 들어 Awake이 먼저 호출되어야하며 스크립트가 사용 가능하게 설정되었는지 여부가 있습니다. 또한이 메서드는 모든 개체에서 동시에 호출되는 것이 아니라 개체가 생성/시작되었을 때만 호출됩니다. 나는 유니티 3D 경험이 없으므로, 나는이 세부 사항을 모르고있다. 나는 당신의 질문에있는 링크에서 읽은 것에 의존하고 있습니다.

나는 다양한 범위의 메소드를 찾을 수 있음을 보여주기 위해 몇 가지 추가 바인딩 플래그를 추가했습니다. 또한, 내 코드에서 명시 적으로 매개 변수가없는 Start 메서드를 찾고 있습니다. 이것은 귀하의 필요에 맞게 수정할 수 있습니다.

using System; 
using System.Reflection; 
class Program 
{ 
    static void Main(string[] args) 
    { 
    Assembly asm = Assembly.GetExecutingAssembly(); 
    Type[] types = asm.GetTypes(); 

    foreach (var type in types) 
    { 
     if (type.IsSubclassOf(typeof(MonoBehavior)) || type.GetInterfaces().Contains(typeof(MonoBehavior))) 
     { 
     MethodInfo startMethod = type.GetMethod("Start", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null); 
     if (startMethod != null) 
     { 
      ConstructorInfo ctor = type.GetConstructor(new Type[] { }); 
      if (ctor != null) 
      { 
      object inst = ctor.Invoke(new object[] { }); 
      startMethod.Invoke(inst, new object[] { }); 
      } 
     } 
     } 
    } 
    } 
} 

interface MonoBehavior 
{ 
} 

class Example1 : MonoBehavior 
{ 
    static void Start() 
    { 
    Console.WriteLine("Example1 Start"); 
    } 
} 

class Example2 : MonoBehavior 
{ 
} 

이제 객체를 생성 좋아하지 않는 경우에, 당신은 Start 정적 만들 수 있고, 반사에 몇 줄은 다음과 같이 조정된다 :

MethodInfo startMethod = type.GetMethod("Start", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static, null, new Type[] { }, null); 
if (startMethod != null) 
{ 
    startMethod.Invoke(null, new object[] { }); 
} 

참고 나는 더 이상 인스턴스를 생성해야하며 Invoke에 전달 된 첫 번째 매개 변수는 null입니다 (이 방법은 항상 static 메쏘드에서 수행됩니다).

그러나 Unity3D 문서를 MonoBehaviour.Start에서 읽는 것은 정적이 아니라이 방식으로 실행되도록 의도 된 것입니다. 나는 다른 다양한 조건 하에서 MonoBehaviour이 만들어 질 때 실행되어야한다고 생각합니다. 이 모델은 리플 렉싱을 필요로하지 않지만 팩토리 객체 요청을 위해 MonoBeaviour 객체를 생성하는 인스턴스 모델을 작성하는 것이 좋습니다. 인스턴스를 반환하기 전에 적절한 AwakeStart 메소드를 호출합니다.

+0

yes 시작은 다른 클래스에서 호출해야합니다. monoBehaviour 클래스에서는 main이 아니지만 MonoBehaviour 클래스는 Unity 클래스에서와 마찬가지로 다른 클래스의 Start() 함수를 모두 실행하기 시작합니다. – MilitaryG

+0

yeey it finally :) finally. 어쨌든 왜 사람들은 당신이 사용하고있는 코드가 무엇이든 상관없이 위에 포함시키지 않습니다. 어제 나는'Assembly.GetExecutingAssembly'가있는 20 분을 찾고있었습니다. 그게 내 필요에 필요한 것인가를 알아내는 것입니다. 어쨌든 나를 도와 주셔서 감사합니다. – MilitaryG

0

유형이 자체 하위 클래스가 아니므로 3 가지 유형이 있지만 조건과 일치하는 유형은 2 가지입니다. (그게 질문이라면.) 게다가, MonoBehaviour는 Start() 메서드가 없거나 매우 피곤합니다 .-)).

+0

모노에서 파생 된 경우 Start는 시작시 실행됩니다. MonoBehaviour – MilitaryG

+0

에서 Start 메서드를 실행하는 방법을 묻습니다. "여기 어떻게 오류가 발생합니까?"라고 주석을 달았습니다. 그것은별로 구체적이지 않습니다. 컴파일 오류입니까? 런타임 오류? 메시지가 뭐니? –

관련 문제