17.08.2016, 16:48
|
#7
|
Гигант индустрии
Регистрация: 13.09.2008
Сообщений: 2,893
Написано 1,185 полезных сообщений (для 3,298 пользователей)
|
Ответ: MonkeyBehaviour
Тогда как когда то pax рекомендовал делать через рефлексию и проверять используется ли функция в скрипте игрока. Так даже можно делать без virtual/override.
Просто при старте игры проверять код на наличие нужных функций и если есть, то делать из найденных функций делегат, который работает быстро в отличии от рефлексии. А там уже например в лист сохраняешь делегаты и вызываешь.
Я такое пробовал использовать на c# + 2д движек. И даже без делегатов на небольших сценках все быстро работало.
Сообщение от Nex
Научите, пожалуйста, как делать методы подобно Start() или Update(), которые уже где то в Юнити объявлены, но при этом их можно использовать/не использовать без override.
Я пробовал несколько способов, но не удачно.
1) Интерфейс требует что бы было объявлено и обязательно public.
2) Если объявлено выше по иерархии, то надо перезаписать.
3) Абстрактный метод как и интерфейс - нужно объявлять.
Какие еще способы есть?
|
Сообщение от pax
Все просто, это рефлексия
obj.GetType().GetMethod("MyMethod").Invoke(obj, arguments[])
Пара ссылок
https://msdn.microsoft.com/ru-ru/lib...eflection.aspx
https://msdn.microsoft.com/ru-ru/lib...v=vs.110).aspx
https://msdn.microsoft.com/ru-ru/lib...v=vs.110).aspx
Правда в Unity не просто рефлексия, а там несколько сложнее. Но принцип один, в Unity ничего не объявлено, все ищется по по именам.
Вот вам пример:
using UnityEngine; using System.Reflection; /// <summary> /// Аналог SendMessage с более продвинутыми функциями. /// Посылает сообщения даже выключенным объектам. /// </summary> public static class Message { public static void InvokeMethod(this GameObject gameObject, string methodName) { foreach (Component c in gameObject.GetComponents<Component>()) { MethodInfo m = c.GetType().GetMethod(methodName); if (m != null) m.Invoke(c, null); } } public static void InvokeMethod(this GameObject gameObject, string methodName, params object[] parameters) { foreach (Component c in gameObject.GetComponents<Component>()) { MethodInfo m = c.GetType().GetMethod(methodName); if (m != null) m.Invoke(c, parameters); } } public static void InvokeMethodUpwards(this GameObject gameObject, string methodName) { Transform t = gameObject.transform; while (t) { foreach (Component c in t.gameObject.GetComponents<Component>()) { MethodInfo m = c.GetType().GetMethod(methodName); if (m != null) m.Invoke(c, null); } t = t.parent; } } public static void InvokeMethodUpwards(this GameObject gameObject, string methodName, params object[] parameters) { Transform t = gameObject.transform; while (t) { foreach (Component c in t.gameObject.GetComponents<Component>()) { MethodInfo m = c.GetType().GetMethod(methodName); if (m != null) m.Invoke(c, parameters); } t = t.parent; } } public static void BroadcastMethod(this GameObject gameObject, string methodName) { foreach (Component c in gameObject.GetComponentsInChildren<Component>()) { MethodInfo m = c.GetType().GetMethod(methodName); if (m != null) m.Invoke(c, null); } } public static void BroadcastMethod(this GameObject gameObject, string methodName, params object[] parameters) { foreach (Component c in gameObject.GetComponentsInChildren<Component>()) { MethodInfo m = c.GetType().GetMethod(methodName); if (m != null) m.Invoke(c, parameters); } } }
|
|
|
(Offline)
|
|