Search Unity

UnitySkidmarks: Free skidmark generation system

Discussion in 'Assets and Asset Store' started by Nition, May 10, 2017.

  1. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Skidmark generator scripts in Unity that I've found in the past either seem to have bad performance, or they're trail renderers where the whole thing disappears as soon as the car stops skidding.

    I've made one that's kind of based on the really old official car tutorial's one, but instead of insane garbage generation that uses up quarter of your CPU in a frame every half second, it generates no garbage. Performance is good unless you're doing something insane.

    Do what you want with this: https://github.com/Nition/UnitySkidmarks



    Update in 2021: Please note that as of 2021 this project still works, and feel free to use it, but I won't be maintaining it or providing support for it any longer.
     
    Last edited: Jun 7, 2021
  2. freedom667

    freedom667

    Joined:
    Sep 6, 2015
    Posts:
    425
    is this works as 2D TopDown?
     
  3. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    I've never actually used the 2D side of Unity. If it's just basically a camera looking straight down it should work. You control when and where the skidmarks generate, and they're just a mesh.
     
    Last edited: Jul 23, 2020
    Raya2408 likes this.
  4. Wenon

    Wenon

    Joined:
    Mar 18, 2018
    Posts:
    19
    Hi, your script works great except one thing, marks are placed even during normal turning, do you know how to fix this?
     
  5. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Edit: The previous post has been edited, and I was replying here to it originally reading: "Hi, your script works great except one thing, marks are under terrain and distant."

    Hmm, I use the same script on Unity terrain with no trouble, but I haven't tested it in recent Unity versions. Does it look correct if you run the Sample Scene?
     
    Last edited: Aug 24, 2019
  6. Wenon

    Wenon

    Joined:
    Mar 18, 2018
    Posts:
    19
  7. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    It looks like you're holding the handbrake on those turns? Or maybe wheel physics have changed a little in the latest Unity versions. The physics on that car are pretty bad anyway honestly - it's a default Unity sample car. I wouldn't recommend using it in a proper game, it's just in there to show how the skidmarks work.

    Re skidmarks on turns. Check out WheelSkid.cs in the project. It's pretty simple and commented. Note how the skidTotal is calculated as a sum of the sideways slip (car not going the way it's facing) and wheel spin (loss of traction). You could remove or modify the sideways slip calculation if you like.
     
  8. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    @Wenon , have a look at this line:


    Code (CSharp):
    1. // NOTE: This extra line should not be needed and you can take it out if you have decent wheel physics
    2. // The built-in Unity demo car is actually skidding its wheels the ENTIRE time you're accelerating,
    3. // so this fades out the wheelspin-based skid as speed increases to make it look almost OK
    4. wheelSpin = Mathf.Max(0, wheelSpin * (10 - carForwardVel));
     
    Wenon likes this.
  9. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Thanks Deeeds, I forgot about that line! That just goes to show how bad the default vehicle actually is.
     
    Deeeds likes this.
  10. Wenon

    Wenon

    Joined:
    Mar 18, 2018
    Posts:
    19
    Thank you, much better when I changed 10 to 0
     
    Deeeds likes this.
  11. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    @Wenon I'm really glad you're able to discern which way to move which number. I didn't have a clue. My math skills are in minus territory. I was purely entertained (and drawn to this line) by the fact it's not necessary and so pointedly/humorously commented. I didn't even dare suggest which part of it to try changing to get a desired result. It's Egyptian hieroglyphics, to me.

    @Nition you deserve an award for figuring out the problems and how to solve them. I have been completely mystified by the Wheel Collider. It seems like a bad idea, badly designed and badly implemented.
     
    Wenon likes this.
  12. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Maths is one thing, but don't ever feel bad that you can't get the wheel colliders to work - they've been almost unusable since the PhysX update in Unity 5.0. You're either sliding on ice or jittering off into space with anything but the most generic vehicle.

    In case you're even thinking of feeling bad that you can't get the wheel collider to work for you, consider that:

    • The official example vehicle is constantly losing traction when accelerating at any speed. Unity Technologies themselves couldn't make it work right.
    • Even Edy, the creator of the most popular vehicle package on the Asset store, couldn't get them to work without disabling most of what they usually do. (source)

    Funnily enough the Unity 4 version of the wheel colliders was actually not bad.
     
    Last edited: May 14, 2018
    samochreno likes this.
  13. wilco3d

    wilco3d

    Joined:
    Feb 15, 2015
    Posts:
    6
    Great Job Nition! It's almost a drop in replacement for Realistic Car Controller's SkidMark system - except now rather than 190KB of GC every frame (lots of vehicles), I'm now getting 0B.. Thanks!

     
    Nition, Razmot and N47 like this.
  14. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Thanks. :)

    I haven't used Realistic Car Controller but I bet theirs is based on the insane garbage generating one from the old Unity 3 Car Tutorial.
     
    Deeeds likes this.
  15. K4M1s

    K4M1s

    Joined:
    Jun 25, 2018
    Posts:
    3
    Thanks for sharing this script. I've got a small problem with using it. The side marks are way off the position that should be.
    Code (CSharp):
    1. Vector3 localVelocity = transform.InverseTransformDirection(m_Rigidbody.velocity);
    2.                 float skidTotal = Mathf.Abs(localVelocity.x);
    3.  
    4.                 float wheelAngularVelocity = m_WheelColliders[i].radius * ((2 * Mathf.PI * m_WheelColliders[i].rpm) / 60);
    5.                 float carForwardVel = Vector3.Dot(m_Rigidbody.velocity, transform.forward);
    6.                 float wheelSpin = Mathf.Abs(carForwardVel - wheelAngularVelocity) * WHEEL_SLIP_MULTIPLIER;
    7.  
    8.                 // NOTE: This extra line should not be needed and you can take it out if you have decent wheel physics
    9.                 // The built-in Unity demo car is actually skidding its wheels the ENTIRE time you're accelerating,
    10.                 // so this fades out the wheelspin-based skid as speed increases to make it look almost OK
    11.                 wheelSpin = Mathf.Max(0, wheelSpin * (0 - carForwardVel));
    12.  
    13.                 skidTotal += wheelSpin;
    14.  
    15.                 if (skidTotal >= SKID_FX_SPEED)
    16.                 {
    17.                     float intensity = Mathf.Clamp01(skidTotal / MAX_SKID_INTENSITY);
    18.  
    19.                     Vector3 skidPoint = wheelHit.point + (m_Rigidbody.velocity * (Time.time - lastFixedUpdateTime));
    20.                     lastSkid = skidmarksController.AddSkidMark(skidPoint, wheelHit.normal, 1, lastSkid);
    21.                 }
    22.                 else
    23.                 {
    24.                     lastSkid = -1;
    25.                 }
    This is my code for creating them. Any ideas?
     
  16. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    That code you pasted is just part of WheelSkid.cs that comes with the project. Do the skidmarks show in the right place when you're running the default test scene that comes with it, before you've made any changes?

    Check where your wheelHit.point actually is - does it match your wheel positions?

    Try removing the velocity component, just setting skidPoint = wheelHit.point, and see where it ends up then.
     
  17. K4M1s

    K4M1s

    Joined:
    Jun 25, 2018
    Posts:
    3
    wheelHit.point is in good position.
    I've removed the velocity component and there is no changes.
    Test scene was working fine.
     
  18. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Okay, I'm out of ideas then I'm afraid - something's different between yours and the original test scene. Maybe post here if you manage to work it out, just in case others have the same issue in the future.
     
  19. K4M1s

    K4M1s

    Joined:
    Jun 25, 2018
    Posts:
    3
    ok, i'm stupid. Object with skidmarks controller was not on position 0 0 0 but 21 -8 0......
     
  20. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Ah, that's not that stupid, I should be allowing for that or at least putting in a note that it needs to be at 0,0,0. Thanks for bringing it up. I think Wenon earlier in this thread probably had the same issue when they said "your script works great except one thing, marks are under terrain and distant", but they edited their post to something else after fixing it.
     
    Last edited: Aug 25, 2019
  21. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Just added a check to the source that sets the transform position to 0,0,0 if it isn't already and warns the user. Thanks for working out the issue and letting me know.
     
  22. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Imagine you have a mesh of say, a sphere, and you delete the vertices from around the equator. Now you have two hemispheres, but still only one mesh, with a gap in it. Meshes don't have to be contiguous.

    The only problem is occlusion culling - the skidmarks always draw, everywhere on the map, since they'll all really one object.
     
  23. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    866
    I assume this does not work with HDRP?
     
  24. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    I haven't tested, but I don't know any particular reason why it wouldn't.
     
  25. Freznosis

    Freznosis

    Joined:
    Jul 16, 2014
    Posts:
    298
    Works fine in HDRP. It's just code. You will need to create a shader in Shader Graph though.
     
  26. puzzlekings

    puzzlekings

    Joined:
    Sep 6, 2012
    Posts:
    404
    @Nition Thanks for this

    In my case I had to have multiple skid mark controllers for this to work - one for each wheel (as I'm not using wheel colliders)

    I found with the script as it was with one controller it failed to draw the skid mark meshes for all wheels, hence I had to separate.

    Hope this helps someone.
     
  27. FeedMyKids1

    FeedMyKids1

    Joined:
    May 17, 2017
    Posts:
    5
    Don't want to cause a fuss or whatever but this looks like it was almost exactly copy and pasted into Realist Car Controllers skidmark system.

    Not sure when he changed his but I've been going through that asset to fix it and saw that the Skidmarks script is not like his usual coding (this is a little more math/manual transform intensive and has comments...)- A quick lookup of Unity Skidmarks led me here and I figured I'd tell you that someone else put their "copyright" on what looks almost exactly the same as your work.
     
    Last edited: Dec 31, 2020
  28. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Thanks for the heads up. I released it under the BSD 2-Clause "Simplified" License which is very permissive, so they are allowed to use it in a commercial package.

    They should have included the following licence text somewhere though, to cover the skidmarks source code: https://github.com/Nition/UnitySkidmarks/blob/master/LICENCE
    If they haven't done that and are just acting like they wrote it then they are breaking the rules.
     
  29. FeedMyKids1

    FeedMyKids1

    Joined:
    May 17, 2017
    Posts:
    5
    Going through and reading it, there are slight differences but it's almost the same - maybe it's an earlier version of yours.

    They don't have the license text on it.
     
  30. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Thanks for the heads up, I'll send them a message.
     
    Last edited: Jan 17, 2021
  31. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Just to update you @Kampinkarl1 ; I decided to buy the asset myself to check it out. I see what's happened. We've both based our code originally on the skidmarks code that came with the old Unity 3 Car Tutorial. The similarities are just the parts that remained the same in mine from the old car tutorial version. So they're fine - they're not copying mine.

    Having said that, if you're using Realistic Car Controller I'd actually recommend swapping their skidmarks code out for mine, which should be pretty straightforward as they're similar in how they work. Reason being that the old car tutorial code that Realistic Car Controller is using regenerates the entire skidmarks mesh from scratch every frame, which causes massive garbage collection spikes. Mine generates zero garbage so it's a lot easier on the CPU.
     
    Last edited: Jan 19, 2021
  32. Peeling

    Peeling

    Joined:
    Nov 10, 2013
    Posts:
    443
    Just picked this up - a great time-saver!

    If you don't mind me saying, it would have saved even more time but for an issue I had to find and fix:

    The fudge in the main skidmarks script to discard connected marks over a certain length had me scratching my head for ages as to why the skidmarks just stopped working above about 40mph. The correct fix, in my opinion, is to put 'lastSkid' values returned to WheelSkid scripts into a 'do not re-use' list until they are a) passed back in as 'lastSkid' values when generating a new skidmark, or b) explicitly abandoned by the WheelSkid when setting 'lastSkid' to -1.

    (EDITED: My bad - the other issue wasn't strictly a bug. Unity's wheel collider ignores transform orientation and instead works entirely off parent rigid body orientation. Depending on how your artist builds his wheels, you might end up with wheel transforms that don't tally up with the wheelskid script's assumptions about local X.
     
    Last edited: Jan 25, 2021
  33. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Yeah @Peeling that hack to fix the looping-around bug is the worst part of the skidmarks system I think. I only discovered the bug that it solves relatively recently and didn't have a lot of time of my hands so it got a less polished solution. To be clear I mean this part:

    Code (CSharp):
    1.  
    2. // Fixes an awkward bug:
    3. // - Car draws skidmark, e.g. index 50 with last index 40.
    4. // - Skidmark markIndex loops around, and other car overwrites index 50
    5. // - Car draws skidmark, e.g. index 45. Last index was 40, but now 40 is different, changed by someone else.
    6. // This makes sure we ignore the last index if the distance looks wrong
    7. if (distAndDirection.sqrMagnitude > MIN_SQR_DISTANCE * 10) {
    8.     lastIndex = -1;
    9.     lastSection = null;
    10. }
    11.  
    Unfortunately I don't really have the time to implement and test a better solution at the moment. If someone were to submit a pull request...
     
  34. FeedMyKids1

    FeedMyKids1

    Joined:
    May 17, 2017
    Posts:
    5
    Thanks for the update.

    The reason the Skidmarks class stuck out to me in his project was because it was so dissimilar to how he writes (There were comments and it's a bit more organized in the Unity-based code).
    I read through most of that project (RCC) - or at least 3000 lines of it - and I get a bit of PTSD thinking about going in to change anything else (I spent about 60 hours on it trying to both make it more efficient and more modular).

    The thing is, RCC has the type of driving that I wanted - sort of a GTA V style. So I can't really flame the guy further than I have.

    I wonder if Edy's Car Physics is any better.
     
  35. Lars-Steenhoff

    Lars-Steenhoff

    Joined:
    Aug 7, 2007
    Posts:
    3,527
    I would like to use this system with sphere collider, can I just swap out every reference with wheel collider to sphere collider?
     
  36. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Yep, that should be fine. Since your collider won't have the helpful GetGroundHit method that WheelColliders have though, you will need to do your own calculation of whether your collider is hitting the ground, and what the normal (the "up" direction) to the ground is at that point.
     
  37. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    I feel like this applies to nearly every large code asset on the Asset Store. :(
     
  38. Lars-Steenhoff

    Lars-Steenhoff

    Joined:
    Aug 7, 2007
    Posts:
    3,527
    280C91F8-993D-48D8-BF3B-4964D5D6DC2E.png
    If its not too much trouble would you be able to add this option ? I'm not a coder but I love to use your system.

    The asset I'm using for the sphere collider has a funtion for ground check, I dont think it had one for ground normal up direction, any tips on how that is called in unity?

    My end goal is to have a texture for the skidmarks that represent a real tire mark, and has parts where the track is masked off.
     
  39. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    You'd want to raycast from inside your spheres straight down, something like this:

    Code (CSharp):
    1. RaycastHit hit;
    2. // You'd have this raycast distance be just enough that the ray
    3. // ends just below your sphere, so that if the raycast hits, you
    4. // can consider it to be on the ground
    5. float maxDist= 2.0f
    6.  
    7. if (Physics.Raycast(spherePos, -Vector3.up, out hit, maxDist)) {
    8.    // Sphere is on the ground if we get here
    9.    // You can use hit.normal to get the normal of the hit surface
    10. }
     
  40. Elharter

    Elharter

    Joined:
    Sep 20, 2015
    Posts:
    58
    Ive tried to remake your work, fitting to my physics model, which works with just 1 sphere for an arcade mode.
    So, i had to change some lines to make it work, but it doesnt work correctly.

    The Skidmark will not appear to the right time, and to the right place.

    For test purposes i have leveraged a few things, lets come to the important lines:

    Code (CSharp):
    1. // Skid if we should
    2.             if (skidTotal >= SKID_FX_SPEED) {
    3.                 float intensity = Mathf.Clamp01(skidTotal / MAX_SKID_INTENSITY);
    4.                 // Account for further movement since the last FixedUpdate
    5.                 Vector3 skidPoint = wheelHitInfo.point + (rb.velocity * (Time.time - lastFixedUpdateTime));
    6.                 lastSkid = skidmarksController.AddSkidMark(skidPoint, wheelHitInfo.normal, Color.green, lastSkid);
    7.             }
    8.             else {
    9.                 lastSkid = -1;
    10.             }
    I´ve changed this to my 2 wheels (because i do not have real wheels, just a sphere in the middle) with skidmark-pointers for the transform.

    So i changed to this:
    Code (CSharp):
    1.  
    2.   Vector3 skidPoint0 = carController.skidMarks[0].transform.position + (carController.rbody.velocity * (Time.time - lastFixedUpdateTime));
    3.  lastSkid = skidmarksController.AddSkidMark(skidPoint0, carController.skidMarks[0].transform.position, Color.black, lastSkid);
    4.  
    5.  
    But the skidmark is:
    a) to late, behaviour is not fitting to my drifting, it comes everytime much too late
    b) the positioning of the skidmarks are misplaced...

    So i dont really get the point about "rbody.velocity * (time.time - lastfixedupdatime) ...." - i think this is the problem
     
  41. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    I might be too late answering here but:

    #1. If you change:
    Code (CSharp):
    1. Vector3 skidPoint0 = carController.skidMarks[0].transform.position + (carController.rbody.velocity * (Time.time - lastFixedUpdateTime));
    to just:
    Code (CSharp):
    1. Vector3 skidPoint0 = carController.skidMarks[0].transform.position;
    do the skidmarks end up at nearly the correct position? I'd expect them to appear just slightly behind where they should be with that setup. If they don't, there's something else wrong.

    #2. In the second line, you need something for the normal. Using the position won't work. It'd be best to get the normal direction of the terrain at that point but a quick version would be use the up direction of your skid point. So change it to:
    Code (CSharp):
    1. lastSkid = skidmarksController.AddSkidMark(skidPoint0, carController.skidMarks[0].transform.up, Color.black, lastSkid);
     
  42. Elharter

    Elharter

    Joined:
    Sep 20, 2015
    Posts:
    58
    nono, i waited for your feedback :) I will test it within the next 2 days

    thanks!
     
  43. shahzaib

    shahzaib

    Joined:
    Dec 14, 2013
    Posts:
    32
    nice share!! it also works with Rigidbodies instead of wheelcolliders? @Nition
     
    Lars-Steenhoff likes this.
  44. Lars-Steenhoff

    Lars-Steenhoff

    Joined:
    Aug 7, 2007
    Posts:
    3,527
    I also would like to use it with a rigid body sphere, but I don't know how to script the changes.
     
  45. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Sorry, I can't help all of you, but yes it can work with anything, as long as you can provide the system with a position and a normal (up) vector.
     
    shahzaib likes this.
  46. shahzaib

    shahzaib

    Joined:
    Dec 14, 2013
    Posts:
    32
    thats more than enough, thanks again.
     
  47. Lars-Steenhoff

    Lars-Steenhoff

    Joined:
    Aug 7, 2007
    Posts:
    3,527
    If you can make it work will you be able to share how you did it? Thanks
     
  48. shahzaib

    shahzaib

    Joined:
    Dec 14, 2013
    Posts:
    32
    I'm on a pretty tight schedule, I may not be able to give you an update any time soon but I did try to make it work with my custom wheel collider solution (where wheels are actual rigidbodies) and sadly it didn't work for me.
     
    Lars-Steenhoff likes this.
  49. simonvutov1

    simonvutov1

    Joined:
    May 28, 2020
    Posts:
    4
    Hey, how can I make this work if I'm not using wheel colliders?
     
  50. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Skidmarks.cs will work with anything, given the right calls to AddSkidMark. Check out what WheelSkid.cs does, but swap out whenever it uses a wheelCollider for your own thing. As long as you can send a series of positions and normals to AddSkidMark it'll work, but do take note of how the lastSkid value is used.

    You will need some coding ability to use it without WheelColliders.