Demigiant / dotween

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

IndexOutOfRangeException: Index was outside the bounds of the array. #647

Open wrymn opened 11 months ago

wrymn commented 11 months ago

Dozens of errors are printed into console when exiting play mode. I have no idea why, I cannot trace it, as I am using tweens across dozens of places across project, so no idea what is wrong.

Maybe in the DOTween code that generated exception, should be some check for the index so the exception does not happen in the next DOTween update :)

image

Also I get this as well every time exiting play mode, again, no idea where problem is or what may be causing this: image

wrymn commented 11 months ago

Okay so after debugging, the issue seems to be when playing multiple tweens on the same object, while others are still not finished. I used:

behaviour.transform.DOScale(scale, 0.1f).SetEase(Ease.OutBack);

but it seems in my code, other do scales on same transform may still have not finished, and when exiting play mode, it caused all these exceptions.

It was enough to complete all tweens on transform, as this:

DOTween.Complete(behaviour.transform);
behaviour.transform.DOScale(scale, 0.1f).SetEase(Ease.OutBack);

However, I still think this exception should be somehow guarded, or throw some meaningful error so other devs know what could be wrong in case this happens.

Decavoid commented 11 months ago

"Some objects were not cleaned up..." [DOTween].

This means that somewhere in your code you attempt to start a tween in OnDestroy() (maybe indirectly) of some GameObject. Don't start tweens in OnDestroy(). To find this GameObject you may have to grab the DOTween code and put it in your project replacing DOTween .dll's.

Demigiant commented 11 months ago

Going to test this now and see if I can replicate, so I can see what failsafes I can add.

Demigiant commented 11 months ago

P.S.

Okay so after debugging, the issue seems to be when playing multiple tweens on the same object, while others are still not finished

This shouldn't be the culprit (what @Andreyul said makes a lot more sense, at least for the exit problem) because conflicting tweens on the same property shouldn't create issues other than only one of them actually working (aka overwriting the others). It's a little puzzling but investigating

Demigiant commented 10 months ago

Update: I didn't manage to reproduce the indexOutOfRange error even when creating crazy combinations of tweens on the same object, but this morning I managed to replicate the "some objects were not cleaned up" error. So I went to open VS to apply some changes but it didn't open. So I updated it... boom, blue screen of death. And now every time I restart Windows I get a bsod if I'm connected to the internet 😬 Been trying to fix it all day but I might have to factory reset my pc so I apologize but I might need at least a couple days to get back to this. Now I go to bang my head against a wall 😬

wrymn commented 10 months ago

@Demigiant wow thats unexpected :( sorry to hear that, its insane that something so unrelated like tweens in unity can destroy a pc into bsod chain

Demigiant commented 10 months ago

Ohno it wasn't the tweens, it was the Visual Studio update that did something to Windows. Doing the factory reset now and hoping it works 🤞

lfg-ryan commented 9 months ago

I don't have a reliable dupe but we are also getting this in scenarios where we are starting a series of sequences, then killing them as they complete.

What seems to be happening is somehow duplicates are making there way into TweenManager._KillList

Then when the code iterates over them to call RemoveActiveTween so when object A goes through this function the first time its activeId is set to -1. When it goes through this a second time you get an indexOutOfRange exception TweenManager._activeTweens[activeId]

private static void RemoveActiveTween(Tween t)
{
      int activeId = t.activeId;
      if (TweenManager._totTweenLinks > 0)
        TweenManager.RemoveTweenLink(t);
      t.activeId = -1;
      TweenManager._requiresActiveReorganization = true;
      if (TweenManager._reorganizeFromId == -1 || TweenManager._reorganizeFromId > activeId)
        TweenManager._reorganizeFromId = activeId;
      TweenManager._activeTweens[activeId] = (Tween) null;

It would be good to find out how duplicates are getting into the list. Could be an that if something is explicitly added to the killlist by a callback or in the same frame its causing duplicates?

Either way I would strongly suggest just doing a activeId == -1 early out given when this dies in Unity it completely breaks DOTween and only a relaunch of the app can fix it.

lfg-ryan commented 9 months ago

This may be a similar issue to a bug I just posted with a solid repro.

https://github.com/Demigiant/dotween/issues/656

Basically this exception happens when a sequence gets added to _KillList twice. Which can easily happen if you ever call ManualUpdate as a result of some other callback.

j1mmie commented 8 months ago

Just ran into a similar one:

IndexOutOfRangeException: Index was outside the bounds of the array.
DG.Tweening.Core.TweenManager.RemoveActiveTween (DG.Tweening.Tween t) (at <81426fb2f082419eb14e96c5244705f0>:0)
DG.Tweening.Core.TweenManager.Despawn (DG.Tweening.Tween t, System.Boolean modifyActiveLists) (at <81426fb2f082419eb14e96c5244705f0>:0)
DG.Tweening.Core.TweenManager.DespawnActiveTweens (System.Collections.Generic.List`1[T] tweens) (at <81426fb2f082419eb14e96c5244705f0>:0)
DG.Tweening.Core.TweenManager.Update (DG.Tweening.UpdateType updateType, System.Single deltaTime, System.Single independentTime) (at <81426fb2f082419eb14e96c5244705f0>:0)
DG.Tweening.Core.DOTweenComponent.Update () (at <81426fb2f082419eb14e96c5244705f0>:0)

This unfortunately happened in my multiplayer game's playtest, and all 45 players clients simultaneously froze and had to restart :X What's interesting though is that it doesn't seem like some sort of race condition since it happened to literally every player. There should be a 100% repro case, but I haven't figured it out yet.