Search Unity

DOTween (HOTween v2), a Unity tween engine

Discussion in 'Assets and Asset Store' started by Izitmee, Aug 5, 2014.

  1. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    399
    Try using DOPunchScale and set "Vibrato" to "1" and "Elasticity" to "0".
     
  2. luniac

    luniac

    Joined:
    Jan 12, 2011
    Posts:
    503
    I been playing around with Visual Editor components.
    to my understanding, the tween values are editable ONLY in editor. At runtime there is NO editings of components.
    so if i need runtime tween editing, it can only be done in code by creating new tweens with new settings.
    Am i correct?
    thanks.
     
  3. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    399
    Do you mean for a DOTweenAnimation component? If so, you can access its tween since it's a public field. Have you tried?
     
  4. luniac

    luniac

    Joined:
    Jan 12, 2011
    Posts:
    503
    not accessible, check screenshot
    Capture.PNG
     
  5. gringo2012

    gringo2012

    Joined:
    Jul 6, 2012
    Posts:
    46
    Nice, thanks. It does indeed do what I wanted and I managed to get a nice effect out of it. I'll post a video later on.

    You're right, playing the loop 2 times with Yoyo is another way to go if I want it to return to the initial value, but it would play the tween forward, then backwards. I do get the initial scale of the object back, but not the effect that I want. Thanks for the reply
     
  6. Lecht

    Lecht

    Joined:
    Jul 1, 2014
    Posts:
    24
    upload_2018-1-28_14-16-29.png

    When I call DOTween.Play with an ID of 0 on this GameObject, it doesn't play. However if I use the other overload of DOTween.Play, it works. But I have 2 tweens and need to be able to specify which one.

    For reference this is the code I'm using:

    Code (CSharp):
    1. DOTween.Play(Shield, 0);
     
  7. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    399
    Well, you can't change the tween settings using Events, no (unless you write your own). But you can access and change the settings through scripting. That's what I thought you meant.

    What are you trying to do?
     
  8. gringo2012

    gringo2012

    Joined:
    Jul 6, 2012
    Posts:
    46
    Here's the video with the effect, thanks again (the animation of the GUI coin count in the top left corner, once you grab a coin)
     
  9. luniac

    luniac

    Joined:
    Jan 12, 2011
    Posts:
    503
    I wanted to have some UI buttons and sliders determine the tween values before playing the tween. Since events dont work directly, i guess ill have to have an intermediate script to access those values. Could be worse lol.

    although im not sure why i can't access them through event if they're public variables, i assume its cause the component is not a monobehavior.
     
  10. baldodavi

    baldodavi

    Joined:
    Nov 9, 2017
    Posts:
    4
    I've an issue with dotween, and can't understood cause of issue.
    Code (CSharp):
    1. Sequence seq = DOTween.Sequence();
    2.         seq.Append(ContainerTweens.DOFade(CharacterTurnedOnContainer, 1f, 0f));
    3.         seq.Append(ContainerTweens.DOFade(CharacterTurnedOnContainer, 0f, 1f));
    4.         seq.Append(ContainerTweens.DOFade(CharacterTurnedOnContainer, 1f, 0f));
    5.         seq.Append(ContainerTweens.DOFade(CharacterTurnedOnContainer, 0f, 1f));
    6.         seq.Append(ContainerTweens.DOFade(CharacterTurnedOnContainer, 1f, 0f));
    7.         seq.Play();
    8.  
    This cose is my goal ContainerTweens.DOFade is a my own function recursively inspect all childs and subchilds of a GameObject to find image or text and fade them all (you can find function on the last code insertion).
    Goal is fade out two times same GameObject. This Sequence don't work properly, the fourth tween going wrong.

    Next Sequence working like a charm
    Code (CSharp):
    1.  
    2. Sequence seq = DOTween.Sequence();
    3.         seq.Append(ContainerTweens.DOFade(CharacterTurnedOnContainer, 1f, 0f));
    4.         seq.Append(ContainerTweens.DOFade(CharacterTurnedOnContainer, 0f, 1f));
    5.         seq.Append(ContainerTweens.DOFade(CharacterTurnedOnContainer, 1f, 0f));
    6.         seq.OnComplete(() =>
    7.         {
    8.             Sequence seq1 = DOTween.Sequence();
    9.             seq1.Append(ContainerTweens.DOFade(CharacterTurnedOnContainer, 0f, 1f));
    10.             seq1.Append(ContainerTweens.DOFade(CharacterTurnedOnContainer, 1f, 0f));
    11.             seq1.Play();
    12.         });
    13.         seq.Play();
    14.  
    Any idea to understand better this behavior?
    Thanks in advance.
    David.

    Here you can find the DOFade function:
    Code (CSharp):
    1. public static Sequence DOFade(GameObject gameO, float alpha, float time)
    2.     {
    3.         Sequence seq = DOTween.Sequence();
    4.         List<Tween> tweens = DOFadeInternal(gameO, alpha, time);
    5.         //Debug.Log("TotalTweens: " + tweens.Count);
    6.         foreach(Tween tween in tweens)
    7.         {
    8.             seq.Join(tween);
    9.         }
    10.         return seq;
    11.     }
    12.  
    13.     private static List<Tween> DOFadeInternal(GameObject gameO, float alpha, float time)
    14.     {
    15.         //Debug.Log("FadeObj: " + gameO.name);
    16.         List<Tween> tweens = new List<Tween>();
    17.  
    18.         Image image = gameO.GetComponent<Image>();
    19.         if (image != null)
    20.         {
    21.             tweens.Add(image.DOFade(alpha, time));
    22.         }
    23.         Text text = gameO.GetComponent<Text>();
    24.         if (text != null)
    25.         {
    26.             tweens.Add(text.DOFade(alpha, time));
    27.         }
    28.  
    29.         int childN = gameO.transform.childCount;
    30.         for (int i = 0; i < childN; i++)
    31.         {
    32.             tweens.AddRange(DOFadeInternal(gameO.transform.GetChild(i).gameObject, alpha, time));
    33.         }
    34.         return tweens;
    35.     }
     
  11. ArtC0de

    ArtC0de

    Joined:
    Sep 7, 2015
    Posts:
    14
    Hello!
    I'm having a bit of difficulty to restart a sequence when i need to.
    So what I'm trying to achive is this
    1. Go with the sequence
    2. Wait for a variable to come TRUE
    3. When the variable is TRUE restart the sequence



    Here is my code:

    Code (CSharp):
    1.  
    2.     bool isAnimationFinished = false;
    3.    
    4.  
    5.     void Start () {    
    6.         animateCatto();
    7.  
    8.     }
    9.    
    10.     // Update is called once per frame
    11.     void Update () {
    12.        
    13.         if (isAnimationFinished)
    14.         {
    15.             isAnimationFinished = false;
    16.             animateCatto();
    17.         }
    18.  
    19.        
    20.     }
    21.  
    22.     void animateCatto()
    23.     {
    24.         waitForMove = Random.Range(0, 5);
    25.         Sequence walkin_catto = DOTween.Sequence();
    26.  
    27.         walkin_catto.Append(this.transform.DOMoveX(-4, 1, false)).SetAutoKill(false);
    28.         walkin_catto.AppendInterval(waitForMove);
    29.         walkin_catto.Append(this.transform.DOMoveX(4, 1, false)).SetAutoKill(false);
    30.         isAnimationFinished = true;
    31.                      
    32.     }
     
  12. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    399
    If you just want the sequence to loop, you don't need the bool, and can just use:

    Code (CSharp):
    1. walkin_catto.SetLoops(-1, loopType.Incremental);
    (Use loopType.Restart if you want it to reset position too.)

    But if you are using your "isAnimationFinished" bool elsewhere in your code, you need to make sure it is only set to true once the sequence has finished playing, which you can do by using the OnComplete() callback.

    Code (CSharp):
    1. walking_catto.OnComplete(()=>{isAnimationFinished = true;});
    In the second case, if the sequence doesn't change, then you can set it up in Start() or Awake() and set AutoPlay to false. Then you can just call Restart() when you want to replay it, rather than making a new seque
     
    ArtC0de likes this.
  13. ArtC0de

    ArtC0de

    Joined:
    Sep 7, 2015
    Posts:
    14
    THANKS!!! solved
     
  14. MoribitoMT

    MoribitoMT

    Joined:
    Jun 1, 2013
    Posts:
    298
    I have a problem with kill and pause. I have menus, I open my UI IAP, and I have purchasing indicator which rotates during purchase.

    SpriteIndicator rotates well no problem, however when I close the UI, rotation keep contunie on behid. I tried kill(spriteIndicator) then I tried pause(spriteIndicator), both of them not works, only killAll() works, any idea ?

    Screen Shot 2018-02-02 at 13.35.59.png
     
  15. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    399
    Have you tried

    Code (CSharp):
    1. DOTween.Kill(spriteIndicator.transform)
    You can also manually set an ID when you create the tween, and use that to kill/pause the tween.
     
    MoribitoMT likes this.
  16. MoribitoMT

    MoribitoMT

    Joined:
    Jun 1, 2013
    Posts:
    298
    Thanx i figured out later..
     
  17. Kirbychwan

    Kirbychwan

    Joined:
    Aug 14, 2012
    Posts:
    430
    Is there any decent way to via the Dotween Animation component to access fields on the current object or, at the very least, stuff like the intensity value in a light so I can quickly and easily animate some lights without having to write an entire script for it?



    There seem to be no light-specific options in here. Is there any way to specify a specific field or value that I want to animate? I see that I can use the Events to specify a field, but I can't tween the values, just set them to a specific value? Am I missing a step?

    I seem to remember Hotween's visual script component had a ton of really useful visual scripting functionality in that regard; was this removed for Dotween Pro?
     
    Last edited: Feb 6, 2018
  18. startleworks

    startleworks

    Joined:
    Jun 8, 2013
    Posts:
    33
    how can I tween the progress of a sequence?
    using Goto seems to do nothing

    Later Edit: nvm, i paused the sequence at start and then it worked
     
    Last edited: Feb 7, 2018
  19. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    439
    Hi! Is it possible to combine two different ease types in the same tween? For example Ease.InExpo and Ease.OutElastic.
     
  20. startleworks

    startleworks

    Joined:
    Jun 8, 2013
    Posts:
    33
    can you give us a bit more context? you want to use the eases on the same property?
     
  21. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    399
    Someone else may know a better way, but I would use an Animation Curve. Here’s a good resource with all the usual eases converted into Easing Curve Presets that you could modify

    https://github.com/nobutaka/EasingCurvePresets
     
    username132323232 likes this.
  22. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    439
    Yes, on the same property. Something like this (doesn't work):
    Code (CSharp):
    1. transform.DOScale(new Vector3(2, 2, 2), 3f).SetEase<Tweener>(Ease.InElastic).SetEase<Tweener>(Ease.OutCirc);
     
  23. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    439
    Thanks! A very nice resource! I was hoping that some combination of SetEase() would work, but building curves should be fun :)
     
  24. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,330
    Idk why but I can't seem to get DOTween to work lol.
    I read the documentation and the start guide.

    says transform doesn't have a definition for DOPath

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using DG.Tweening;
    6.  
    7. public class ShipController : MonoBehaviour {
    8.  
    9. [HideInInspector] public Route[] Routes;
    10.  
    11. void FollowPath(){
    12.  
    13.   Transform[] Route = Routes[0].RoutePoints;
    14.   transform.DOPath(Route,1f,PathType.Linear,PathMode.Full3D,10,Color.blue);
    15.  
    16.  
    17. }
    18. }
    19.  
     
  25. arvzg

    arvzg

    Joined:
    Jun 28, 2009
    Posts:
    574
    I'm seeing some inconsistent behaviour with my tween.

    I've got these blocks moving left and right, tweening between 2 positions continuously, like this:



    As you can see - after just a few seconds the blocks get 'desynced' with each other as it appears some blocks are moving faster or perhaps turning around sooner or later than others.

    The code that moves them is like this:

    Code (CSharp):
    1. rb2d.DOMove(_locations[_tweenerIndex].position, _speed).SetSpeedBased(true).SetEase(Ease.Linear).OnComplete(PlayNextTween).Play();
    They have a kinematic rigidbody2d attached to them and are moved to transform positions set in an array in the inspector. Not really sure why this is happening
     

    Attached Files:

  26. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,330
    Im new to Dotween as you can see from my previous post. Are you setting DoTween to not use Unity default time scale? I was thinking that could cause inconsistent behavior. maybe a option in the DoTween menu.

    Or a option that ignores frame rates and instead animates when its best performance to do so.
     
  27. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    248
    Compounded Float Rounding Error, it looks like to me. Your code seems to rely on each tween starting, and finishing at the exact same moment with every pass in order to maintain synchronization. I'm not sure you can count on the precision of those tweens because floats are notoriously imprecise.

    Consider refactoring to a Sequence instead of several discreet tweens.
     
    Last edited: Feb 8, 2018
  28. arvzg

    arvzg

    Joined:
    Jun 28, 2009
    Posts:
    574
    Nah haven't changed the default time scale.

    I did consider that could be an issue since DOTween has to figure out when the position is 'close enough' to the target and fire the OnComplete, 'close enough' is probably really imprecise. I'm gonna try it without a rigidbody and see if it makes a difference
     
  29. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,330
    Anyone know what my issue is that Im having? few posts up.
     
  30. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    248
    transform.DOPath requires a Vector3 Array ( Vector3[] ) as the first parameter. It appears that you're supplying a single Vector3
     
  31. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,330
    Thanks for the reply @FuguFirecracker
    Nah its an array. I know that 0 key value is confusing. Its a multideminsional array.
    each value of Route is an array of transforms

    Does an array of transforms work? Or does it need to be an array of Vector3?
     
  32. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    248
    Oh look at at that. You do return an array of Transforms and not a single Vector3.

    My reading comprehension is a bit off. The use of 'var' has become such a habit for me that I never look to the left of the operator to see what variable type is being returned. I try to puzzle it out from the statement on the right.

    And to answer your questions. No and yes, in that order. :)
     
  33. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,293
    Hi all, Just jumped back on DOTween and it's great!
    I have one issue though that I seem to keep coming up against, if I kick off a tween then need to interrupt it to start the tween again (or to start another tween) the new tween starts from the current transform and that is causing some issues.
    Like this for example (see how the rotate builds up if tweened repeatedly) -

    I feel I must be missing something, is there a nice way to handle this?
    Thanks!
    Pete

    P.S This tread needs a search function of it's own :p
     
  34. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    248
    Do you mean the current transform ROTATION? or are you actually trying to pass another transform to the interrupted tween?

    What do you want to happen when you interrupt the tween?
    Do you want the tween to just stop? And then resume from stopped position | rotation when you reapply another tween (or the same tween) to the same transform ?

    Let's see some code.,
     
  35. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,293
    Hey, thanks for getting back to me.
    Sorry, by transform I meant Scale, Rotate or Translate since it seems to occur with all of them.

    Imagine if you wanted to punch a score out by scaling it.
    Code (CSharp):
    1. if (Input.GetKeyDown("j")) cubeA.DOScale(new Vector3(1.2f, 1.2f, 1.2f), 1).From().SetEase(Ease.OutElastic);

    This works fine as a once off animation but if you hit it repeatedly it's not always the same result.



    What would be the best way to approach that problem?
    Thanks!
    Pete
     
  36. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    399
    A few ways you can do it, but the way I like to work with DOTween is to disable AutoPlay. (You can do this in the DoTween settings panel, or through code) Then I can cache tweens and have more control over when they are played. Of course, disabling AutoPlay is not necessary if you don't mind the tween playing once when the scene starts.

    In your case, if you cache the tween (and disable AutoKill) then you could use Restart() to interrupt and replay the tween using its original values.

    Code (CSharp):
    1. Tween cubeATween;
    2.  
    3.     void Start()
    4.     {
    5.         cubeATween = cubeA.DOScale(new Vector3(1.2f, 1.2f, 1.2f), 1).From().SetEase(Ease.OutElastic).SetAutoKill(false);
    6.     }
    7.  
    8.  
    9.     void Update()
    10.     {
    11.         if (Input.GetKeyDown(KeyCode.J)) cubeATween.Restart();
    12.     }
     
    Last edited: Feb 12, 2018
    FuguFirecracker likes this.
  37. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,293
    Hey thanks @flashframe!
    What about an instance like this where you might want to add a bit of variation?

     
  38. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    399
    If you're ok with interrupting it, then you could check to see if the Tween is already playing and call Complete()

    Code (CSharp):
    1. if(cubeATween.IsPlaying()) cubeATween.Complete();
    That will force it to finish, and then you can reinitialise the tween with slightly different settings as you've done in your example.
     
  39. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,293
    Thanks @flashframe that sounds like what I'm looking for.
    I was a little surprised that I hadn't seen this pop up more, I would have thought you'd mostly want to have your animations controlled like this, particularly for UI stuff.
     
  40. spakment

    spakment

    Joined:
    Dec 19, 2017
    Posts:
    27
    Hey, thanks for the great tween library it's given me a great head start on my project.

    I'd really like to sync dotween to an audio clock but am fudging my way through the best way to do it. I see that recently you added in a way to support an extenal updater / timescale using UpdateType.Manual and then calling DOTween.ManualUpdate(float deltaTime, float unscaledDeltaTime).

    Would you be able to add in an example of this being used?
     
    ScriptGeek likes this.
  41. gegagome

    gegagome

    Joined:
    Oct 11, 2012
    Posts:
    331
    I animated a RectTransform from A to B, but I also need to move the same RectTransform from B to C.

    Is there a way to handle this?

    I am looking to see if there is a more efficient way that having two different sequences handling the same object.

    Thanks
     
  42. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    248
    One sequence should do it. If you need it run concurrently, use insert. If you need it to run consecutively, use append.
    Code (CSharp):
    1.  
    2.   DOTween.Sequence().Append(transform.DOLocalRotate(new Vector3(90, 0, 0), 3))
    3.                     .Insert(0, transform.DOMove(new Vector3(10, 0, 0), 3));
     
  43. gegagome

    gegagome

    Joined:
    Oct 11, 2012
    Posts:
    331
    Thanks for your quick reply @FuguFirecracker
    My implementation requires the Sequence to animate DOAnchorPosY from A to B, and later, say after other events, or key press, from B to C.

    They will not run consecutively or at the same time at all.

    Any ideas?
     
  44. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    248

    Ahha... What you are describing is not a sequence. It's 2 separate tweeners you want.
    And truth be told, a Sequence doesn't do any magic... it just bundles together a bunch of tweeners in one call for convenience.

    So you do your move tweener, and then later when you need it... you call the next tweener.
    There is no optimization to be done... You need value changed over time - you need a tweener.

    Any shortcuts or 'syntactic sugar' is just hiding the fact that behind the scene - multiple tweeners are being deployed.
     
  45. gegagome

    gegagome

    Joined:
    Oct 11, 2012
    Posts:
    331

    @FuguFirecracker thanks, I thought so
    Ended up doing a sequence and a tween on Start:
    Code (CSharp):
    1. _panel = DOTween.Sequence().SetAutoKill(false).Pause();
    2. _panel.Append(_thisRectTransform.DOAnchorPosY(0f, EXPAND_TIME).SetEase(Ease.InOutQuad));//.OnComplete(_counter.StartCountdownTracker)//;
    3. _IAPPart = _thisRectTransform.DOAnchorPosY(parentCanvasSize.y, EXPAND_TIME).SetEase(Ease.InOutQuad).SetAutoKill(false).Pause();
    and this is what is working for me:

    Code (CSharp):
    1.  
    2. if(_panel.IsComplete())
    3.             {
    4.                 Debug.Log(_IAPPart.IsComplete());
    5.                 if (!_IAPPart.IsComplete())
    6.                 {          
    7.                     _IAPPart.PlayForward();
    8.                 }
    9.                 else
    10.                 {
    11.                     Debug.Log(_panel.IsComplete());
    12.                     _IAPPart.PlayBackwards();
    13.                 }
    14.             }
    15.  

    Thanks!
     
    FuguFirecracker likes this.
  46. ScriptGeek

    ScriptGeek

    Joined:
    Mar 4, 2011
    Posts:
    45
    I need to tween a custom data type value using a custom data type for the time variables so that the tween is deterministic throughout its full range of interpolation. I've created a custom plugin to work with tweening a custom data type, but the evaluate methods use floating points, which are not guaranteed to be the same every calculation.

    I looked into attempting to use the DOTween API to construct tweens using SetUpdate so I could manually call when updates occur and then use OnUpdate to set my own update callback where I could calculate my own easing evaluations for tweening, but this seems to be a hackish way to go about a solution; although, if there is a clean way to do it this way I'd like to be corrected.

    I thought I might try checking out the repository and plugging in my custom data types for keeping track of time, you know instead of using floats. My dev team has moved to a newer version of Unity 2017.3 and it appears the code no longer compiles, given that there are so many errors, so this idea is pretty much dead in the water at the moment.

    I'd appreciate any help with this.
     
  47. vivredraco

    vivredraco

    Joined:
    Jan 19, 2016
    Posts:
    22
    How would I make a DOTweenPath pause briefly at each waypoint?
     
  48. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    248
    OnWaypointChange is what you're looking for.
    Code (CSharp):
    1.  
    2. using DG.Tweening;
    3. using UnityEngine;
    4.  
    5. public class WhatsThePoint : MonoBehaviour {
    6.  
    7.     private readonly Vector3[] _waypoints =
    8.     {
    9.         Vector3.zero,
    10.         Vector3.back,
    11.         Vector3.down,
    12.         Vector3.forward,
    13.         Vector3.left,
    14.         Vector3.right,
    15.         Vector3.one,
    16.         Vector3.up,
    17.         Vector3.zero
    18.  
    19.     };
    20.  
    21.     private Tweener _pathTweener;
    22.  
    23.     private void Start()
    24.     {
    25.     _pathTweener =    transform.DOPath(_waypoints, 5,  PathType.CatmullRom).OnWaypointChange(RestHereForAbit);
    26.     }
    27.  
    28.     private void RestHereForAbit(int waypoint)
    29.     {
    30.         _pathTweener.Pause();
    31.         // I use a sequence instead of a CoRoutine because Hey... Why not!?
    32.         DOTween.Sequence().AppendInterval(1).OnComplete(()=>_pathTweener.Play());
    33.     }
    34. }
     
    vivredraco and flashframe like this.
  49. vivredraco

    vivredraco

    Joined:
    Jan 19, 2016
    Posts:
    22
    Thanks!
     
  50. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    399
    Essentially the same thing, but I like to use it because it's a bit shorter:

    Code (CSharp):
    1. DOVirtual.DelayedCall();
    :)
     
    FuguFirecracker likes this.