Demigiant / dotween

A Unity C# animation engine. HOTween v2
http://dotween.demigiant.com
Other
2.3k stars 346 forks source link

OnComplete on Reversed loop #617

Open EricBatlle opened 1 year ago

EricBatlle commented 1 year ago

I'm trying to achieve this:

using DG.Tweening;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Menu : MonoBehaviour
{
    [SerializeField] private List<GameObject> menuButtons = new List<GameObject>();

    [SerializeField] protected float duration = 0.35f;
    [SerializeField] protected Ease easeIn = Ease.OutBack;
    [SerializeField] protected Ease easeOut = Ease.InBack;

    private Sequence menuTween = null;

    private void Awake()
    {
        menuTween = DOTween.Sequence();
        foreach (var buttonGO in menuButtons)
        {
            buttonGO.GetComponent<Button>().onClick.AddListener(Close);
        }
    }

    private void Close()
    {
        if (menuTween.IsActive() && menuTween.IsPlaying())
            return;

        menuTween = DOTween.Sequence();

        foreach (var button in menuButtons)
        {
            menuTween.Append(button.transform.DOScale(Vector3.zero, duration).SetEase(easeOut).OnComplete(() => button.SetActive(false)));
        }
        menuTween.OnComplete(() => isOpen = false);
    }
}

But on reverse, there are two ways to achieve this, first one I can reverse the list on the foreach, or second one, use a for loop on the reverse order, something like:

for (int i = menuButtons.Count - 1; i > 0; i--)
{
    menuTween.Append(menuButtons[i].transform.DOScale(Vector3.zero, duration).SetEase(easeOut).onComplete(() => menuButtons[i].SetActive(false)));
}

But if I use this second method it always affect the menuButtons[0], so every time the lambda method is called, the i value seems 0, what is happening?

wiwii commented 1 year ago

i is sent the reference not a value to the inner looping function. so at the end, it will be 0 in you case