При разработке игр, довольно часто возникает необходимость в построении системы широковещательной рассылки сообщений. Предположим, Вы хотите сделать так, чтобы в тот момент когда персонаж, управляемый игроком, вошел в определенную зону, или выполнил определенное действие, все заинтересованные в этом объекты получили уведомление. По возможности это уведомление должно нести в себе информацию о произошедшем событии. В данной статье, я предлагаю Вашему вниманию один из возможных способов построения подобной системы. Приведенная система построена на базе Unity3D EventSystem.
Начиная с версии 4.6 в состав Unity3D включена UI System, значительно упрощающая процесс создания UI. К тому же она является Open Source проектом. В основе этой системы лежат два очень важных компонента — EventSystem и InputModules, позволяющие принимать и обрабатывать события. По сути, InputModules — это обычные компоненты. Они являются наследниками UIBehaviour который в свою очередь наследует MonoBehaviour и содержат в себе логику обработки событий, поступающих от EventSystem.
Отправка события определенному GameObject осуществляется посредством вызова метода ExecuteEvents.Execute(). Определение метода имеет следующий вид:
public static bool Execute<T>(GameObject target, BaseEventData data, EventFunction<T> functor) where T : IEventSystemHandler;
public abstract class BroadcastInputModule<TEventType> : BaseInputModule
where TEventType : IEventSystemHandler
{
protected override void Awake()
{
base.Awake();
BroadcastReceivers.RegisterBroadcastReceiver<TEventType>(gameObject);
}
protected override void OnDestroy()
{
base.OnDestroy();
BroadcastReceivers.UnregisterBroadcastReceiver<TEventType>(gameObject);
}
}
[AddComponentMenu("Event/Something Happened Input Module")]
public class SomethingHappenedInputModule
: BroadcastInputModule<ISomethingHappenedEventHandler>, ISomethingHappenedEventHandler
{
public void OnSomethigHappened(SomethingHappenedEventData data)
{
Debug.Log("SomethingHappenedInputModule::OnSomethigHappened()");
}
public override void Process()
{
}
}
public interface ISomethingHappenedEventHandler : IEventSystemHandler
{
void OnSomethigHappened(SomethingHappenedEventData data);
}
public static class BroadcastReceivers
{
private static readonly IDictionary<Type, IList<GameObject>>
BroadcstReceivers = new Dictionary<Type, IList<GameObject>>();
public static IList<GameObject> GetHandlersForEvent<TEventType>()
where TEventType : IEventSystemHandler
{
if (!BroadcstReceivers.ContainsKey(typeof (TEventType)))
{
return null;
}
return BroadcstReceivers[typeof (TEventType)];
}
public static void RegisterBroadcastReceiver<TEventType>(GameObject go)
where TEventType : IEventSystemHandler
{
if (BroadcstReceivers.ContainsKey(typeof(TEventType)))
{
BroadcstReceivers[typeof(TEventType)].Add(go);
}
else
{
BroadcstReceivers.Add(typeof(TEventType), new List<GameObject>());
BroadcstReceivers[typeof(TEventType)].Add(go);
}
}
public static void UnregisterBroadcastReceiver<TEventType>(GameObject go)
{ . . . }
}
public static class BroadcastExecuteEvents
{
public static void Execute<T>(BaseEventData eventData, ExecuteEvents.EventFunction<T> functor)
where T : IEventSystemHandler
{
var handlers = BroadcastReceivers.GetHandlersForEvent<T>();
if (handlers == null) return;
foreach (var handler in handlers)
{
ExecuteEvents.Execute<T>(handler, eventData, functor);
}
}
}
BroadcastExecuteEvents.Execute<ISomethingHappenedEventHandler>(null, (i, d) => i.OnSomethigHappened(new SomethingHappenedEventData()));
К сожалению, не доступен сервер mySQL