Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

HOTween: a fast and powerful Unity tween engine

Discussion in 'Assets and Asset Store' started by Demigiant, Jan 7, 2012.

  1. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    476
    Aw booo... moment developers sets aside their component, that's a baaaaad sign. :/
     
  2. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    Hey I worked on HOTween almost full-time for almost 2 months... I think that's a good start. And I'm not setting it aside: I'm simply dedicating some time more to using it than to enhancing it (the current project is a Unity Android/iOS game, for which I'm obviously extensively using HOTween) :p
     
  3. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    476
    Hey, I hear ya. I know how it is, I really do. But the reason I think this is bad news is because HOTween is a paid asset that doesn't come with source. Which means one has to rely on you to be timely with updates and especially bug fixes. If you included the source (which I think everyone should always do), then it'd be less of a big deal since you could get in there and fix what needs fixing, add what needs adding, and so on.

    How about making the source available? NGUI, #1 top paid asset in the store.... source included. And you can even opt for a premium license that gives you real-time access to his git repo. Most importantly, including source does not hamper sales. It enhances it.

    David
     
  4. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
  5. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    476
    Oh... geez.. what was I thinking? :D

    Nevermind. Nothing to see here.

    (slinks away)
     
  6. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
  7. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    476
    I therefore reverse my previous statement....

    Thanks for making such a cool thing, making it free and spending so much time on it! And good luck with your game!
     
  8. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    Thanks a lot for the nice words David :)
     
  9. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    476
    BTW, just for my sanity... was it always open-source? I could have sworn it was DLLd at one point.
     
  10. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    Actually HOTween wasn't open-source during the first week it was released, because I wanted to refine some things before allowing anyone to make changes (but it was always free), so you're right :)

    Though I have to mention that now, even if it's open-source, the thing you use in Unity is still a DLL assembly (but the source comprises the csproj file, so it should be quick and easy to re-compile after making some changes), because I really couldn't stand building a code library without decent namespace management and internal members :p
     
  11. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    Small update: v0.8.019.

    • Added IntId() method parameter to TweenParms() and SequenceParms(). It works exactly as Id(), but wants an integer instead of a string ID, which makes it way faster when using group operations like HOTween.Pause(myId), and thus is the best solution if you want to squeeze maximum performance out of your tweens (like on mobile platforms).
    • Added intId property (which can also be changed while a tween/sequence is running) to IHOTweenComponent and ABSTweenComponent (meaning it can be used with Tweeners and Sequences).
     
  12. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    New update, and quite cool (on my humble opinion, obviously): v0.8.101 :)

    I added a new loop type: LoopType.Incremental. It creates a loop that, instead than rewinding or restarting at each cycle, increments the values each time (like 0 to 50, 50 to 100, 100 to 150, and so on). It works with all ease types and plugin types (even PlugVector3Path and strings), but it still doesn't work with Sequences (though it works with Tweeners inside Sequences).
     
  13. shaderbytes

    shaderbytes

    Joined:
    Nov 11, 2010
    Posts:
    900
    Thanks for the update ;)

    Here is a sample of HOTween LoopType.Incremental in use :

    http://shaderbytes.co.za/unity3D/HOTween/index.html

    I notice there is a small glitch on the first tween cycle it performs it seems to subtract the value to tween once from the start value before continuing as normal.

    I tried with and without a delay ( barrel on the right has a delay )

    Code (csharp):
    1.      parms.Prop("rotation", new Vector3(-45,0,0),true);
    2.         parms.Ease(EaseType.EaseOutElastic);
    3.         parms.Loops(-1,LoopType.Incremental);
    4.         parms.Delay(5);    
    5.         HOTween.From(transform, 2, parms );
    Expected behaviour is it should be starting from the transforms current rotation which in my case has x value of 0.
     
    Last edited: Feb 18, 2012
  14. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    Hey tictox, thanks for the example :D

    The behaviour seems ok to me, unless I'm missing something, because you're using HOTween.From, which means the starting value becomes the end value and viceversa (for the first loop). If you just want to start from the current value and go on, you should use HOTween.To.

    Let me know if I didn't understand something.

    By the way, I also put an example on HOTween Example page (Incremental Loop Type).
     
  15. shaderbytes

    shaderbytes

    Joined:
    Nov 11, 2010
    Posts:
    900
    DOH! Sorry man I was so excited about the loop type I overlooked the method call I used . Im impressed the linear ease type works seamlessly in your example ,well done!
     
  16. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    Glad that got you excited tictox :D

    I built HOTween so that loops don't simply restart from "0" time, but they calculate the right amount of time that went by since the previous update, and position themselves accordingly. This makes tweens more precise, and also allows things like linear Incremental to work seamlessly :)
     
  17. yuewah

    yuewah

    Joined:
    Sep 21, 2009
    Posts:
    98
    if there is a target transform.rotation with value x = 0, y = -25, z = 0 ( entered in the inspector )

    then I run
    HOTween.To(gameObject.transform, 1, new TweenParms().Prop("rotation", target.transform.rotation ) );

    However,
    the gameObject is rotated in clockwise instead if anti-clockwise.
     
  18. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    @yuewah: that's because if you use another transform's rotation you're using Quaternions, and Quaternions don't have negative values. If you check the inspector, you'll see that, as soon as you press PLAY, your -25 becomes a 335, and thus HOTween will tween to that value. If you want to use negative values, you should directly assign rotations as Vectors:
    Code (csharp):
    1. HOTween.To(gameObject.transform, 1, new TweenParms().Prop("rotation", new Vector3(0,-25,0)));
     
  19. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    New update (v0.8.102), with just a small bugfix:

    - Fixed NullReferenceException which could happen when killing a tween during an update.
     
  20. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    New version of HOTween Editor: v0.2.101

    - Added *From* Checkbox to apply tweens FROM instead than TO.
    - Added header which reports the current HOTweenEditor and HOTween DLL versions in use.
    - Much more responsive (the "wait time" that sometimes happened when moving back and from the Editor Panel isn't there anymore).
    - Supports tweening of Rects.
    - Minor optimizations.

    Remember that you need to install the latest version of HOTween before importing HOTween Editor.

    P.S. in case you're wondering why I'm updating HOTween much more than HOTween Editor, that's because I based HOTween Editor mostly on Reflection, thus it automatically adapts itself to the current features offered by HOTween (mostly) :p
     
  21. shaderbytes

    shaderbytes

    Joined:
    Nov 11, 2010
    Posts:
    900
    Hi Izitmee

    Just wanted to ask if you had a look at the delay repeating option in looped tweens , is it something you will be able to implement soonish?

    Thanks again
     
  22. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    Hi tictox,

    going at it right now. If all goes well, I'll have it up in some 5 hours or so :)
     
  23. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    Uhm, all didn't go well, because it kind of breaks the logics behind the Tweeners... I will do another thing instead: add the Loop.Incremental type to Sequences. That way, you will be able to achieve the same result, since you can Append/Insert intervals in sequences, with mySequence.InsertInterval() and mySequence.AppendInterval().

    Will get on it tomorrow afternoon, and hope to have it done for the weekend.
     
  24. alperozer

    alperozer

    Joined:
    Aug 18, 2011
    Posts:
    11
    Hi Izitmee,

    By using PlugVector3Path I try to move a character (with a camera attached to it) through a curve.

    While the character is moving, it's rotational x,y,z parameters are changing continuously and camera keeps shaking always.

    However I would like to change only y rotation.

    I'm using this:

    HOTween.To( target1, 20, new TweenParms().Prop( "position", new PlugVector3Path( path ).OrientToPath(),true).Loops( 1 ).Ease( EaseType.Linear ).OnStepComplete( PathCycleComplete ) );

    Is it possible to prevent this situation ?

    Thank you very much.
     
  25. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    Hi alperozer,

    I tried, after reading your post, to implement a "lockAxis" option in the OrientToPath method, but I couldn't find a "decent" way to do it. It looks like it'll take a long coding time to get it done, mainly because of HOTween's "timeline-like" approach.

    I'll get at it again, but after I manage to add the Incremental Loop to Sequences. Can't really say when it'll be done, though I'll definitely try to get at it for the beginning of next week.
     
  26. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    Just released HOTween v0.8.110:

    - Added Incremental LoopType also to Sequences. Please note that this is an experimental option: it works perfectly with simple Sequences, but you should check that your animation works as expected with more complex ones (@tictox: works perfectly for the implementation of delays between each tween :)).

    Also, you may note that a "lockAxis" parameter has been added to PlugVector3Path OrientToPath method. Don't use it! Sorry, I'm still working on that :p
     
  27. alperozer

    alperozer

    Joined:
    Aug 18, 2011
    Posts:
    11
    Thank you very much Izitmee, your plug-in is very good and of course it'll take time to be mature. By the way you can create an examples pack and you can sell it like iTween. lockAxis feature will be great because curve movement features (constant speed, speed change) is absent in other tween libraries. I am waiting for your feature anouncement.

    Best regards.
     
  28. shaderbytes

    shaderbytes

    Joined:
    Nov 11, 2010
    Posts:
    900
    thanks for the updates , I have not tried using sequences yet .. gonna give it a spin tomorrow!
     
  29. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    New HOTween v0.8.111:
    - Fixed bug where appending an interval at the start of a Sequence didn't work.

    @tictox: I added an example of a Sequence with an interval to the "Incremental Loop Type" example (the last ball on the right moves with an Incremental loop, while pausing within each loop).

    @alperozer: thanks alperozer :) Initially I intended to put a paid example pack as you suggested, seen that I definitely need some money now, but when I think about really doing it I feel like it's a bad thing (though I'm not sure why) :p
     
    Last edited: Feb 27, 2012
  30. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    New HOTween v0.8.112:
    - Removed leftover Debug.Log message from *PlugVector3Path* (sorry for that :p).
     
  31. shaderbytes

    shaderbytes

    Joined:
    Nov 11, 2010
    Posts:
    900
    Thanks for the example , I would have never guessed to add the loop to the sequence instead of the tweener! .. works like a charm , excellent ;)
     
  32. SilentWarrior

    SilentWarrior

    Joined:
    Aug 3, 2010
    Posts:
    107
    Hey Izitmee, nice to see another tweening lib :D

    I was wondering, with iTween I have the following problems :
    - When game is playing and code is updated, I have to restart the player or iTween will start throwing errors.
    - When I dynamically spawn an object that has iTween animations in it, iTween starts throwing errors.

    Does HOTween suffer from the same problems? iTween works by attaching components to my gameobjects, this is good and bad. Does HOTween support (or could in the future support) a way of just returning the new tweened values by code and I take care of updating the "ticks" myself?

    public Tween myAnim; // myAnim = new Tween(Time.time, /*from*/ 5, /*to*/10, /*using*/EaseType.easeOutBounce);
    Example : float yPos = myAnim.Update(Time.time).tweenedValue();

    The Time.time would just update the code internally with some type of interpolation of the difference in start time with current time.
     
  33. OmniverseProduct

    OmniverseProduct

    Joined:
    Feb 26, 2012
    Posts:
    1,568
    This is off topic, but what the heck does tween mean? I've been trying to figure that out for a while now, :p
     
  34. SilentWarrior

    SilentWarrior

    Joined:
    Aug 3, 2010
    Posts:
    107
    Tweening, in animation, the creation of intermediate frames between two key points, often added by an assistant animator or by computer. (Wikipedia)

    Basically its the way you express the "path" or "animation" of a object between 2 (or more) points in time, could be position change over time, scale change, etc.
     
    Last edited: Feb 28, 2012
  35. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    Hey SilentWarrior, thanks for the tween definition :)
    I'm not sure what you mean. You mean errors are returned if you change your code while the Editor player is actually in a play state? If that's the case, it's not a problem limited to iTween (nor to anything else). You should always stop the player when you want to change your code, because Unity needs to recompile it before it can be "digested" and played again.

    With HoTween, you first spawn an object, and then assign a tween to it. If for some reason the tween target gets destroyed while the tween is running, the tween is automatically destroyed without throwing exceptions.

    I'm not sure I understood this, but it looks interesting. Could you explain me better, and I'll see what I can do?
    Consider that HOTween has additional "controls" that make it work like a video timeline, so you could create a full tween, and then tell him to GoTo( myTime ), and the full animation would be updated to that point:
    Code (csharp):
    1.  
    2. // Sends the animation to where it would be
    3. // after 1 seconds of playing.
    4. myTween.GoTo( 1 );
    5.  
     
  36. yuewah

    yuewah

    Joined:
    Sep 21, 2009
    Posts:
    98
    I am using HOTween 0.8.112
    Code (csharp):
    1. Sequence mySequence = new Sequence( new SequenceParms() );
    2.        
    3. mySequence.Append( HOTween.To( cube.transform, 0.5f, new TweenParms().Prop("localPosition", new Vector3( 10, 10, 10) ).OnUpdate( () => Debug.Log("Update") ) ) );
    4.        
    5. mySequence.Play();
    Why OnUpdate() didn't called ?
     
  37. shaderbytes

    shaderbytes

    Joined:
    Nov 11, 2010
    Posts:
    900
    @ yuewah

    I see OnComplete works inside the appended tweener and i see if you add the OnUpdate to the sequence it works like the example below , but OnUpdate inside the appended tweener is also not working on my side..

    Code (csharp):
    1. Sequence mySequence = new Sequence( new SequenceParms().OnUpdate( () => Debug.Log("Update") ));
    2. mySequence.Append( HOTween.To( cube.transform, 0.5f, new TweenParms().Prop("localPosition", new Vector3( 10, 10, 10) ).OnComplete( () => Debug.Log("complete") ) ) );
     
  38. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    I guess he wants to talk about the possibility of recovering the future position or/and rotation of the tween (like a bezier curve).
    +1

    JP
     
    Last edited: Feb 28, 2012
  39. SilentWarrior

    SilentWarrior

    Joined:
    Aug 3, 2010
    Posts:
    107
    1:
    Let me try to explain better, in my current game, that has about 20 or 30 classes more or less (not very big yet), if I update just a single line of code while in Play mode it will work correctly since unity will compile and run it without complaining, if I have iTween working, it will start spitting out errors, not a major thing since I mostly restart the scene anyways.
    2:
    When I spawn an object that uses an iTween animation, notice that iTween animations are "created" by iTween itself when you call a static method, it will start spitting errors, probably because 2 objects of the same type normally exist, I only tried this with spawning more than 1 tank in my RTS game where itween is used to make the cannon recoil+bounceback animation.
    3:
    If you were to create the animations by hand (code) you would create some variables to hold the current position and time, lets keep it simple and say that it is an animation that causes a movement over time. You would then calculate a new position based on the last position and the delta (change amount/difference vector/posX-posY, whatever you want to call it) over a set amount of time (say delta = speed*(currentTime-lastTime) but you could also apply some other methods on top such as easing equations), in iTween, if you would like to do this, you would proceed and do the following :
    - create a new dummy gameobject
    - create the animation code and set it to that gameobject
    - copy the gameobject position properties each frame to your desired variable
    - use that variable somewhere you need it.

    So, in order to get a simple value change in a variable (float) you would need the overhead of creating a new gameobject, maintaining the references, addition of itween animation component on that gameobject, unity engine rendering(unless u go out of your way to make it not render), keeping track of and updating that gameobject and then copying that gameobjects position and translate it into a variable you wanted.

    When you could actually do : in void Start() -> var x = new Anim(/*from*/10, /*to*/20,/*using*/easing.bounce,/*over*/10/*seconds*/, /*initial time*/, Time.time);
    and then each void Update() -> float valueNeeded = x.Update(Time.time); to get a value at current Time.time.


    Looking at your code example, it seems very close to what I want, I still have to see what is actually beeing done in the background, it its updating a gameobject and all the overhead behind it, than it is similar to the iTween way.


    Let me code something fast so you can understand it better (not tested):
    Code (csharp):
    1.  
    2.  
    3.  
    4. class Anim{
    5.     public enum EasingType {
    6.         linear,
    7.         bounce,
    8.         other
    9.     }
    10.     private EasingType easing;
    11.     private float from, to, howLong, initialTime, speed;
    12.     public Anim(float from, float to, EasingType easing, float howLong, float initialTime){
    13.         this.from = from; this.to = to;
    14.         this.howLong = howLong; this.initialTime = initialTime;
    15.         this.easing = easing;
    16.         this.speed = Math.abs(from - to)/howLong;
    17.     }
    18.     private float _lastValue;
    19.     public float Update(float currentTime){
    20.         // reached end of anim, return last value
    21.         if(currentTime > (initialTime+howLong))
    22.             return _lastValue;
    23.         if(easing.linear)
    24.             return _lastValue = from + ((from - to)*speed*(currentTime - initialTime);
    25.     }
    26. }
    27.  
    28. class myObject : Monobehavior{
    29.     Anim myAnim;
    30.     void Update(){
    31.         if(myAnim == null)
    32.             myAnim = new Anim(/*from*/10, /*to*/20,/*using*/easing.linear,/*over*/10/*seconds*/, /*initial time*/, Time.time);
    33.         Debug.Log("new value " + myAnim.Update(Time.time));
    34.     }
    35. }
    36.  
    37.  
    instead of

    Code (csharp):
    1.  
    2. class myObject : Monobehavior{
    3.     GameObject myDummy;
    4.     void Update(){
    5.         if(myDummy == null){
    6.             myDummy = new GameObject("dummyAnimTarget");
    7.             myDummy.transform.translate(new Vector3(10,0,0));
    8.         }
    9.         iTween.MoveTo(myDummy, new Vector3(20,0,0), 10);
    10.         Debug.Log("new value "+myDummy.transform.position.x);
    11.     }
    12. }
    13.  
    The overhead of creating a new gameobject for getting a simple "animated" value is terribad.

    I had to do this for animating a guiLabel for example, each time I wanted it animated or I wanted a new label, I would have to make a new gameobject, animate it, copy its position and store it in a List to keep track of and clean up when I didnt need it anymore. All for a "simple" animation.

    I also used this method for simulated a Mood swing in one of my AI scripts, but then scrapped it because it was too slow :/
     
    Last edited: Feb 28, 2012
  40. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    @yuewah @tictox: when using a Sequence, you should add callbacks to the main Sequence instead than to the nested Tweener or the other nested Sequences. Actually, nested Tweeners and nested Sequences callbacks work even when inside a Sequence, except OnUpdate. If you think you really need nested OnUpdate callbacks to work when inside a Sequence, tell me what would be a good reason for it, and I'll implement it :)

    @SilentWarrior: great and detailed explanation, I appreciate it :) Let me get to the points:
    1:
    This leaves me puzzled. I thought Unity couldn't recompile while playing (or better: it recompiles the project, but not what's playing): each time I did it (mostly because I forgot to stop the player while editing), I got all sorts of errors (in projects without iTween or HOTween). Anyway, I gave it a try: modified a single line of code while the player was running some HOTweens, and no errors happened.
    2:
    I'm right now developing a game, obviously using HOTween, where I spawn many objects that contain tweens (meaning those objects have attached MonoBehaviours that create and start a tween on Start()), and I have no problems at all.
    3:
    Actually this is one of the main difference from iTween, and one of the reasons I created this tween engine. HOTween doesn't attach anything to gameObjects. It simply creates a single gameObject (called "HOTween : [total-number-of-tweens-currently-running]") in the root, and uses that to store all data of any running tween (and to update them). When all tweens are complete, the gameObject is automatically destroyed (unless some of the running tweens was set to AutoKill(false), which prevents it to be automatically destroyed at completion, so you can keep it for further use). The overhead of HOTween's gameObject is practically null, since it's a single GameObject for all tweens, and has no MonoBehaviours attached.
    This also means that you don't need a GameObject target. You can animate any public property/field of any object. For example, let's say I want to animate the float "someVar", which is in an instance of a class I derived from System.Object, in one second:
    Code (csharp):
    1.  
    2. // This will tween someVar from its current value to 15.5f in 1 second.
    3. HOTween.To( myClassInstance, 1, "someVar", 15.5f );
    4.  
    Another example, with a more advanced usage of HOTween:
    Code (csharp):
    1.  
    2. // Store the tween, so I can control it manually,
    3. // and use TweenParms to set a desired EaseType
    4. // and to set AutoKill to false (to prevent the tween to be automatically destroyed at completion)
    5. IHOTweenComponent myTween = HOTween.To(myClassInstance, 1, new TweenParms().Prop("someVar", 15.5f).Ease(EaseType.EaseOutElastic).AutoKill(false));
    6. // Send "someVar" to where it would be after 0.5 seconds:
    7. myTween.GoTo(0.5f);
    8.  
    If you need to update the object often, this is the best way to go. Though, I understand that what you (and ZJP) would also like, is to have a method that, without prior creations of tweens, just sends a variable to a given time, using a given virtual easing? Like:
    Code (csharp):
    1.  
    2. // HOTween.GetValue( float from, float to, float virtualDuration, EaseType virtualEase, float time )
    3. float myVar = HOTween.GetValue( 5f, 10f, 3f, EaseType.Linear, 1.5f );
    4. // Which would set myVar to 7.5
    5.  
    If so, it looks like an interesting idea: will see if I can implement it.
     
    Last edited: Feb 28, 2012
  41. SilentWarrior

    SilentWarrior

    Joined:
    Aug 3, 2010
    Posts:
    107

    Thank you for the nice detailed explanation :D

    The last example is exactly what I am looking for. If you can get around to implement it, it would be awsome :D It will simplify some of the stuff we do as programmers, I love tweening stuff and I love to use them for less common stuff (other than moving things) as I said.

    For example the falloff of bullets could be calculated using a Tween. Also, the changing of the mood from an AI actor cold also be managed easily with a tween, "start hotheaded and using an easing equation, de-escalate to coolheaded". Also, how good is the aim of a infantry men based on the falloff of its visual acuteness (did i spell that correctly?). The rotation of a tanks turret could also use a easing equation, and so can its expected accuracy while moving. Etc etc etc.

    Having all this easing equations and "animation" values in a single easy to use method call would be completely awsome, and controlling time would also be great because I can, beforehand, input the end time and get a good estimate (if not completely accurate) of where the value will end up. For example pre-loading an explosion on the spot where the projectile falls and pre-select the gameobjects that have to be removed from the explosion.

    The uses for this are endless.
     
  42. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    Great idea, I'm liking it a lot, and I'm actually sold. I'll start working on it - and hopefully complete it - tomorrow :)

    I was thinking about the best way it should work (from a user's point of view and following your examples), and maybe this would be even more interesting?
    Code (csharp):
    1.  
    2. // TweenVar will be a special class that stores a "virtual tween", using
    3. // HOTween.Var( float from, float to, float virtualDuration, EaseType virtualEase )
    4. TweenVar myVar = HOTween.Var( 5f, 10f, 3f, EaseType.Linear );
    5. // This way, each time I want to get a value,
    6. // instead of calling the method again, I would just do this:
    7. float someVar = myVar.Update( /*time*/1.5f );
    8. // which would set someVar to 7.5f
    9.  
    Also, TweenVar would have startValue, endValue, easeType and duration set as properties, thus they could be changed at any moment.

    What do you think? It's the right way to go? Any suggestions?
     
  43. yuewah

    yuewah

    Joined:
    Sep 21, 2009
    Posts:
    98
    Is this exception mentioned in the documentation ? It is straight forward to think that it works for all cases.
     
  44. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    You're right, my bad :p I just added working OnUpdate callbacks for all nested Tweeners and Sequences. Will be available in the next update (later today, as soon as I complete the additional TweenVar method).
     
    Last edited: Feb 29, 2012
  45. faultymoose

    faultymoose

    Joined:
    Oct 1, 2010
    Posts:
    246
    I just got home from Sydney so I finally had a chance to get into HOTween a bit...

    I have to say, this is BRILLIANT. I spent the day going through my code and replacing all of my awkwardly hacked in animation and tweening with HOTween calls. This extension is an absolute dream to use. I cannot recommend it enough.
     
  46. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    Hey faultymoose! Hi to you and to your hair! Thanks for the recommendation, and hope your time in Sidney was awesome, and you're back for some more one-day game :)
     
  47. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    New update: HOTween v0.8.121

    - Added TweenVar, which does what SilentWarrior and ZJP were asking. To learn more about it, check the documentation (refresh the page if you don't see TweenVar in the summary)
    - OnUpdate now gets called also for nested Tweeners and Sequences.
    - Added enabled property to Tweeners and Sequences (meaning also IHOTweenComponent and ABSTweenComponent), which allows to completely disable animations for a Tweener/Sequence (again, see documentation for Tweener/Sequence properties)
     
  48. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    :cool: Thx.
    Nice add on. My Ik Solvers will love.

    JP
     
  49. SilentWarrior

    SilentWarrior

    Joined:
    Aug 3, 2010
    Posts:
    107
    Yes it is :D

    That way actually cleans up the code needed because I can just define the animation at start and then only update/call it when I need to.

    Might be asking too much but, could you make a composite system that would work essentially like the HOTween Sequences but for this variable thing:

    Code (csharp):
    1.  
    2. mySequence = new SequenceVar(new SequenceVarParms().Loops(3,LoopType.Yoyo))
    3. var first = HOTween.Var( 5f, 10f, 3f, EaseType.Linear); // perform linearly here
    4. var second = HOTween.Var( 10f, 0f, 3f, EaseType.EaseOutQuad); // perform smoothing here
    5. mySequence.Append( first);
    6. mySequence.Append( second );
    7.  
    and then

    Code (csharp):
    1. float myVar = mySequence.Update(/*time*/ 5f);
    internally the sequence class would have something like:

    Code (csharp):
    1.  
    2. float totalAnimatedTime;
    3. List<TweenVar> myList = new List<TweenVar>();
    4. void Append(TweenVar t){
    5.     totalAnimatedTime += t.duration;
    6.     myList.add(t);
    7. }
    8.  
    9. TweenVar getCurrent(float time, bool goBackwards){
    10.     if(time <= 0)
    11.         return myList.First;
    12.     if(time >= totalAnimatedTime)
    13.         return myList.Last;
    14.  
    15.     TweenVar t = null;
    16.     var from = 0f; // store time from start/end of FOR
    17.     if(goBackwards){ // if we are going backwards, lets start from end
    18.         from = totalAnimatedTime;
    19.         for(int i=myList.length; i>-1; i--){
    20.             var cur = myList[i];
    21.             var starTime = from - cur.duration;
    22.             var endTime = from;
    23.             if(time < endTime  time >= starTime){
    24.                 t = cur;
    25.                 break;
    26.             }
    27.             from -= cur.duration;
    28.         }
    29.     }else{
    30.         for(int i=0; i<myList.length; i++){
    31.             var cur = myList[i];
    32.             var starTime = from;
    33.             var endTime = starTime + cur.duration;
    34.             if(time < endTime  time >= starTime){
    35.                 t = cur;
    36.                 break;
    37.             }
    38.             fromStart += cur.duration;
    39.         }
    40.     }
    41.     return t;
    42. }
    43. float _lastTime;
    44. TweenVar _lastTween;
    45. Update(float time){
    46.     bool goBackwards;
    47.     if(myLoopType == LoopType.Yoyo  time > totalAnimatedTime){
    48.         time = totalAnimatedTime - (time - totalAnimatedTime); // go backwards
    49.         goBackwards = true; // optimization
    50.     }
    51.  
    52.     // quick optimization
    53.     var current = (_lastTime == time)? _lastTween : _lastTween = getCurrent(_lastTime = time, goBackwards);
    54.     return current.Update(time);    
    55. }

    Again that code is not tested :p

    Does that make sense? Of course the example is not complete, but, its there just to give you a better idea of what i mean.
     
  50. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    @ZJP: glad you liked it. Say hi to your Ik Solvers from me :D

    @SilentWarrior: glad you thought it was good, because I didn't resist and already implemented it :)
    The SequenceVar idea should be easy enough, and thanks for the code, will do it within this weekend :) Though I didn't think of implementing also loops. You really think they're necessary (loops are quite a complicated thing in HOTween, since there's also LoopType.YoyoInverse and LoopType.Incremental)?