Issue
I have some functions that take in an Enemy instance and change one of its fields. The Enemy class has some basic fields like speed, damage, attack range. Each function just stores one of the normal value of the enemy and then change the current field to some value for an amount of time and then change it back to the normal state (I code in Unity and use Coroutine for this). The difference is which field to store (speed or damage or attack range, etc). So I want to make a single function that takes in a delegate that returns the field that it wants to change:
delegate ref float Stat();
private IEnumerator EnemyStatModify(Enemies enemy, float duration, float percent, Stat stat)
{
ref float enemyStat = ref stat();
float normalStat = enemyStat;
enemyStat *= (1 - percent);
yield return new WaitForSeconds(duration);
enemyStat = normalStat;
}
and then use it like this
EnemyStatModify(enemy, state.duration, state.timeBtwHits, () => ref enemy.speed);
EnemyStatModify(enemy, state.duration, state.timeBtwHits, () => ref enemy.damage);
But Iterators can't have by-reference locals. How to bypass this?
Solution
You actually don't need the return value of your delegate. You also don't need the Enemies
since you don't use it in the routine anyway.
This is of course still not as beautiful as ref
parameters would be but you could simply use a callback like
delegate void Stat(float newValue);
private IEnumerator EnemyStatModify(float duration, float percent, float currentValue, Stat onUpdated)
//or
//private IEnumerator EnemyStatModify(float duration, float percent, float stat, Action<float> onUpdated)
{
onUpdated?.Invoke(currentValue * (1 - percent));
yield return new WaitForSeconds(duration);
onUpdated?.Invoke(currentValue);
}
and call it like
StartCoroutine(EnemyStatModify(state.duration, state.timeBtwHits, enemy.speed, (newValue) =>
{
enemy.speed = newValue;
}));
StartCoroutine(EnemyStatModify(state.duration, state.timeBtwHits, enemy.damage, (newValue) =>
{
enemy.damage = newValue;
});
Instead of the Stat
you could also just use a Action<float>
Answered By - derHugo Answer Checked By - Cary Denson (PHPFixing Admin)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.