Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by Muhwu · Jun 17, 2013 at 12:48 AM · renderingfootstepstrailspermanent

Rendering permanent trails? (such as footsteps)

I'm new to Unity and have been experimenting around. Basically I have an idea for something that would require rendering "permanent" trails (or perhaps some that would fade over a given interval) like footsteps.

What I'm looking to do is to have a trigger (such as pressing breaks or stepping in to dog poo) that will start the trail process. The trail will then continue for distance X and fade away, but the trail left should be permanent. The trail should be scriptable in the sense that I want different types of trails (f.ex. depending on the material) to behave differently.

Furthermore, since I mentioned footsteps, it would be nice if it would be at least slightly footstep like, but I can "make do" with the trail texture being 2 foot steps if more fancy stuff is too complicated.

Any pointers on how I can achieve this? I found this "Trail Renderer" thing and some tutorial but I got the impression that it's usually temporary.

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image robertbu · Jun 17, 2013 at 04:26 AM 0
Share

The most efficient method I can think of would to dynamically modify/add to a mesh. Each quad would be a footsteps. The different footsteps (left and right as well as the different kinds for different terrain) would come from a texture atlas. So the mesh would draw in a single draw call. You could have 1000s of steps without seriously impacting performance. But between the mesh manipulation and the UV/texture atlas code, it would be a fairly major coding effort

avatar image SinisterRainbow · Jun 17, 2013 at 04:33 AM 0
Share

There's a AAA game that recently did something like this, and only for snow (it did manage to run reasonably well on PS3).. Definitely a large coding effort.

avatar image Muhwu · Jun 17, 2013 at 09:29 AM 0
Share

Aye, my first instinct as a game programmer was to simply have some sort of mesh that i would modify. I didn't mention it here, but the surface I'm rendering on is flat in the current design so that removes some complexity from the issue :)

2 Replies

· Add your reply
  • Sort: 
avatar image
7
Best Answer

Answer by AlucardJay · Jun 19, 2013 at 03:24 AM

This answer is based off the the method described by robertbu, an example can be found in the unity car tutorial in the skidmarks script. I have no idea and cannot find where this 'Unity Footstep' script is.

For my answer, here is a footprint gameObject with a mesh that gets updated by the player object. Player object tells the Footprints script where to place a footprint and what type of footprint, then the Footprints script calculates where that footprint goes, also if it is a left or right footprint, then updates the mesh information.

  • create a new scene, delete the camera (first person controller prefab has a camera)

  • add a terrain, set the layer to "Water"

  • add a first person controller (and a directional light)

  • create an empty gameObject

  • name it "Footprints"

  • set the position to 0,0,0

  • attach the Footprints script to the Footprints object

  • create a footprint material, attach it to the Footprints object

  • set the terrain layer on the Footprints object to "Water"

  • attach the PlayerFootprints script to the first person controller

Hit play, walk around, footprints should be left behind. These footprints are random, just to show how the player script adds the footstep, but also states what type of footstep to leave. The Footsteps script looks after the size and offset of the footprints.

Variables :

Footprints :

 public var maxFootprints : int = 256; // Maximum number of footprints total handled by one instance of the script.
 public var footprintSize : Vector2 = Vector2( 0.4, 0.8 ); // The size of the footprint. Should match the size of the footprint that it is used for. In meters.
 public var footprintSpacing : float = 0.3; // the offset for the left or right footprint. In meters.
 public var groundOffset : float = 0.02;    // The distance the footprints are places above the surface it is placed upon. In meters.
 public var terrainLayer : LayerMask; // the layer of the terrain, so the footprint raycast is only hitting the terrain.

PlayerFootprints :

 public var footprintSpacing : float = 2.0; // distance between each footprint


Now for the scripts :

