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)
|
|