Search Unity

TrailRenderer Reset

Discussion in 'Scripting' started by nickavv, Jan 14, 2010.

Thread Status:
Not open for further replies.
  1. nickavv

    nickavv

    Joined:
    Aug 2, 2006
    Posts:
    1,801
    Is there a way that I can temporarily kill a trailRenderer's trail so that when I move an object's position dramatically it doesn't draw a weird trail?

    I tried putting GetComponent(TrailRenderer).time = 0; before the move, and time = 1; at the end, but it didn't work.
     
  2. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    I guess you've already tried disabling/enabling the component?
     
  3. nickavv

    nickavv

    Joined:
    Aug 2, 2006
    Posts:
    1,801
    Yes I have. Upon enabling it, all the trail that would have been drawn while it was disabled appears.

    My solution for now anyways is to disable the trailRenderer, wait for the full 1 second of draw length for my trail size, and then move the object and reenable the renderer. It slows down the pacing of the game a bit, but it doesn't break the gameplay, so I'm cool with that.
     
  4. SarperS

    SarperS

    Joined:
    Mar 10, 2009
    Posts:
    824
    I would like to know how to get it done too.
     
  5. cfexrun

    cfexrun

    Joined:
    Mar 14, 2010
    Posts:
    5
    What about setting the time to 0, then back to whatever it is you want after your transition?
     
  6. GodModeTech

    GodModeTech

    Joined:
    Jun 21, 2010
    Posts:
    66
    That does not work.
     
  7. Drexster

    Drexster

    Joined:
    Feb 3, 2009
    Posts:
    20
    Just ran into this myself. Trying to use a object pooling system so I don't have to Instantiate and Destroy constantly. By design I have the trail Time set fairly high, so it's not an acceptable workaround for my needs.

    Some clean way of resetting a trail renderer would ideal.
     
  8. imtrobin

    imtrobin

    Joined:
    Nov 30, 2009
    Posts:
    1,548
    two years, and still no fix?
     
    guetta18, Zamaroht and nventimiglia like this.
  9. Velvety

    Velvety

    Joined:
    May 4, 2009
    Posts:
    153
    Just ran into the same problem myself. I have ball objects in my game that are fired from a cannon. The balls have a short trail renderer. But if I reload a ball into the cannon after it has be fired into the level, the trail draws all the way back to the cannon.

    I tried disabling/re-enabling the trail renderer when moving the balls to the cannon, but it still draws the trail bits in between when I re-enable it.

    For now I will try the "wait 1 second" method that was mentioned above. Would be nice if it didn't draw any trail for movements when disabled...
     
  10. FiveFingers

    FiveFingers

    Joined:
    Oct 15, 2009
    Posts:
    541
    As far as I remember only disabling the gameobject that carries the trail worked. An object pool system can help (for performance) so you won't destroy / instantiate when the bullet has finished, but you will simply DISABLE the whole bullet/trail gameobject and children, then you will enabling it again.

    Better use a custom trail script than the built-in one, for many reasons. One is surely this. Other are that you can have much more control over it if you code the component yourself.

    If enabling again the component/gameobject results in seeing the trail back route, well, I guess the only fix would be to make this route being drawn on a part of the 3D world where the camera is not rendering.
    If this is still not acceptable, pray :) Can be useful, at least to moderate the pain.
     
  11. sicklepickle

    sicklepickle

    Joined:
    Apr 8, 2012
    Posts:
    44
    There's a pretty easy workaround to this. (I'm framing this in the context or car wheel skids, so apply to whatever you like).

    -When the wheel falls below the skid threshold, we start counting down 30 frames...
    -During this 30 frames, the trail is still *on* but it's not following the car wheel..

    Simply set the "Time" from say 5 seconds to 0.1 seconds a few frames before you turn the thing off ( say 20 or 25 seconds into the countdown).
    It has 5 or 10 or whatever frames to turn off, (which is easy now that it turns off in 0.1 or 0.001 seconds).
    That way it's not moving, but still turned on, and will naturally bring the trails to a proper close.

    Your coundown timer now determines how long the trails stay on screen instead of the Time value.

    Edit:
    Don't forget to start out with a low value, or compare your 1st skid vs 2nd.


    Here's some code:

    Code (csharp):
    1.                
    2.                 public int skidTimeoutCount = -1;
    3.                
    4.                 if ( trailGameObject != null ){
    5.                    
    6.                     float slipFactor = Mathf.Abs(getSidewaysSlip());
    7.                    
    8.                     //we want it to come on and turn off at different values...
    9.                     if ( skiddingOn ){                     
    10.                             if ( slipFactor < 0.25 ){                          
    11.                                 skiddingOn = false;            
    12.                                 skidTimeoutCount = 30;          //start a 30 frame counter before we turn this thing off.                      
    13.                             }                      
    14.                     }else{                     
    15.                         if ( slipFactor > 0.7f ){                          
    16.                             skiddingOn = true;
    17.                             trailGameObject.time = 5.0f;        //reset it back to 5 seconds or whatever tickles your fancy.                   
    18.                         }                      
    19.                     }
    20.                    
    21.                    
    22.                     //count down from 30 when we're below the speed, so the skidmarks stay on screen for 30 frames.
    23.                     if ( skidTimeoutCount > -1 ){
    24.                         skidTimeoutCount--;        
    25.                        
    26.                         //10 frames from the end, we set it to timeout really quickly.
    27.                         //this forces the thing to actually time out and doesn't spazz to the new spot when it's re-enabled.
    28.                         if ( skidTimeoutCount == 10 ){
    29.                             trailGameObject.time = 0.1f;   
    30.                         }
    31.                        
    32.                         //okay, now we've passed 30 full frames.. actually turn the thing off.
    33.                         if ( skidTimeoutCount == -1 ){
    34.                             //well, nothing really....
    35.                         }
    36.                        
    37.                     }
    38.  
    39.                    
    40.                     //only follow the wheel while still skidding
    41.                     // OR  once it's turned off, have it follow the wheel, so it's already in place for when it's switched back on.
    42.                     if ( skiddingOn || (!skiddingOn  skidTimeoutCount == -1) ){
    43.                         trailGameObject.transform.localPosition = Vector3.zero - new Vector3(0, wheelRadius + suspensionTravel , 0 );
    44.                     }
    45.                        
    46.                    
    47.                     //but remain on for about 30 frames afterwards (without following)
    48.                     trailGameObject.enabled =  skiddingOn || (skidTimeoutCount > -1);
    49.                    
    50.                    
    51.                    
    52.                 }// trailGameObject != null
     
    Last edited: Apr 26, 2013
  12. sicklepickle

    sicklepickle

    Joined:
    Apr 8, 2012
    Posts:
    44
    Excuse the double post, but it feels like a different solution might warrant a separate post.

    Following the code I pasted earlier, I had a little brainwave: when the wheel leaves the ground, or you're not skidding.. just warp the trail renderer underground (obviously, don't leave it on all the time though). This way at least you don't need to use a pool system either.

    Pseudocode
    Code (csharp):
    1. trailrenderer.y = (suspension.grounded? wheelPos + wheelRadius : wheelPos + 100 );
     
  13. crogersKixeye

    crogersKixeye

    Joined:
    May 15, 2013
    Posts:
    1
    hey

    setting the time to -1 worked for me. 0 did not, but -1 erases all of the old trails
     
    Gwom likes this.
  14. Languard

    Languard

    Joined:
    Nov 2, 2009
    Posts:
    8
    -1 did not work for me. What I did do was create a coroutine.

    Code (csharp):
    1.  
    2. IEnumerator MoveTrailIn()
    3.     {
    4.         pcEmitter.GetComponent<TrailRenderer>().time = timeDelay;  //timeDelay = 0.02f
    5.         pcEmitter.gameObject.SetActive(false);
    6.         yield return new WaitForSeconds(timeDelay);        
    7.         pcEmitter.position = particleCircle.position;
    8.         pcEmitter.gameObject.SetActive(true);
    9.         yield return new WaitForSeconds(timeDelay);
    10.         pcEmitter.GetComponent<TrailRenderer>().time = emitterTime;  //emitterTime is the original time of the trail
    11.     }
    12.  
    What I'm doing here is switching the emitter from orbiting the object to creating a trail as it moves. First I set the time to a low value then disable the object. Then wait for the life of the new trail time using yield, and move the emitter to its new position. Turn the object back on, wait for another full life span (just to be paranoid) and restore the original time. The time delay is so small it isn't noticeable.
     
  15. magicqy

    magicqy

    Joined:
    Nov 13, 2012
    Posts:
    2
    you can set the trail renderer 's time property to a negative value to clear the trails already displayed.
    but you must wait for a few frames before set negative value back.
    use MonoBehaviour.Invoke("ResetTrails", 0.01f) to do this job.
     
    ktpttd and Glen_Hunter like this.
  16. ufot

    ufot

    Joined:
    Sep 11, 2013
    Posts:
    6
    Thanks, works like a charm!
     
    Glen_Hunter likes this.
  17. scott_dev

    scott_dev

    Joined:
    Mar 14, 2014
    Posts:
    1
    Thank you, using Invoke worked for me as well. Now if only changing the trail renderer's time didn't immediately clear the existing trail. It would look much better in my project if the original trail would fade out as normal, but I suppose that isn't possible being that we are setting the time to -1.
     
  18. philip-mk

    philip-mk

    Joined:
    Aug 1, 2012
    Posts:
    2
    I use a combination of the above approaches that lets the trail expire and doesn't involve caching the original trail time.

    Basically, I use a coroutine to disable a trail renderer:

    Code (CSharp):
    1.     IEnumerator DisableTrail(TrailRenderer trail)
    2.     {
    3.         if (trail.time < 0)
    4.             yield break;
    5.  
    6.         yield return new WaitForSeconds(trail.time);
    7.  
    8.         trail.time = -trail.time;
    9.     }
    And to re-enable it I simple do the following:

    Code (CSharp):
    1. if (trail.time < 0)
    2.     trail.time = -trail.time;
    I keep a list of trail renderers that I find using GetComponentsInChildren and make sure not to move my object while the trail renderer is disabling. If you are using an object pool, use a delayed return that waits for the trail.time before returning to the pool.

    Hope that helps!
     
  19. Glen_Hunter

    Glen_Hunter

    Joined:
    Mar 12, 2014
    Posts:
    3

    Awesome! Just what I needed :D
     
  20. bobding

    bobding

    Joined:
    Mar 31, 2015
    Posts:
    1
    Add a helper component cooperate with TrailRenderer that set its time to 0 in coroutine.

    Code (CSharp):
    1. public class TrailRendererHelper : MonoBehaviour
    2. {
    3.     protected TrailRenderer mTrail;
    4.     protected float mTime = 0;
    5.  
    6.     void Awake()
    7.     {
    8.         mTrail = gameObject.GetComponent<TrailRenderer>();
    9.         if (null == mTrail)
    10.         {
    11.             LogHelper.LogError("[TrailRendererHelper.Awake] invalid TrailRenderer.");
    12.             return;
    13.         }
    14.  
    15.         mTime = mTrail.time;
    16.     }
    17.  
    18.     void OnEnable()
    19.     {
    20.         if (null == mTrail)
    21.         {
    22.             return;
    23.         }
    24.  
    25.         StartCoroutine(ResetTrails());
    26.     }
    27.  
    28.     IEnumerator ResetTrails()
    29.     {
    30.         mTrail.time = 0;
    31.  
    32.         yield return new WaitForEndOfFrame();
    33.  
    34.         mTrail.time = mTime;
    35.     }
    36. }
     
    Atomiz2002 likes this.
  21. lliviu

    lliviu

    Joined:
    Aug 3, 2013
    Posts:
    7
    bobding solution did not work for me not sure why;
    this is what worked (the ResetTrails part):

    Code (CSharp):
    1.  
    2.  
    3.    
    4.     override public Transform positionAndActivate(Vector3 position, Quaternion rotation)
    5.     {
    6.         Transform objectTemp = base.positionAndActivate(position, rotation);
    7.  
    8.         StartCoroutine(ResetTrails(objectTemp));
    9.         return objectTemp;
    10.     }
    11.  
    12.     IEnumerator ResetTrails(Transform objectTemp)
    13.     {
    14.         TrailRenderer trailRender = objectTemp.gameObject.GetComponent<TrailRenderer>();
    15.         trailRender.time = -1f;
    16.        
    17.         yield return new WaitForEndOfFrame();
    18.         trailRender.time = 0.35f;
    19.     }
    20.  
     
  22. nxtboyIII

    nxtboyIII

    Joined:
    Jun 4, 2015
    Posts:
    281
    Man, thank you so much! It works perfect! :D
     
    Qmansvednetta likes this.
  23. maxrevilo

    maxrevilo

    Joined:
    Oct 6, 2014
    Posts:
    1
    Thank you, it works plug and play and with the APS Polling System!
     
  24. renuke

    renuke

    Joined:
    Feb 4, 2016
    Posts:
    6
    EsmailKM, ngduykhanh, maramak and 3 others like this.
  25. ignacevau

    ignacevau

    Joined:
    Apr 21, 2015
    Posts:
    2
    roger0 likes this.
  26. mat108

    mat108

    Joined:
    Aug 24, 2018
    Posts:
    131
    This worked for me, in case anyone finds this post via google.

     
  27. ngduykhanh

    ngduykhanh

    Joined:
    Mar 14, 2018
    Posts:
    5
  28. EsmailKM

    EsmailKM

    Joined:
    Dec 27, 2019
    Posts:
    2
    Brockert likes this.
  29. Bitwak

    Bitwak

    Joined:
    May 10, 2014
    Posts:
    27
    This solution is not working for me.

    It seems that every time that I draw the trail into a new position it is starting from where I left it during the previous drawing. Neither clear nor disable/enable or time tricks are working.
     
    Danielkip and Ragir like this.
  30. Qmansvednetta

    Qmansvednetta

    Joined:
    Mar 8, 2017
    Posts:
    8
    Worked like a charm!
     
    Atomiz2002 likes this.
  31. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,474
    Please use the "Like" button so as not to necro the thread for everyone.

    Thanks.
     
Thread Status:
Not open for further replies.