Demigiant Forum

Unity Assets => DOTween & DOTween Pro => Topic started by: cynicalwanderer on April 21, 2015, 02:16:24 AM

Title: Adding a Tween to a sequence by its ID
Post by: cynicalwanderer on April 21, 2015, 02:16:24 AM
Hi,

I've got some DOTween Pro component tweens added on some uGUI panels that I have given ID names to in the inspector, and I'm wanting to collect these tweens up in a sequence so I can fire them all off via code.

This works:
Code: [Select]
DOTween.Restart ("HUDPanelTopIn");
DOTween.Restart ("HUDPanelLeftIn");
DOTween.Restart ("HUDPanelRightIn");

However I'm not sure how to insert into the sequence using those ID strings.  E.g. after looking at the doco I tried writing a little function that polls :

Code: [Select]
vHUDPanelsIn = DOTween.Sequence ();
vHUDPanelsIn.Insert (0.0f, FindTween ("HUDPanelTopIn"));
vHUDPanelsIn.Insert (0.0f, FindTween ("HUDPanelLeftIn"));
vHUDPanelsIn.Insert (0.0f, FindTween ("HUDPanelRightIn"));

...

private Tween FindTween (string pTweenName)
{
Tween vReturnTween = null;

List<Tween> vFindTweenList = DOTween.TweensById (pTweenName);
if (vFindTweenList != null)
{
foreach (Tween vFindTween in vFindTweenList)
{
if (vFindTween != null)
{
vReturnTween = vFindTween;
break;
}
}
}

return vReturnTween;
}

which I had hoped would do it, however the "DOTween.TweensById" seems to be returning a null list.

Am I doing something wrong?  Is there an easier way to get the tween object by ID for use in a sequence?

Title: Re: Adding a Tween to a sequence by its ID
Post by: Daniele on April 21, 2015, 02:54:50 AM
Hi,

I never thought of using visual editor tweens in a Sequence. In theory, that should be possible as long as the tweens are not set to AutoPlay (because a tween can be added to a Sequence only before it starts). I can't test it now (3AM here and I'm going to bed), but your approach should work. The only reason I can think of why TweensById is not returning you anything, is because you're maybe calling it before the tweens are created? If you're calling your FindTween method inside Awake, try with Start.

Let me know, and cheers.

P.S. on a side note, I have in my "maybe" list the idea of creating a new visual editor panel that will allow you to create Sequences of tweens connected to different gameObjects.
Title: Re: Adding a Tween to a sequence by its ID
Post by: cynicalwanderer on April 21, 2015, 09:00:55 AM
Yes, AutoPlay is off and the sequence is being constructed well after Awake, so it's not that.

I've checked a few of your other list commands such as TweensByTarget (off the GameObject holding them) and PausedTweens and those seem to bring up their tweens list just fine, so they are definitely there and don't appear to have started yet.  It's only TweensById that doesn't seem to be working and unfortunately that's the one I need to be able to identify them via string.  Could that function be not picking up the visual editor ones perhaps?

I also tried as an alternative option having public inspector Tween or Tweener variables in the code and then dragging the tween directly onto the variable in inspector to access it that way, which is a trick I've used before in another product, but that didn't work either.  Is it possible for these types to be exposed in the inspector as well when public, to further allow for any visual editor tweens to be attached and then identified in the code?

Visual sequences would be very nice.   :)  As would having a "tween" for setting UI objects to enabled/disabled or visible/invisible to include in those sequences.  For example some of my sequences involve a rotation where at the peak of the rotate, one sprite swaps out and another swaps in.  It would be great if I could work the timing of those bool changes into the tween sequence chain and have it all handled there.
Title: Re: Adding a Tween to a sequence by its ID
Post by: cynicalwanderer on April 21, 2015, 11:14:54 AM
FYI in case it helps anyone else I have got around this for now by using this:

Code: [Select]
private Tween FindTween (string pUIObjectName,
                         string pTweenName)
{
Tween vReturnTween = null;

GameObject vUIObject = GameObject.Find (pUIObjectName).gameObject;
if (vUIObject != null)
{
List<Tween> vFindTweenList = DOTween.TweensByTarget (vUIObject);
if (vFindTweenList != null)
{
foreach (Tween vFindTween in vFindTweenList)
{
if (vFindTween                != null &&
    vFindTween.id.ToString () == pTweenName)
{
vReturnTween = vFindTween;
break;
}
}
}
}

return vReturnTween;
}