Footprints :

 //------------------------------//
 //  Footprints.js               //
 //  Written by Alucard Jay      //
 //  6/19/2013                   //
 //------------------------------//
 
 #pragma strict
 @script RequireComponent( MeshFilter, MeshRenderer )
 
 
 public var maxFootprints : int = 256; // Maximum number of footprints total handled by one instance of the script.
 public var footprintSize : Vector2 = Vector2( 0.4, 0.8 ); // The size of the footprint. Should match the size of the footprint that it is used for. In meters.
 public var footprintSpacing : float = 0.3; // the offset for the left or right footprint. In meters.
 public var groundOffset : float = 0.02;    // The distance the footprints are places above the surface it is placed upon. In meters.
 
 public var terrainLayer : LayerMask; // the layer of the terrain, so the footprint raycast is only hitting the terrain.
 
 
 private var mesh : Mesh;
 
 private var vertices : Vector3[];
 private var normals : Vector3[];
 private var uvs : Vector2[];
 private var triangles : int[];
 
 private var footprintCount : int = 0;
 
 private var isLeft : boolean = false;
 
 
 // Initializes the array holding the footprint sections.
 function Awake()
 {
     // - Initialize Arrays -
     
     vertices = new Vector3[ maxFootprints * 4 ];
     normals = new Vector3[ maxFootprints * 4 ];
     uvs = new Vector2[ maxFootprints * 4 ];
     triangles = new int[ maxFootprints * 6 ];
     
     // - Initialize Mesh -
     
     if ( GetComponent( MeshFilter ).mesh == null )
     {
         GetComponent( MeshFilter ).mesh = new Mesh();
     }
     
     mesh = GetComponent( MeshFilter ).mesh;
     
     mesh.name = "Footprints_Mesh";
 }
 
 
 // Function called by the Player when adding a footprint. 
 // Adds the information needed to create the mesh later. 
 public function AddFootprint( pos : Vector3, fwd : Vector3, rht : Vector3, footprintType : int )
 {
     // - Calculate the 4 corners -
     
     // foot offset
     var footOffset : float = footprintSpacing;
     
     if ( isLeft )
     {
         footOffset = -footprintSpacing;
     }
     
     var corners : Vector3[] = new Vector3[ 4 ];
     
     // corners = position + left/right offset + forward + right
     corners[ 0 ] = pos + ( rht * footOffset ) + ( fwd * footprintSize.y * 0.5 ) + ( -rht * footprintSize.x * 0.5 ); // Upper Left
     corners[ 1 ] = pos + ( rht * footOffset ) + ( fwd * footprintSize.y * 0.5 ) + ( rht * footprintSize.x * 0.5 ); // Upper Right
     corners[ 2 ] = pos + ( rht * footOffset ) + ( -fwd * footprintSize.y * 0.5 ) + ( -rht * footprintSize.x * 0.5 ); // Lower Left
     corners[ 3 ] = pos + ( rht * footOffset ) + ( -fwd * footprintSize.y * 0.5 ) + ( rht * footprintSize.x * 0.5 ); // Lower Right
     
     
     // raycast to get the position and normal for each corner
     var hit : RaycastHit;
     
     for ( var i : int = 0; i < 4; i ++ )
     {
         var rayPos : Vector3 = corners[ i ];
         rayPos.y = 1000.0;
         
         if ( Physics.Raycast( rayPos, -Vector3.up, hit, 2000.0, terrainLayer ) ) // also add a layermask for the terrain
         {
             var index : int = ( footprintCount * 4 ) + i;
             
             // - Vertex -
             vertices[ index ] = hit.point + ( hit.normal * groundOffset );
             
             // - Normal -
             normals[ index ] = hit.normal;
             
         }
     }
     
     
     // - UVs -
     
     // what type of footprint is being placed
     var uvOffset : Vector2;
     
     switch( footprintType )
     {
         case 1 :
             uvOffset = Vector2( 0.5, 1.0 );
         break;
         
         case 2 :
             uvOffset = Vector2( 0.0, 0.5 );
         break;
         
         case 3 :
             uvOffset = Vector2( 0.5, 0.0 );
         break;
         
         default :
             uvOffset = Vector2( 0.0, 1.0 );
         break;
     }
     
     // is this the left foot or the right foot
     switch( isLeft )
     {
         case true :
             uvs[ ( footprintCount * 4 ) + 0 ] = Vector2( uvOffset.x + 0.5, uvOffset.y );
             uvs[ ( footprintCount * 4 ) + 1 ] = Vector2( uvOffset.x, uvOffset.y );
             uvs[ ( footprintCount * 4 ) + 2 ] = Vector2( uvOffset.x + 0.5, uvOffset.y - 0.5);
             uvs[ ( footprintCount * 4 ) + 3 ] = Vector2( uvOffset.x, uvOffset.y - 0.5 );
             
             isLeft = false;
         break;
         
         case false :
             uvs[ ( footprintCount * 4 ) + 0 ] = Vector2( uvOffset.x, uvOffset.y );
             uvs[ ( footprintCount * 4 ) + 1 ] = Vector2( uvOffset.x + 0.5, uvOffset.y );
             uvs[ ( footprintCount * 4 ) + 2 ] = Vector2( uvOffset.x, uvOffset.y - 0.5 );
             uvs[ ( footprintCount * 4 ) + 3 ] = Vector2( uvOffset.x + 0.5, uvOffset.y - 0.5);
             
             isLeft = true;
         break;
     }
     
     
     
     // - Triangles -
     
     triangles[ ( footprintCount * 6 ) + 0 ] = ( footprintCount * 4 ) + 0;
     triangles[ ( footprintCount * 6 ) + 1 ] = ( footprintCount * 4 ) + 1;
     triangles[ ( footprintCount * 6 ) + 2 ] = ( footprintCount * 4 ) + 2;
     
     triangles[ ( footprintCount * 6 ) + 3 ] = ( footprintCount * 4 ) + 2;
     triangles[ ( footprintCount * 6 ) + 4 ] = ( footprintCount * 4 ) + 1;
     triangles[ ( footprintCount * 6 ) + 5 ] = ( footprintCount * 4 ) + 3;
     
     
     // - Increment counter -
     footprintCount ++;
     
     if ( footprintCount >= maxFootprints )
     {
         footprintCount = 0;
     }
     
     // - update mesh with new info -
     ConstructMesh();
 }
 
 
 function ConstructMesh() 
 {
     mesh.Clear();
     
     mesh.vertices = vertices;
     mesh.normals = normals;
     mesh.triangles = triangles;
     mesh.uv = uvs;
 }


