agiro agiro - 4 years ago 78
C# Question

Collect different functions to one delegate

I have different

functions
I want to be called from each other. They are all UI animations, one for rotate, one for scale, one for move, and so on. I wish to chain them, so at the end of a
coroutine
an event fires off if something else was subscribed. Currently I would have to create
delegates
for all of them which would make the code's extension unbearable. How to create a delegate - or a collection of delegates? - whose event can fire off a variety of functions?

EDIT:
The functions are not dependent on each other. Move moves only. Rotate rotates only and so on.
Only one instance of
Move
or
Rotate
can effect on one component.

class MoveClass : MonoBehaviour
{
#region Move
//to ensure only one mover coroutine can be active.
public IEnumerator moveRoutine = null;
/// <summary>
/// Moves a UnityEngine.GameObject from position A to position B over timeToReachDestination.
/// Uses Coroutines.
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
/// <param name="overTime"></param>
public void Move(Transform from, Transform to, float overTime)
{
//pull off this shit to ensure only once it will be executed.
if (moveRoutine != null)
{
StopCoroutine(moveRoutine);
}
moveRoutine = _Move(from, to, overTime);
StartCoroutine(moveRoutine);
//StartCoroutine(_Move(from, to, overTime));
}
IEnumerator _Move(Transform from, Transform to, float overTime)
{
Vector2 original = from.position;
float timer = 0.0f;
while (timer < overTime)
{
float step = Vector2.Distance(original, to.position) * (Time.deltaTime / overTime);
from.position = Vector2.MoveTowards(from.position, to.position, step);
timer += Time.deltaTime;
yield return null;
}
if(event != null)
{
event(/*parameters*/);
//or loop through the events?
}
}
#endregion
}

Answer Source

Seems like you want a callback at the end of your coroutine.

IEnumerator _Move(Transform from, Transform to, float overTime, Action /*<Parameter>*/ onCompletion = null)
{
    // Your current code

    if(onCompletion!= null)
    {
        onCompletion(/*parameters*/);
        //or loop through the events?
    }
}

EDIT: added onCompletion = null so it has default parameter.

Considering you may have different parameter list for the callback, you'd come up with various overloads. The common code would be move to a method that is called in all different overloads, only the last part would be different:

void MoveItem(Transform from, Transform to, float overTime)
{
     float step = Vector2.Distance(original, to.position) * (Time.deltaTime / overTime);
     from.position = Vector2.MoveTowards(from.position, to.position, step);
}
IEnumerator _Move(Transform from, Transform to, float overTime, Action onCompletion = null)
{
    Vector2 original = from.position;
    float timer = 0.0f;
    while (timer < overTime)
    {
        MoveItem(from, to, overTime);
        timer += Time.deltaTime;
        yield return null;
    }
    if(event != null)
    {
        event();
    }
}

    IEnumerator _Move(Transform from, Transform to, float overTime, Action <float>onCompletion = null)
{
    Vector2 original = from.position;
    float timer = 0.0f;
    while (timer < overTime)
    {
        MoveItem(from, to, overTime);
        timer += Time.deltaTime;
        yield return null;
    }
    if(event != null)
    {
        event(10.0f);
    }
}

You could push the flexibility to provide a delegate for the MoveItem method so you can pass any movement method (shape of the movement could be either linear, exponential and so on).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download