2016-05-18 1 views
2

Я использую единство с отражением, и я пытаюсь вызвать определенный метод имя Start, но мой код не называя егоC# Отражения Не Вызов методов

Вот ModLoader.cs:

using UnityEngine; 
using System.Collections; 
using System.IO; 
using System.Reflection; 
using System.Collections.Generic; 

public class ModLoader : MonoBehaviour { 
    List<MethodInfo> modMethods = new List<MethodInfo>(); 

    // Use this for initialization 
    void Start() { 
     if (!Directory.Exists (Application.dataPath + "/../Mods")) { 
      Directory.CreateDirectory (Application.dataPath + "/../Mods"); 
     } 

     foreach (var mod in Directory.GetFiles(Application.dataPath + "/../Mods", "*.dll")) { 
      var assembly = Assembly.LoadFile(mod); 
      foreach (var type in assembly.GetTypes()) { 
       foreach (var method in type.GetMethods()) { 
        modMethods.Add (method); 
       } 
      } 
     } 

     //Execute Start method in all mods 
     foreach (MethodInfo method in modMethods) { 
      print (method.Name); 
      if (method.Name == "Start" && method.GetParameters().Length == 0 && method.IsStatic) { 
       method.Invoke (null, new object[]{ }); 
      } 
     } 
    } 

    // Update is called once per frame 
    void Update() { 
     //Execute Update method in all mods 
     foreach (MethodInfo method in modMethods) { 
      if (method.Name == "Update" && method.GetParameters().Length == 0 && method.IsStatic) { 
       method.Invoke (null, new object[]{ }); 
      } 
     } 
    } 
} 

Вот мой мод (а .dll):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using UnityEngine; 

public class Class1 { 
    static void Start() { 
     Debug.Log("hello world"); 

     foreach (GameObject go in GameObject.FindObjectsOfType<GameObject>()) { 
      if (go.GetComponent<MeshRenderer>()) { 
       go.GetComponent<MeshRenderer>().material.color = new Color(1f, 0f, 0f); 
      } 
     } 
    } 
} 

у меня есть библиотеки DLL из сборки в папке «Стиляги», и я знаю, что мой сценарий находит его, я просто не знаю, почему метод id не вызывается.

+1

Вы активизировали через нее в отладчик, чтобы посмотреть, что происходит, когда 'foreach' вызов достигает методов, которые вы пытаетесь вызвать? –

+0

Метод не передает инструкцию if, и я думаю, что это из-за имени метода. Почему не набирает имя? –

ответ

2

Метод Start в вашем модуле является закрытым. Отражение работает с общедоступными методами по умолчанию. Вы должны сделать его общедоступным:

public class Class1 { 
    public static void Start() { 
     Debug.Log("hello world"); 

     foreach (GameObject go in GameObject.FindObjectsOfType<GameObject>()) { 
      if (go.GetComponent<MeshRenderer>()) { 
       go.GetComponent<MeshRenderer>().material.color = new Color(1f, 0f, 0f); 
      } 
     } 
    } 
} 

или указать BindingFlags для метода GetMethods. Вам нужно BindingFlags.Static и BindingFlags.NonPublic

type.GetMethods(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic) 
+0

Спасибо за ваш ответ! –

0

В отсутствие public ключевого слова на вашем методе Start он не будет общедоступным, и GetMethods() только ищет общедоступные методы по умолчанию.

Либо сделать Start общедоступным, либо изменить type.GetMethods() на type.GetMethods(BindingFlags.NonPublic | BindingFlags.Static).