2016-08-20 2 views
0

Я пытаюсь создать статус-эффект для своей игры, это те вещи, которые влияют на статистику вашего игрока с течением времени, например. Однако у меня возникают проблемы с запоминанием переданной переменной, то есть той, которая должна быть изменена. Допустим, у вас есть некоторый статусный эффект, который снижает ваше здоровье на 10% в течение 10 секунд, как я это делаю, создавая экземпляр нового класса, передавая некоторые параметры вместе с переменной, которая должна быть изменена в этом случае для здоровья игрока, но проблема заключается в том, что после того, как конструктор исчез, ссылка прерывается между этими 2, а затем я просто редактирую некоторую переменную, которая никогда не используется.Хранить ссылку переменной типа значения C#

Вот как я экземпляр Status Effect

/// <summary> 
    /// Creates a status effect which ticks at specified period of time without any condition. 
    /// </summary> 
    public StatusEffect(float increase, EffectIncreaseType increaseType, float timeOfStatusEffect, float tickTime) 
    { 
     this.increase = increase; 
     this.endTimeOfStatusEffect = Time.time + timeOfStatusEffect; 
     this.tickTime = tickTime; 
     increaseCalculator = increaseType == EffectIncreaseType.Percentage ? increaseCalculator = (a) => (int)(increase/100f * a) : increaseCalculator = (a) => (int)increase; 
    } 

И вот, как я использую его теперь

public bool TryTrigger(ref int affectedProperty) 
    { 
     if (condition.Invoke(affectedProperty)) 
     { 
      affectedProperty += increaseCalculator.Invoke(affectedProperty); 
     } 
     return condition.Invoke(affectedProperty); 
    } 

Это не то, что я хочу в первую очередь это требует поле, чтобы быть переданы в метод TryTrigger, а не свойство, во-вторых, вы не должны знать, какая переменная требуется все время, которую вы должны просто передать в начале, а затем попробуйте запустить ее с помощью самого класса, работающего с этой переменной на заднем этапе. Это возможно ? Есть ли лучший способ сделать Status Effects (DoT, HoT)? Также я хотел бы сделать эту работу для мгновенного изменения статуса, например, снизить ваше здоровье на 30% в течение 1 минуты, но я не уверен, что моя текущая настройка подходит для этого.

+0

Это совершенно неправильно в среде Единства, Асимм. Для procs просто используйте это ... http://stackoverflow.com/a/36249404/294884 – Fattie

+0

И для тривиальных таймеров в Unity вы просто используете 'Invoke' или' InvokeRepeating'. – Fattie

ответ

4

Невозможно сохранить «ref» для переменной в .NET; это преднамеренно. Это исключает класс ошибок, распространенных в C/C++, где вы храните ref до переменной за всю свою жизнь, и происходят плохие вещи.

Способ, которым вы хотите, вместо этого передать Action<T>, который устанавливает переменную (или свойство), которую вы хотите изменить, а затем, когда вы хотите ее изменить, вы вызываете действие.

Как же это решить проблему? Поскольку C# гарантирует, что переменная, захваченная делегатом, всегда долговечна.

+0

Как это сейчас (я не говорю, что он работает так, как я его хочу, или проблема исправлена) заключается в том, что я постоянно вызываю функцию TryTrigger, передавая соответствующую переменную, но я просто ее тестирую, и я точно знаю, какая переменная я буду нуждаться в дальнейшем, когда разные классы передают некоторую переменную этому, он станет беспорядочным, и моя текущая настройка не будет работать. – Asimm

+0

Но Эрик, это значит, я должен вычислить все вещи за пределами этого класса, чтобы я мог передать его этому правилу? – Asimm

+0

@Asimm: вы все еще можете рассчитать все свои вещи внутри своего класса и просто передать двух делегатов; сеттер и получатель, которые ничего не делают, кроме как получить или установить свойство на вашем объекте. например: «Действие setter = (newValue) => {a.Weight = newValue; }; ' –

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