2017-02-11 2 views
3

Хорошо, я немного смущен. Я изучил UnityEvent и систему обмена сообщениями this. Но у меня есть один вопрос, который я не могу понять. Как передать аргументы функции Invoking?Пропустить аргумент UnityEvent

Например (я имею EventManager как в учебнике):

void OnEnable() { 
     EventManager.StartListening ("OnPlayerTeleport", TeleportPlayer); 
    } 

    void OnDisable() { 
     EventManager.StopListening ("OnPlayerTeleport", TeleportPlayer); 
    } 

    void TeleportPlayer() { 
     float yPos = transform.position.y; 
     yPos += 20.0f; 
     transform.position = new Vector3 (transform.position.x, yPos, transform.position.z); 
    } 

И у меня есть триггер:

void Update() { 
    if (Input.GetButtonDown ("Teleport")) { 
     EventManager.TriggerEvent ("OnPlayerTeleport"); 
    } 
} 

Но что, если я хочу передать значение 'высоты' функционировать «TeleportPlayer ':

void TeleportPlayer (float h) { 
    float yPos = transform.position.y; 
    yPos += h; 
    transform.position = new Vector3 (transform.position.x, yPos, transform.position.z); 
} 

Как это сделать?

ответ

1

Использовать делегат C#/Действие вместо UnityEvent Unity. Это быстрее, чем событие Unity. Несколько дней назад я портировал it. Вам просто нужно немного изменить это, чтобы получить то, что вы ищете.

.Make Action принять float, изменив все Action декларацию Action<float>, что означает, что это позволит функции с float параметром.

.Теперь, сделать функцию TriggerEvent принять параметр float. путем изменения

public static void TriggerEvent(string eventName) 

в

public static void TriggerEvent(string eventName, float h) 

Вот новый EventManager сценарий.

using UnityEngine; 
using System.Collections.Generic; 
using System; 

public class EventManager : MonoBehaviour 
{ 

    private Dictionary<string, Action<float>> eventDictionary; 

    private static EventManager eventManager; 

    public static EventManager instance 
    { 
     get 
     { 
      if (!eventManager) 
      { 
       eventManager = FindObjectOfType(typeof(EventManager)) as EventManager; 

       if (!eventManager) 
       { 
        Debug.LogError("There needs to be one active EventManger script on a GameObject in your scene."); 
       } 
       else 
       { 
        eventManager.Init(); 
       } 
      } 

      return eventManager; 
     } 
    } 

    void Init() 
    { 
     if (eventDictionary == null) 
     { 
      eventDictionary = new Dictionary<string, Action<float>>(); 
     } 
    } 

    public static void StartListening(string eventName, Action<float> listener) 
    { 

     Action<float> thisEvent; 
     if (instance.eventDictionary.TryGetValue(eventName, out thisEvent)) 
     { 
      thisEvent += listener; 
     } 
     else 
     { 
      thisEvent += listener; 
      instance.eventDictionary.Add(eventName, thisEvent); 
     } 
    } 

    public static void StopListening(string eventName, Action<float> listener) 
    { 
     if (eventManager == null) return; 
     Action<float> thisEvent; 
     if (instance.eventDictionary.TryGetValue(eventName, out thisEvent)) 
     { 
      thisEvent -= listener; 
     } 
    } 

    public static void TriggerEvent(string eventName, float h) 
    { 
     Action<float> thisEvent = null; 
     if (instance.eventDictionary.TryGetValue(eventName, out thisEvent)) 
     { 
      thisEvent.Invoke(h); 
     } 
    } 
} 

Тест:

public class Test : MonoBehaviour 
{ 

    void OnEnable() 
    { 
     EventManager.StartListening("OnPlayerTeleport", TeleportPlayer); 
    } 

    void OnDisable() 
    { 
     EventManager.StopListening("OnPlayerTeleport", TeleportPlayer); 
    } 

    void Update() 
    { 
     if (Input.GetButtonDown("Teleport")) 
     { 
      EventManager.TriggerEvent("OnPlayerTeleport", 5); 
     } 
    } 

    void TeleportPlayer(float h) 
    { 
     float yPos = transform.position.y; 
     yPos += h; 
     transform.position = new Vector3(transform.position.x, yPos, transform.position.z); 
    } 
} 
+1

Хорошо, спасибо. Но могу ли я задать еще один вопрос? Что делать, если у меня есть много функций, а некоторые из них имеют аргументы «float», некоторые - «string», а некоторые - без аргументов? –

+0

@ AlexandrKöln Это сложно оттуда, но может быть сделано. Вы можете создать класс под названием AllData, а затем все переменные в нем. Может быть, строки массивов или поплавки. Затем измените параметр float на этот класс класса AllData. Теперь вы можете передать класс, содержащий всю вашу информацию. – Programmer

+1

Другим способом является использование ключевого слова 'params' для передачи неограниченных переменных. Вместо создания типа 'float или' string', сделайте его 'object'. Затем вы можете передать объект или из 'float' или' string'. Мой совет вам должен пройти только то, что вам нужно. Не создавайте EventSystem, которая может передавать каждый тип данных в свой параметр. Это замедлит вашу игру. – Programmer

Смежные вопросы