Проблема с делегатами и событиями в Unity

146
21 февраля 2018, 07:44

Не могу разобраться как использовать делегаты и события в проекте Unity.
У меня есть класс Observer

public class Observer : MonoBehaviour 
{
   #region Singletone
   private static Observer _instance;
   public static Observer Instance
   {
       get
       {
           if (!_instance)
           {
               _instance = FindObjectOfType(typeof(Observer)) as Observer;
               if (_instance == null)
               {
                   Debug.Log("Error!");
               }
           }
           return _instance;
       }
   }
   #endregion
   public delegate void GivePoints(int value);
   public static event GivePoints OnGivePoints; 
}

У меня есть метод Death в скрипте зомби:

public void Death()
{
    if (Observer.OnGivePoints != null)
    {
        Observer.Instance.OnGivePoints(5);
    }
}
public void GivePoints(int value)
{
    Debug.Log(value);
} 

Также в методе старт в скрипте зомби написано:

void Start()
{
    Observer.OnGivePoints += GivePoints;
}

Вроде всё сделал правильно, но в строке Observer.OnGivePoints != null ругается на OnGivePoints, пишет: "The event OnGivePoints only appear on the left hand side of += or -= (except when used from within the type 'Observer')

Использовал паттерн Observer по этому видеоуроку, и код собственно тоже оттуда взял - https://www.youtube.com/watch?v=qwQ16sS8FSs, у него всё работает почему-то

Answer 1

Здравствуйте. Вы вызываете событие в классе зомби, а не в классе Observer.

Т.е. у вас ошибка здесь:

У меня есть метод Death в скрипте зомби:

public void Death()
{
    if (Observer.OnGivePoints != null)
    {
        Observer.Instance.OnGivePoints(5);
    }
}

В этой строчке Observer.OnGivePoints != null идет вызов события, о чем вам говорится в сообщении об ошибке - что можно только подписаться или отписаться от события (+= or -= ), а проверять его на null нужно в классе Observer. Т.е. проверка на null и вызов события вам надо перенести в класс, где это событие объявлено, либо объявляйте делегат и событие в классе зомби.

Answer 2

Смысл события заключается в том, чтобы его можно было вызвать только из объекта, в классе которого оно объявлено. А извне можно только подписаться или отписаться от него.

Я так понимаю, после смерти зомби, Вам надо прибавить игроку очки? Тогда будет логичнее создать событие в классе зомби и вызывать его после смерти зомби изнутри этого же класса.

В видео уроке же событие нужно для нанесение врагу урона. Урон наносит игрок, поэтому и объявлено событие в классе игрока. Из класса игрока событие и вызывается.

READ ALSO
Как создать измененный exe c# [требует правки]

Как создать измененный exe c# [требует правки]

Есть форма туда вводишь данные и должен создаваться билд программы с измененными данными

183
C# Как ускорить поиск?

C# Как ускорить поиск?

У меня есть клас в котором есть List обьектов другого класа в котором есть еще один List обьектов другого класаМне нужно сравнить найти обьект...

187
как удалить куки, очистить куки в xNet c#

как удалить куки, очистить куки в xNet c#

как удалить куки, очистить куки в xNet c#

232