PlayerFootprints :

 //------------------------------//
 //  PlayerFootprints.js         //
 //  Written by Alucard Jay      //
 //  6/19/2013                   //
 //------------------------------//
 
 #pragma strict
 
 public var footprints : Footprints;
 
 public var footprintSpacing : float = 2.0; // distance between each footprint
 
 private var lastPos : Vector3 = Vector3.zero;
 
 
 function Start() 
 {
     lastPos = transform.position;
     
     if ( !footprints )
     {
         footprints = GameObject.Find( "Footprints" ).GetComponent( Footprints );
     }
 }
 
 
 function Update() 
 {
     var distFromLastFootprint : float = ( lastPos - transform.position ).sqrMagnitude;
     
     if ( distFromLastFootprint > footprintSpacing * footprintSpacing )
     {
         // AddFootprint( pos : Vector3, fwd : Vector3, rht : Vector3, footprintType : int )
         //footprints.AddFootprint( transform.position, transform.forward, transform.right, 0 );
         footprints.AddFootprint( transform.position, transform.forward, transform.right, Random.Range( 0, 4 ) );
         
         lastPos = transform.position;
     }
 }


Footprints source image : http://www.bytedust.com/free-shoe-sole-print-vector-design

Edited image : http://www.alucardj.net16.net/unityanswers2013/footprints_256x512.png

Complete package : http://www.alucardj.net16.net/unityanswers2013/Footprints.unitypackage


Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Muhwu · Jun 19, 2013 at 09:08 PM 0
Share