this lets me construct sequences as follows:

Code: [Select]
// Construct HUD in sequence
vHUDPanelsIn = DOTween.Sequence ();
vHUDPanelsIn.Insert (0.0f, FindTween ("HUDPanelTop",   "HUDPanelTopIn"));
vHUDPanelsIn.Insert (0.0f, FindTween ("HUDPanelLeft",  "HUDPanelLeftIn"));
vHUDPanelsIn.Insert (0.0f, FindTween ("HUDPanelRight", "HUDPanelRightIn"));


and trigger it in the code just with:

Code: [Select]
public void ShowHUD ()
{
// Restart and play the tweens
vHUDPanelsIn.Restart ();
}


It'd still be nice to know what's going on with TweensById not working, but I can at least proceed now.  Thanks!
Title: Re: Adding a Tween to a sequence by its ID
Post by: Daniele on April 21, 2015, 01:31:39 PM
Hi,

I'm back. Will have to work on a thing for the next hour, but then I'll jump on this issue, because if TweensById isn't working that can only be a bug and I'll fix it :)

About the other questions, you can't assign a DOTweenAnimation tween to a public Inspector variable, because the tween is created at startup. But you can assign the DOTweenAnimation itself (regardless of which one, in case you have more), and then call

Code: [Select]
myDOTweenAnimation.GetTweens();
which returns a list of all tweens created by all DOTweenAnimations on the gameObject (which, after all, is like calling

Code: [Select]
DOTween.TweensByTarget (myGameObject);
About the enable/disable request, I'm adding it to my todo list.
Title: Re: Adding a Tween to a sequence by its ID
Post by: Daniele on April 21, 2015, 05:54:10 PM
TweensById did have a bug with tweens created by DOTween Pro, sorry for that. Download this new version of DOTween (http://dotween.demigiant.com/download.php) (just replace the DOTween folder with the one inside the download) and it'll be fixed.
Title: Re: Adding a Tween to a sequence by its ID
Post by: cynicalwanderer on April 21, 2015, 07:31:14 PM
Great, thanks, I'll give that a try.  I had worked around it using TweensByTarget but this fix will be better.

For the booleans, after playing with it further, that feature seems to be able to be worked around already via your tween events, so I'm now using the GameObject.SetActive call off the OnComplete event.  So it's all good there, if a little clunky with needing to store the objects in code so they can be re-enabled later, but that's a Unity limitation anyway.  Hopefully one day Unity will add an actual visibility flag on the canvas renderer and make a lot of people happier.   :D

Cheers, and thanks for the quick response!

Title: Re: Adding a Tween to a sequence by its ID
Post by: Daniele on April 21, 2015, 08:18:26 PM
Glad you're getting it to work.

About the visibility, I'm thinking of a way to be able to activate/deactivate a gameObject via a checkbox in the DOTweenAnimation Inspector. Or maybe to instead add a
Code: [Select]
DOTweenAnimation.DOSetActive(bool active) which could be used via the visual tween events.

Cheers!
Title: Re: Adding a Tween to a sequence by its ID
Post by: cynicalwanderer on April 24, 2015, 08:50:22 PM
Hi again,

I've been using my tween finder approach and it's been working fine, so I am now ramping up the number of tweens and sequences. 

I'm currently pre-loading 4 sequences at start time, each with about seven tweens that have ID strings of on average about 25 letters.  However, there seems to be some hard limit getting hit in the dll, as once I get beyond a certain amount of these it gives me:

Code: [Select]
IndexOutOfRangeException: Array index is out of range.
DG.Tweening.Core.TweenManager.RemoveActiveTween (DG.Tweening.Tween t) (at D:/DG/_Develop/__UNITY3_CLASSES/_Holoville/__DOTween/_DOTween.Assembly/DOTween/Core/TweenManager.cs:786)
DG.Tweening.Core.TweenManager.AddActiveTweenToSequence (DG.Tweening.Tween t) (at D:/DG/_Develop/__UNITY3_CLASSES/_Holoville/__DOTween/_DOTween.Assembly/DOTween/Core/TweenManager.cs:165)
DG.Tweening.Sequence.DoInsert (DG.Tweening.Sequence inSequence, DG.Tweening.Tween t, Single atPosition) (at D:/DG/_Develop/__UNITY3_CLASSES/_Holoville/__DOTween/_DOTween.Assembly/DOTween/Sequence.cs:56)
DG.Tweening.TweenSettingsExtensions.Insert (DG.Tweening.Sequence s, Single atPosition, DG.Tweening.Tween t) (at D:/DG/_Develop/__UNITY3_CLASSES/_Holoville/__DOTween/_DOTween.Assembly/DOTween/TweenSettingsExtensions.cs:441)

I've tried rearranging the order of the sequence inserts to see if I could identify the culprit, but there doesn't seem to be a particular one it's dying on.  I'm speculating perhaps some buffer is getting filled up in the DLL of a maximum size of some sort hardcoded there?

Anyway, hopefully you can track it down from the line numbers there in the error.  In the meanwhile I'll be looking into a workaround.  Cheers!
Title: Re: Adding a Tween to a sequence by its ID
Post by: Daniele on April 24, 2015, 09:27:38 PM
Agh, that error shouldn't be there at all. I can't find a way to replicate it, and it's a very sneaky one. Any chance you could send me your project so I can test it there? Or if you manage to create a barebone replica it would be even better.
Title: Re: Adding a Tween to a sequence by its ID
Post by: cynicalwanderer on April 24, 2015, 10:07:29 PM
Ok, let me see if I can reproduce it in a stripped down version.  What's the best process for sending you the project files?
Title: Re: Adding a Tween to a sequence by its ID
Post by: Daniele on April 24, 2015, 10:27:51 PM
Thanks! Upload it using something like Dropbox or Mediafire or anything like that, and send me the link via Personal Message (click on the balloon icon below my avatar). If you have problems uploading it somewhere, write me a message anyway and I'll share my mail with you, so you can simply attach it there.
Title: Re: Adding a Tween to a sequence by its ID
Post by: cynicalwanderer on April 24, 2015, 10:48:57 PM
Ok, I've put a reproduction of the issue on Dropbox, which I have installed but have never used, so hopefully this works - please let me know if it's not accessible.  I'll PM you the link.

On the UI Canvas object you will see my "HUDManager" scripts.  There's a bool on the inspector called vDebugSequenceIssue which when true will cause the error on startup, but when false will allow at least the portion before the error to go through so that the HUD buttons sort of work and show the tweens. 

Anyway the function in the code where I've left some comments about the error is SetupSequences.

Thanks for taking a look!
Title: Re: Adding a Tween to a sequence by its ID
Post by: Daniele on April 25, 2015, 12:48:45 AM
It worked! :)


Gonna take a look now, but if it starts getting too complicated I will continue tomorrow (almost 1AM here). And thanks to you for sending me the bugged project. I hate bugs. Will squash them all!
Title: Re: Adding a Tween to a sequence by its ID
Post by: cynicalwanderer on April 25, 2015, 01:22:29 AM
Sure, no rush - it's midnight here and I'm finishing up for the night myself.  I've got plenty of my own bugs elsewhere in my project that I can tackle in the meantime, so I know what you mean!
Title: Re: Adding a Tween to a sequence by its ID
Post by: Daniele on April 25, 2015, 01:24:03 AM
I managed and found the issue! With vDebugSequenceIssue set to TRUE, you were trying to add the same tween to multiple Sequences, which can't be done. I now updated DOTween to safely prevent that instead of throwing an error. Grab the version attached here and overwrite with it the Demigiant/DOTween folder (you'll also have to run DOTween's Setup from the Utility Panel again).
Title: Re: Adding a Tween to a sequence by its ID
Post by: cynicalwanderer on April 25, 2015, 10:38:02 AM
Ah, ok - that explains it.  I had been thinking that Sequence could be used as a way of grouping shared tweens that are to be used in more than one context, and assumed that there could be reuse of the same tweens in different sequences.  Apparently not.  All right, I guess I'll have to have handle separate copies of each one for its usage.

Hopefully this also explains another bug I was experiencing, where some tweens were strangely firing when they shouldn't, even though they weren't part of the sequence being called.  I'll see if that problem goes away now after fixing for this one.

Thanks for your effort in tracing the problem so quickly.
Title: Re: Adding a Tween to a sequence by its ID
Post by: cynicalwanderer on April 25, 2015, 11:19:36 AM
Okay, the other bug is still there.  This one can also be reproduced using that same sample project, if you set the vDebugSequenceIssue flag unchecked.

In the UI Canvas -> HUDPanelRight -> HUDMenuSprite object, you'll see a DOTween called HUDMenuSpriteFlashUp - the third one down.  This is just scaling the sprite up to 1.5, and as you can see Autoplay is off.  Clicking the "Show HUD" button will bring in the panels but not yet touch this tween, which is only supposed to happen later when you hit "Hide HUD".

Now however, if you change the tween direction from "TO" to "FROM" and do the "Show HUD" you'll see that the scale on the sprite is getting bumped up to 1.5 immediately even though the tween hasn't run yet.  Further investigation shows that the scaling is actually happening on the object even before clicking "Show HUD".  So it looks to me like DOTween is searching for any "FROM" scalars and applying them at startup when the tween is loading, instead of applying them at the time of playing the tween, which is what I would have expected it to do.  I have also reproduced this with my Rotate tweens as well, where I used "FROM".

Am I mistaking the usage of "FROM" here?  I would have thought that if I play a Scale tween of FROM 1.5, on an object with the scale currently at 1, that it would lerp the scale backwards from 1.5 down to 1.  Is that correct understanding?  Instead, because DOTween seems to be changing the scale to 1.5 at startup even before the tween runs, it's effectively tweening from the parameter 1.5 back to its already altered 1.5 and so it stays large and never goes back to 1 as intended.

Anyway, please advise if this is something I need to do differently, or if this is actually a bug of DOTween acting on the FROM changes in advance of its tween playing.

EDIT: I think I know what I've done wrong now.  I was firing off both the scale up and down tweens at the same time, with the down tween having a delay so that it was intended to fire off after the up tween finished.  Foolishly I thought that would take the "current value" as at the time the delay ended, but clearly it's taking it from the time the tween plays instead.

I'll see if I can get the same functionality working more appropriately using OnComplete event to call the next tween.
Title: Re: Adding a Tween to a sequence by its ID
Post by: cynicalwanderer on April 25, 2015, 12:30:09 PM
Okay, I'm getting closer, I think.

Because I have multiple reusable tweens on each UI object, I couldn't assign the event to the correct function using DG.Tweening.DOTweenAnimation dropdown option, because that dropdown doesn't distinguish which of the multiple tweens to access a function for, and it just calls the first one it finds.  It would be nice if a particular tween could be chosen to fire in an OnComplete, but since it can't, for now instead I'm using my string based tween play function to kick the chain off at appropriate times using the events.

Which seems to work for the first iteration.  However it doesn't work the second time after that - perhaps the tween is getting killed off when executed this way, or something, even though AutoKill is turned off and my function uses Restart().  I'll keep investigating.  It does seem to me though that DOTween seems to be focused more on single-use "play at instantiation" type tweens that are expected to get killed off, rather than reusable tweens for persistent GUI objects.  Anyway, I'm sure a solution will arise.   :)
Title: Re: Adding a Tween to a sequence by its ID
Post by: Daniele on April 25, 2015, 01:30:05 PM
Hi,

About FROM, you're right: it is set as soon as the tween starts.

And about the dropdown, sadly that's a Unity issue, where there is no way to assign a specific Component (if multiple Components of the same type are present on the same GameObject) as an Inspector reference. That's why I added methods like DOPlayById or DOPlayNext (which plays the next tween on a Component, following a top-down order, that is not already playing, until its internal "tweens counter" reached the end).

About your Sequencing issues, even if DOTweenAnimation was not built to be used with Sequences, that should work. Are you Restarting the Sequence, and not the tween? After you investigate more, send me another repo so I will help you out.

Oh, and I can assure you that DOTween is definitely not focused on a single "play at instantiation" logic, quite the contrary (my tween workflow is most of the time focused on reusing existing tweens instead of "fire and forget").

P.S. I don't know if I mentioned this already, but I'm working on a Visual Editor Sequencing panel to add to DOTween Pro. It won't be tied to a single gameObject and will return a Sequence, so it should be perfect for your case. But before doing that, I'm refactoring some internal parts of DOTweenAnimation/Path, so they will share a common architecture/logic, thus it might take a while.
Title: Re: Adding a Tween to a sequence by its ID
Post by: cynicalwanderer on April 25, 2015, 04:50:49 PM
Okay, thanks for the explanation.  I hadn't spotted the DOPlayById and DOPlayNext - will give those a try, and they should be better than my current method.

I was restarting the sequence actually, and had been assuming that doing so would also restart the tweens inside it.  For the time being, I've switched to using code to trigger my tween chain rather than sequences, but I'll give those another try when the Visual Sequencing editor become available.