Search Unity

Chronos – Time Control – Unity Awards Winner

Discussion in 'Assets and Asset Store' started by Ludiq, Apr 9, 2015.

  1. Tony707

    Tony707

    Joined:
    Jun 15, 2015
    Posts:
    38
    Hi,

    Another question:

    At game start my gameobject animator is not slowing whereas it depends on a global clock initialy set at .3.

    In fact timeline components seems to adjust their properties only when the new timescale differs from the last one.
    Is it possible to call AdjustProperties() at Start in order to set the animator speed accordingly ?

    Thank you.
     
  2. zhuchun

    zhuchun

    Joined:
    Aug 11, 2012
    Posts:
    411
    Hi, I find another issue about AreaClock3D. Enable/Disable AreaClock3D can't change timeline inside it .
    chronos_bug.gif
    So, a workaround, put these lines into AreaClock3D.
    Code (CSharp):
    1.  void OnDisable()
    2.         {
    3.             ReleaseAll();
    4.         }
    5.  
    6.         protected virtual void OnTriggerStay(Collider other)
    7.         {
    8.             OnTriggerEnter(other);
    9.         }
    Hmm, looks good :)
    chronos_fix.gif
    You may want to apply this to other scripts and find a better way other than OnTriggerStay since I have no idea will it cause performance problem :p Cheers!
     
  3. Micropez

    Micropez

    Joined:
    Aug 25, 2015
    Posts:
    4
    Hi all,

    Just a silly question here.
    I am sure I have seen this mentioned on RFPS (Realistic FPS) some time ago, but for the life of me I cannot find that thread anymore.
    Does anyone know how to modify the RFPS enemy script for this to work?

    I have followed the tutorial but got stuck on where to change it to time.rigidbody etc...
    Any direction will be greatly appreciated.
     
  4. zhuchun

    zhuchun

    Joined:
    Aug 11, 2012
    Posts:
    411
    I don't have RFPS but I have changed some assets to let them work with Chronos, here's some info.
    1. Find out every "new waitforseconds" and "Time.deltaTime/timeScale", they're very common. Change them first, put others behind(like rigidbody), in most case as-is is cool.
    2. Try change codes from the top, not the bottom.
    3. Most assets have their own timeScale system and have API to modify, so call them in YourScriptWithTimeline.OnStartSlowDown()/OnStopSlowDown() etc.
    4. Test more. If you find anything hard, try make a gif and upload it to this thread. LICEcap is a nice FREE tool.
     
    Micropez likes this.
  5. Micropez

    Micropez

    Joined:
    Aug 25, 2015
    Posts:
    4
    Thanks zhuchun,
    With RFPS instead of Time.deltatime, Time.time is used. Am I correct in assuming that I can use Chrono's migration guide with it as Timeline.time?

    Thanks for your tips man!!!
     
  6. zhuchun

    zhuchun

    Joined:
    Aug 11, 2012
    Posts:
    411
    That migration guide is good :)
    I've take a look into Timeline and it describe properties like this.
    Code (CSharp):
    1.     float unscaledDeltaTime = Timekeeper.unscaledDeltaTime;
    2.             deltaTime = unscaledDeltaTime * timeScale;      
    3.             time += deltaTime;
    So Timeline.time depends on its timeScale. I seldom change it in script since in most case they're used as flag, it works fine as long as time is still running. I'm not sure if there's any Math.abs() to handle timeScale(I bet no :p), that means if you "rewind" time in your scene, changing this may cause problems. Such as you have a trigger and you check it in this way
    Code (CSharp):
    1. if (lastTime < Timeline.time)
    , then it may not works properly, meanwhile Time.time is cool.
    I suggest leave this alone for now, test it before you change it :)
     
  7. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    711
    Hm, OnTriggerStay is wayyyy too performance intensive. It basically means at every frame. And it would cause problems with some area clock modes because the entry point would be reset.

    Couldn't you just set the Timescale of your area clock to 1 (if it's multiplicative) or 0 (if it's additive) when you need it "disabled"?

    Will be fixed for v.2.0.6!

    Hotfix: Replace the Start function in Timeline.cs with this:
    Code (CSharp):
    1.     protected virtual void Start()
    2.      {
    3.        timeScale = lastTimeScale = clock.timeScale;
    4.  
    5.        foreach (IComponentTimeline component in activeComponents)
    6.        {
    7.          component.AdjustProperties();
    8.          component.Start();
    9.        }
    10.      }
    11.  
     
  8. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    711
    Question: how many of you use Chronos without rewind? (e.g. only for slow / pause / accelerate)

    I think I could do some performance and / or bugfixes on Particle Systems if you don't need it to be rewindable.
     
    Arx and hopeful like this.
  9. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,372
    I have nearly zero interest in rewind, personally.
     
  10. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    711
    Chronos v.2.0.6 has been submitted for review!

    Changelog:
    • Fixed Timekeeper.AddClock
    • Fixed parent clock error
    • Fixed component timelines not being adjusted on start
     
  11. SpaceRay

    SpaceRay

    Joined:
    Feb 26, 2014
    Posts:
    427
    I personally do not like the rewind, as I do no think it may be interesting for a game, and I think it may be cool for others things, but I do not have any plan to use it.
     
  12. SpaceRay

    SpaceRay

    Joined:
    Feb 26, 2014
    Posts:
    427
    I have a possible suggestion that I have seen in some videos related to time freeze and rotating or moving cameras

    I found this frozen explosion that moves the camera



    Here is a 20 seconds spanish ad that have frozen the scene with things in the air, and have a rotating camera



    I wonder how can be done this using Chronos?

    I think is a beautiful idea and think It would be good and interesting that if you freeze the time completely, you could be able to rotate the camera either manually or automatically, and when you turn off freeze it would go back to normal camera

    Another example is in U2 - Elevation video at 44 seconds from start



    And not only with frozen time also with slow time moving as shown on Matrix movie, at 40 seconds from start

     
    Last edited: Aug 29, 2015
  13. mwozniak93

    mwozniak93

    Joined:
    Feb 4, 2015
    Posts:
    11
    Hello,

    I have an issue, I am creating game for mobile and I have bullets which have particles. I also have Timeline attached to the same GameObject (in order to slow it down).
    How can I turn off particle recording in the clock? I do not want to reverse time for any particle anywhen, I just want to slow it down or stop it, so recording which makes my game realllly laggy is not needed.
     
  14. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    711
    In light of this, v.2.1 will include serious performance optimizations and hopefully some workarounds for the limitations by optionally disabling rewind on particles.

    I'm starting a new semester and a getting a bit of rush in my dayjob this week though, so please be patient.

    There are many ways to easily do that with Chronos!
    Basically, you want most if not all objects to be affected by the pause, but not the camera.

    Some options:

    1. Simplest but least flexible: Don't put a Timeline on the Camera. Chronos won't affect it at all.
    2. Put a Timeline on the Camera, set its mode to Local, and add a Local Clock to the camera, too. This way, you can control its time scale independently on a per-object basis.

    If you only want some objects to be paused in the scene, remember you can group them by affecting their Global Clock to different ones.
     
    hopeful likes this.
  15. zhuchun

    zhuchun

    Joined:
    Aug 11, 2012
    Posts:
    411
    Ah! I thought that timescale of area clock is a static property just like its parent value
     
  16. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    711
    Luckily not! You can change it via localTimeScale (timeScale only returns the computed time scale from its parents etc.; but you can't manually change it).
     
  17. Arx

    Arx

    Joined:
    Jan 28, 2014
    Posts:
    22
    Thanks! I, too, don't need rewind, but still struggle with that "Local space" limitation of particles.
     
    Last edited: Aug 31, 2015
  18. Tony707

    Tony707

    Joined:
    Jun 15, 2015
    Posts:
    38
    We too use chronos without rewind, we had to rewrite the ParticleSystemTimelime to only adjust the playbackspeed to improve performance.
     
  19. Arx

    Arx

    Joined:
    Jan 28, 2014
    Posts:
    22
    Would you be so kind as to share this code with us?
     
  20. Tony707

    Tony707

    Joined:
    Jun 15, 2015
    Posts:
    38
    Hi,

    Here it is:

    Warning: This breaks the rewind functionnality.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. namespace Chronos
    5. {
    6.     public class ParticleSystemTimeline : ComponentTimeline<ParticleSystem>
    7.     {
    8.         public ParticleSystemTimeline(Timeline timeline) : base(timeline) {}
    9.  
    10.         private float _playbackSpeed;
    11.         /// <summary>
    12.         /// The playback speed that is applied to the particle system before time effects. Use this property instead of ParticleSystem.playbackSpeed, which will be overwritten by the timeline at runtime.
    13.         /// </summary>
    14.         public float playbackSpeed
    15.         {
    16.             get { return _playbackSpeed; }
    17.             set { _playbackSpeed = value; AdjustProperties(); }
    18.         }
    19.  
    20.         private ParticleSystem[] _childrenParticleSystems;
    21.  
    22.         public override void CopyProperties(ParticleSystem source)
    23.         {
    24.             _childrenParticleSystems = source.GetComponentsInChildren<ParticleSystem>();
    25.  
    26.             playbackSpeed = source.playbackSpeed;
    27.         }
    28.  
    29.         public override void AdjustProperties(float timeScale)
    30.         {
    31.             var speed = (timeScale >= 0) ? playbackSpeed * timeScale : 0;
    32.  
    33.             component.playbackSpeed = speed;
    34.  
    35.             // Used to apply speed changes to children particle systems since playbackSpeed is not recursive.
    36.             foreach (var child in _childrenParticleSystems)
    37.             {
    38.                 child.playbackSpeed = speed;
    39.             }
    40.         }
    41.     }
    42. }
    43.  
     
    Last edited: Aug 31, 2015
    s1fr, Ludiq, Arx and 1 other person like this.
  21. Arx

    Arx

    Joined:
    Jan 28, 2014
    Posts:
    22
    Really simple, thousand thanks for sharing!

    If anyone of you uses Spine for 2D animations and spine-runtimes to run those animations in Unity, I've written a simple component to enable Chronos functionality for those Spine animations. Attach it to the object that has Skeleton Animation script on it.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using Chronos;
    4.  
    5. [DisallowMultipleComponent]
    6. public class ChronosSpineEnabler : MonoBehaviour
    7. {
    8.     // -------------------------------------------------
    9.     // Attributes:
    10.     // -------------------------------------------------
    11.  
    12.     // -------------------- Public: --------------------
    13.  
    14.     // -------------------- Private: --------------------
    15.     // current timescale of the Timeline component attached to this object
    16.     private float CurrentTimescale = 1f;
    17.  
    18.     // holds the reference to Timeline component on this game object
    19.     private Timeline Timeline;
    20.  
    21.     // Object that holds Spine's Skeleton Animation script
    22.     private SkeletonAnimation ThisSkeletonAnimation;
    23.  
    24.     // -------------------------------------------------
    25.     // Unity Callback methods:
    26.     // -------------------------------------------------
    27.     void Start()
    28.     {
    29.         Timeline = GetComponent<Timeline>();
    30.  
    31.         // get current timescale
    32.         if (null != Timeline)
    33.         {
    34.             CurrentTimescale = Timeline.time;  
    35.         }
    36.  
    37.         // cache SkeletonAnimation
    38.         ThisSkeletonAnimation = GetComponent<SkeletonAnimation>();
    39.     }
    40.  
    41.     void Update()
    42.     {
    43.         // if we have both Timeline and SkeletonAnimation components on this object, adjust the timescale of the
    44.         // Spine animations with respect to the timescale of the Timeline. Do this only if the timescale changed.
    45.         if (null != Timeline && !Mathf.Approximately(CurrentTimescale, Timeline.timeScale))
    46.         {
    47.             // if SkeletonAnimation is null, try to get it (maybe it was attached during the lifespan of this game
    48.             // object)
    49.             if (null == ThisSkeletonAnimation)
    50.             {
    51.                 ThisSkeletonAnimation = GetComponent<SkeletonAnimation>();
    52.             }
    53.  
    54.             if (null != ThisSkeletonAnimation)
    55.             {
    56.                 CurrentTimescale = Timeline.timeScale;
    57.                 ThisSkeletonAnimation.timeScale = Timeline.timeScale;
    58.             }
    59.         }
    60.     }
    61. }
     
    Adoll likes this.
  22. daville

    daville

    Joined:
    Aug 5, 2012
    Posts:
    286
    Hi, a Question before purchase.

    Will this Asset help me to create an animated Pause menu using Unity's UI... I mean to pause everything on the game, but still let the Animations of UI to run?
     
  23. zhuchun

    zhuchun

    Joined:
    Aug 11, 2012
    Posts:
    411
    That depends on how you build your game.
    Basically Chronos use a Clock component to adjust the timeScale, and lots of Timescale component(an event listener) attach to gameOjbects. So if you attach Timelines to everything you want to affect, and let other assets work fine with it, you can do it. But you have to know that there's no such a magic word to do that, like a single "PauseAll()" function and then boom! Nope :p
     
  24. daville

    daville

    Joined:
    Aug 5, 2012
    Posts:
    286
    Every "pausable" object should have a Script on that case?

    Would that be an efficient or good way to use this?


    or Can it have like... one parent GameObject and that have the script and every object of the game be a child of that Object and just pause everything inside? is that how this work?
     
  25. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,372
    I believe that's the case, and when you can do it this is probably a good way to design anyway.
     
  26. zhuchun

    zhuchun

    Joined:
    Aug 11, 2012
    Posts:
    411
    I hope so, just made a simple test, unfortunately that cube seems can't inherit timeline from parents. At least in this case it doesn't work, do you have better idea? :)
    heierarchy.png
     
  27. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,372
    Well ... drat. :(
     
  28. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    711
    Believe me, it's both more flexible, more efficient, and a better design to do it on a per-component basis. Adding a Timeline to an object rarely if ever decreases performance: I've spent a lot of time optimizing it using the profiler.

    Ha! That's almost exactly what I have coded for v.2.1 (except I'll add a togglable configuration option on the Timeline when a ParticleSystem is found).
     
  29. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    711
    Chronos has been selected as a finalist for the Unity Awards 2015!


    I was extremely thrilled (and humbled!) to learn today that Chronos had been picked for the Unity Awards 2015 in the Asset Store Awards category. :) Big thanks to the Unity team and to all of you who help me make a quality plugin.

    You can vote for Chronos and all other finalists right here:
    https://unity3d.com/awards/2015

    I'd love to be able to count on your vote, but I'm really just happy to be there. Check out the other finalists, too!

    By the way, this means I might go to the Unite 2015 conference in Boston (Sep 21-23). Are any of you going? Maybe we could meet up!
     
    Arx, Tony707, zhuchun and 1 other person like this.
  30. ConfirmCrit

    ConfirmCrit

    Joined:
    Nov 26, 2013
    Posts:
    7
    Weird question, whenever I download Chronos from the asset store, the package only seems to contain the PDF. Is something wrong on my end or yours?
     
  31. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    711
    Seems like a problem on your end, just tested with the latest version:
    http://i.imgur.com/LHj7bMH.png
     
  32. Der_Kevin

    Der_Kevin

    Joined:
    Jan 2, 2013
    Posts:
    509
    maybe this is a weird question, but. i like the protoype models from the video, where did you get these from/are they included in chronos? :)
     
  33. Tony707

    Tony707

    Joined:
    Jun 15, 2015
    Posts:
    38
    Perfect ! Waiting for this relase then :)
     
  34. Tony707

    Tony707

    Joined:
    Jun 15, 2015
    Posts:
    38
    Another feature suggestion:

    The ability to parent a timeline to a parent gameobject's local clock.
    For example in case this parent has the collider that can be triggered by an area clock.

    I don't know what would be the best option to implement this though :p
    Maybe finding the first available localclock in the parent ?
     
  35. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    711
    They're by BrainBox. The link is in the description in the asset store (at the bottom)!

    The easiest I could think of is to add a LocalClock and a Timeline to your child object, then set in Update of your child object the local clock's timescale to that of the parent's. For example:

    Code (CSharp):
    1. GetComponent<LocalClock>().localTimeScale = transform.parent.GetComponentInParent<LocalClock>().localTimeScale;
    I use transform.parent before GetComponentInParent because this method also returns components on the same GameObject, if I recall correctly.
     
  36. mkgame

    mkgame

    Joined:
    Feb 24, 2014
    Posts:
    592
    In Clock.cs all the awake code belongs to Start(). I always got the error, that the Root-Clock cannot be found. The Awake call order cannot be set, so you cannot hope that the Root clocks Await()'s comes always at first. By the way, does your asset 'Chronos' have a big impact to the performance, especially for mobile games?

    protected virtual void Awake()
    {

    if (string.IsNullOrEmpty(_parentKey))
    {
    parent = null;
    }
    else if (Timekeeper.instance.HasClock(_parentKey))
    {
    parent = Timekeeper.instance.Clock(_parentKey);
    }
    else
    {
    throw new ChronosException(string.Format("Missing parent clock: '{0}'.", _parentKey));
    }

    }
     
  37. mkgame

    mkgame

    Joined:
    Feb 24, 2014
    Posts:
    592
    Hello,

    I bought this asset for stop certain things (freeze the main game) in a game to execute a minigame and to freeze the game if the user switch to the main menu. My problem is, that I can just stop the time for physical things but the update methods are not affected.
    How can I achive this goals? Am I have to give all the dynamic stuffs additionally in the update, lateUpdate and fixedUpdate a flag to return if paused?
    Don't misundertand me, this asset is still good for me, I'am just a bit disapointed that the clocks are not valid clocks, which are able to change the time for certain GameObjects...

    Thanks for your answer in advance.
     
  38. Async0x42

    Async0x42

    Joined:
    Mar 3, 2015
    Posts:
    104
    Personally, I just have a boolean getter that is like bool isPaused { get { return timeline.state == Timeline.paused } }

    Then, in the update or fixed update, you just if (isPaused) return; at the point you don't want to continue if the objects time is stopped.

    (something like that, I don't have the project open, but you get the idea)
     
  39. Async0x42

    Async0x42

    Joined:
    Mar 3, 2015
    Posts:
    104
    This was fixed and ludiq submitted the update, but it hasn't gotten to us yet. He posted a reply with the fixes though, if you'd like to open up the .cs and change it in the meantime. See http://forum.unity3d.com/posts/2264918/
     
  40. mkgame

    mkgame

    Joined:
    Feb 24, 2014
    Posts:
    592
    Thanks Async0x42, did nearly the same. The fix is simple and I check with:

    Code (CSharp):
    1. protected Chronos.GlobalClock clock;
    2.  
    3. protected virtual void Start() {
    4.        clock = Chronos.Timekeeper.instance.Clock("MainGame");
    5.      }
    6.  
    7. protected virtual void Update () {
    8.    
    9.        if (clock.timeScale == 0) {
    10.          return;
    11.        }
    12. ....
    13. }
    In this way you don't have to spam the Timeline script to each scripted child object.
    Works fine now, but trails (TrailRenderer) don't stop with the Timeline script attached to it.
     
    Last edited: Sep 6, 2015
  41. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    711
    That has been discussed in the thread and fixed in v.2.0.5. Make sure you use the latest version.
    Chronos doesn't have a big performance impact (read the first pages of this thread for more explanation); however, rewindable particle systems do. I'm working to minimize that right now.

    That is indeed the correct way to do things. Chronos cannot possibly read and interpret all your code (which could be infinitely complex) to determine what it should and shouldn't execute.

    If you use Time.deltaTime (which you should be doing to normalize your framerate), you can replace it with Timeline.deltaTime, and therefore all values using it will be affected by Chronos.
    You shouldn't check for Clocks; look for Timelines instead. This is more stable and extensible. Have a look at the structure part of the tutorial: http://ludiq.io/chronos/tutorial#Structure

    TrailRenderer, as has been discussed in the thread, are not (yet?) supported. There seems to be no property or method that Unity exposes that would allow me to make them behave according to different time scales.
     
  42. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,372
    I wonder if it is feasible to get Chronos working with a 3rd party trail renderer, like Better Trails ...? He's doing a refactoring right now for a 2.0 version, so if something special needs to be done to accommodate Chronos, maybe it could be worked in.
     
  43. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    711
    I believe it could work, yes. Basically, he surely uses Unity Time methods; replacing them with the equivalent in the migration guide (http://ludiq.io/chronos/migration) would make it compatible with Chronos.

    Otherwise, even more basically, as long as he exposes a "TimeScale" or "Speed" parameter (which ideally can be negative), you simply have to link it with the Timeline's time scale.
     
  44. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,372
    For those interested in getting some trails that work with Chronos, it seems like it could happen. The guy behind Better Trails responded with:

     
  45. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    1,013
    I can expose a timescale value, though I don't think it'll run with a negative value. Once trail points have 'died'/'expired', they are writen over by the system and reused as new trail points. The trail points are stored in a circular buffer, so eventually the new trail points will start eating into the old trail points and there will be no way to 'bring them back to life'. Running in slow-mo should be no problem though!
     
    hopeful and Ludiq like this.
  46. maltadirk

    maltadirk

    Joined:
    Mar 12, 2014
    Posts:
    43
    @ludiq First off I'm loving the asset :)
    I've just run into a slight issue. probably something on my side. So I have a game that when the player moves time slows down. This works for Animated and Transform moving gameobject. However I'm applying the exact same Timeline to a rigidBody2d, however the slow down is not effecting the rigidbody2D gameobject. I'm the Tutorial section it doesn't go into much detail into how to control a RigidBody2D gameobject.
     
  47. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    711
    There seems to be missing properties on the Timeline component; are you using the latest version?
     
    maltadirk likes this.
  48. Hodgson_SDAS

    Hodgson_SDAS

    Joined:
    Apr 30, 2015
    Posts:
    123
    First,

    Congratulations!

    Is it true you're also working on a replay plugin?
     
  49. Ludiq

    Ludiq

    Joined:
    Mar 6, 2015
    Posts:
    711
    I was, but I hit a massive roadblock (namely, I can't serialize or deserialize a GameObject). Unless I somehow find a way around that, I'm not sure how I could release a product up to the quality standards that I want to uphold (which is really unfortunate, because otherwise, the whole plugin is ready, even documented).
     
    DuncanIdaho likes this.
  50. Hodgson_SDAS

    Hodgson_SDAS

    Joined:
    Apr 30, 2015
    Posts:
    123
    That's quite unfortunate, I was really looking forward to that plugin. Maybe if you win the Unity Awards you should ask one of the Unity engineers how to fix this issue.

    Btw, what exactly were some of the features of this plugin?
     
unityunity