Whoa, thanks man. This is awesome.

avatar image
0

Answer by SinisterRainbow · Jun 17, 2013 at 04:14 AM

There's a free script in Unity that does footsteps. It's cool to walk through things and leave trails, I like that idea.

You can modify it quite easily when you come into contact with say dog shit, just make sure it has a collider with a trigger. At that point, you can set new particle effects for footsteps, using perhaps the foot position.

For permanent trails, I really don't think you want to do this. It may sound cool, but there's a reason other engines haven't done it (using effects), it's because it increases drawcalls, and could dramatically increase them to the point the game barely runs. (ie, it WILL for some players, if it can happen in a game, it will happen is the rule).

Even if they just walk through a pile creating footsteps in a small area, this will be a huge problem. You're adding a new texture to the scene each footstep, with one or more drawcalls. It won't take long before the game is running at 0.1 fps.

Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image robertbu · Jun 17, 2013 at 04:23 AM 0
Share

The textures are shared/material is shared, so even in the worst case, the footsteps should batch. But if you do each step with a separate game object, you will drag the game down.

avatar image SinisterRainbow · Jun 17, 2013 at 04:29 AM 0
Share

That could be, I'm assu$$anonymous$$g they are not batched but very well may be wrong.

avatar image Muhwu · Jun 17, 2013 at 09:26 AM 0
Share

Alright, I'll try to look it up. Leaving trails is really a core mechanic in my idea so it is necessary that they are permanent. However, I doubt that there will be a huge amount of them. That being said, I can't have each footstep as a separate game object (and definitely don't want to).

I am actually not sure how heavy operation it would be to render a square for every 2 footsteps or so, but yeah - I don't really have a vision of how this would work in Unity, I know how I could just have some sort of vertex array if doing it from scratch as having a trail of footsteps would probably not be too many triangles added to the scene.

Anyway, I'll look up the footstep script and see if it is efficient enough for my purposes, it might well be. Thanks. :)

avatar image SinisterRainbow · Jun 17, 2013 at 12:15 PM 0
Share

You should maybe try just using the footsteps script and check the unity stats in the game window to see if new draw calls are being added. In CryEngine they don't seem to batch (and I don't see this in any game, AAA or otherwise) so I assume you cannot, but worth a try. Usually if it's represented as a decal, it's projecting onto a surface (not creating say a square plane with a texture affixed to it), and not creating a separate mesh that can be batched. This is my experience, but I don't know how Unity does it. I know unity can batch particle systems, but you'll have to check out the specifics.

Even if it proves to not batch, you could make a simple game mesh plane & using transparency it will dynamically batch and set it to terrain level.

But this will have it's own problems on curves, footsteps will hang in mid-air or sink into the ground if not at the perfect angle. (if you want to make the rest of it transparent and just have say a foot print). The better option in this case, imo, is to make a model with a foot print, or use models (of say dirt clods when trampling through mud).. you could have a few models for mud/snow/etc that randomly pop out per step. They could even collide with the terrain, then maybe delete their scripts and never move again when settled (else this will definitely be a performance problem). This would use dynamic batching, see: http://docs.unity3d.com/Documentation/$$anonymous$$anual/DrawCallBatching.html

It still has come CPU overhead, how much I dunno.

You could also limit the amount spread. For example stepping in paint, you can drag it, but paint is finite...you may want to limit it to X amount before it 'dries'.

If you can post back when you discover your solution it would be good knowledge I'd like to know.

avatar image AlucardJay · Jun 18, 2013 at 01:43 AM 0
Share

Where is this 'Unity Footstep script' ?

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

17 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Refer from Shader to C# code? 1 Answer

Unity doesn't scale Blit-to-screen render on X-axis? 0 Answers

Albedo tinting reflections even when metallic set to 0 1 Answer

Instantiated light not working properly 0 Answers

Text Appearance Glitch in Unity UI 5.3 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges