Unity - Plexus Effect || Part 1 (Particle/VFX & Programming Tutorial)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone welcome back to another very exciting unity VFX particle programming tutorial and today we're finally going to be working on this plexus effect that you see here right now in the background for this we're gonna be creating a new component a custom particle system component that we're gonna program ourselves called particle plexus and this is based off the After Effects plug-in by the same name known as plexus where what basically happens is you have these individual particles and the particle looks around itself checks to see if there's any other particles nearby and within some distance that we specify such as max distance right here if there's a particle it makes a connection to it so we've got a bunch of parameters we'll be able to play with once we're done the entire tutorial you know for performance we've got max connections maximum of line renderer as possible the width wherever you want to get it from either the template you pass in or the particle itself you know the color from the particle or the template you can look between them and also this wacky delay effect which almost makes it look like it's lagging but obviously as you can see it's otherwise just fine so that's for the full tutorial but today we're actually going to keep it a little bit simple and instead just work on this right so this is a simplified component we're going to work on and in the next episode we'll add on those extra parameters so you can see we've got Max's since max connection line renders and then the template so without any delay let's get started so obviously the first thing I need to do is create a new C sharp component I'll call it particle plexus 3 you can just call it particle plexus because you know I've got other copies in here so I do need to add in the extra thing open it up in visual studio so at this point I just want to remind you guys that if you haven't watched the previous introduction of particle programming tutorials you should do that because we're basically just building off of whatever we made there and a lot of the concepts are similar so I won't go into them in as much detail so with the particle plexus 3 script component just created I'm going to quickly take this out because I know I won't be needing this name space but I will be needing this or a list when we get to that later we're going to add a require component to this type of particle system so we know that there's a particle system component attached to whatever object this script is also attached to because we will be working with that and we're gonna be doing everything inside of late update and start I obviously all so want to start creating a public float for the max distance which equals one in this case I'll get the other two in a bit which is max connections and line renderers then I'll just quick please skip ahead into particle system particle system which is the reference to the particle system that on this game object as well as saving I'm using new because of the old I don't want to inflict with the old unity for point X stuff particle system dot particles this is an array that contains all the particles in their system that I'm gonna save outside here and I'll also save the main module although it's not going to be a huge performance boost right here just for the heck of it okay so in start I need to actually get the component which I can do so particle system equals get component particle system and also the main module which which I can get off that system this particle system dot main now that I have that I can move on into the loop here I'll do int max particles equals particle system main module max particles so we need to make sure that if particles array has not been initialized at all then we need to first set it to the max value the max particle count size particles equals new array of size max particles of that length and then we also need to make sure that if the array or if the max particles value ever changes to be greater than the array size and we need to adjust the array length as well so particles are length becomes less than max particles then again reallocate the array so now we can move on to our main loop so now what we need to do is get all the particles in the system and then throw it in this array right here so we can do that by doing particle system get particles and I'll get as many particles as are in the system up to whatever the size the array is on this case because the array size is greater than the number of particles we can get it shouldn't be a problem filling it all up then int particle count equals particle system dot particle count so now we go to the main loop we can do an int for and I equals 0 I is less than particle count as plus and that'll just make sure that we go through every single particle in the system and then we need to duplicate this array create a second nested array using J basically what's gonna happen is we're gonna compare every single particle its position to every other particles position and see that if it's less than max distance then we'll create a connection between the two so for this we don't actually need to start at 0 we can start at I plus 1 because we know that for the previous particles checked if it found a particle position or another particle that was close to it it's already made a connection to that particle and we don't need to double back and check the connection again it also saves up on obviously performance because we're not creating 2 lines between the two of them and also not checking every single particle against every single particle we have a little bit of slack here you can use better algorithms for this you can use partitioning and whatnot but because this is what I'm familiar with this is what I'm gonna be covering in the tutorial so how do we do this well first we need to create a vector3 for the first particles position I'll just call it p1 position for particles I got position and then get the position of the second particle as well and now I need to get the distance between the two so what I can do is float distance equals vector 3 dot distance between the first particle and the second particle now this is fine it'll do what we want but the problem is that distance is actually a pretty expensive function call because of what it does inside so what it does is that it basically gets the difference between these two and from that vector it calculates the magnitude that is the length of the difference vector and then that gets the distance between the two positions so that's fine it is what we want but it's expensive because it has a square root call in there so we can just directly call magnitude and subtract these two so again this is equivalent to distance but we can make that better because instead of new magnitude which does the square root call we can do the square magnitude which doesn't call square root and then call this distance squared and then instead of comparing against max distance on its own which is has a default value of 1 which is just yet 1 meter we can create a new variable right here float max distance squared and it's outside of the loop so it's not a big deal to add that extra multiplication in multiplied by itself and we can just compared to here so if we do if distance squared is less than or equal to max distance squared we know that this second particle that we're comparing the first particle is within this particles range so we would create a connection inside here so at this point we need to go back to the line renderer stuff so let's go up here and create a new public line renderer variable which is the line renderer template I'm gonna using this word line renderer over and over again so it's possible I might start pronouncing it weird and well just weird as time goes by so list and we want to keep track of all the line renders that we create so we can reuse them we'll call it line there is equals new you're just instantiating here and I think that's good to go so for this we also need to create another variable out here which keeps track of which line renderer were working with so we can reuse them properly now because this is a list I want to keep track of the count myself rather than constantly calling the count on the line renderer variable so what I can just do is quickly create an int line render field which is just line renders count and I can modify that value after if I add any more or whatever else so what I can do is if the LR index is equal to the line renderer account we know that the line Runner account is the number of line renderers not the index and the indexes and index which is a zero index that starts at zero we know that if this is zero and the count is zero then we have one more line that we need to have more than whatever this is right so that's just for the first one if for example this was 27 and the index was 27 we know it's the 28th line renderer because it's zero index so we know that if they're equal to each other then I do need to treat any line under so I can just do as line renderer LR equals Stan she ate based off our template okay we use the transform and we want it to be parented to this transform and then we add Falls for world space now we can actually cache the transform up here colors thanks form and then just keep a reference to that somewhere like this school transform and then just use that one so that way we're not accessing the property of this game object for the transform and then we can just add it to the line renders that we have add this one so now we that we know that that line renderer exists we can just go ahead and set the values for the position for this line renderer which is LR index dot set position zero to the first particle position and then the second one to the second particle position make sure to add one here so it's the first and second position so this line would be like from here to here or whatever else wherever the particles would be and that's close to finishing off our template well I just need to quickly implement the line renderer index as well as the line renderer count because we've added a new one right so I can just do that now outside of this for loop I can just quickly trade another one I equals L our index and what this is basically gonna be doing is making sure that any unused line renders are disabled so they're still if the particle you know count changes then they're not going to be rendered and they're just gonna be disabled and we can know that based on the LR index because the LR index is the number of line runners we've actually use and if that number of use line renders is less than the actual count of line renders which I can just use this for then I can disable all the extra line renders from there on so I can just do line renders i dot enabled equals false okay so now that we've also disabled them we need to remember to also enable the ones that we want to use so we'll go here set this to enable the equals true and I realize that this should not be I there should be J because it's the second particle position so one thing I want to mention now at this point is that getting an element from a list is actually pretty expensive so what we can do is just save the element beforehand so here I'll just copy and paste this above then I won't need to do that and then I can do LR equals current index and then just use LR for the rest of the stuff so like this okay and I think that's all we need to do to actually test this out okay so to be able to test this I need to first create a line renderer template so I can press control-shift and to create a new game object or you know just do it from here create empty make sure it's completely reset and then add the line rendering component I'm gonna leave everything to its default value except the material which you can use the default material I'm gonna use a material for my ultimate VFX particle pack will leave the link in the description and I'm gonna set the width to 0.025 I'm gonna keep world space and I'll show you why that may or may not be a problem shortly so I need to just rename this quick data line render template or something and then drop this into my list of prefabs and then delete this object cuz I don't need it there and then make sure also that the positions the number of positions are set to two because obviously here we don't modify it so with that being said I can just pass this in and hit play and it should work so you can see that it's working but the positions aren't quite right and that's because I set it to world space enabled right that was the default value and it's also instantiating a ridiculous amount of line renders because there's no limitation set up right now which will do shortly let's disable the world space use world space on the template and see what happens and the positions should be corrected now right so the reason that happens is because right now I'm using the simulation space set to local which is a mismatch between what the line renderer is being rendered in so the positions that are being passed to that aren't in tune so let's play this again with world space simulation this time and we'll space line render and you can see they're in sync so we can actually make sure all of that works in the script itself so to do that right about let's say here I'm gonna create a switch statement and check the particle systems main module simulation space so particle system main module simulation space then create a case or local okay click that create a case for custom and create case for a world and then finally create actually a default case in which case we should throw a new exceptions of system not supported exception will do string format supported simulation space pass the parameter period their system raishin name type of particle system simulation space system million module relation space bunny tagged maybe one more of this and I think that's okay so I'll just drop this down here so it's neat okay so for this transform we can actually take this out because we won't be using it here but rather it needs to be here so the transform in the case of local is the same transform of this in the case of custom it's actually the custom simulation transform so we can use custom simulation space which is a transform and in the event that it's world space well then we can just pass in this again right but we do need to modify the templates world space variable so what we can do is just get the template set use world space to false and true take this one and that should allow us to switch back and forth freely between the simulation spaces up I missed something so this is fine you'll be able to switch between the simulation spaces as long as you don't do it in play mode because if you do it in play mode it's only going to get some of the newer instantiated line renders and it's gonna miss the ones that have already been instantiated with the settings preset beforehand on the template so for example if I move this up now it's fine but let's say I set it to world space it's not gonna work anymore unless it instantiate s'more particles and gets all messy and weird you can see it's instantiating up there or it's moved the system's up there so what we can do is then it's up to you if you want to do this because it does have a small performance penalty you can just save this simulation space first of all so let's create a new here and call it simulation space and we can instead set it for every single line renderer every time we you know render it out or cycle through it so simulation space equals so that's the current simulation space for the particle system we can just use this now and instead of setting it here okay we can just read out this we can just do it right here somewhere so we can do a line renderer use world space equals simulation space equals world yes/no if true then set this to true or false another way this is fine because it's used up here so that's fine we could also do something similar here I doubt unity again is gonna be adding more types here so we could have just used something similar up here but for now I'll just leave it as is and let you guys figure out if it's worth changing so if I go here now I should be able to switch it while it's playing without any issue so again if you if you think that's okay it's not gonna be a too big of a deal for you and you want that then go ahead and implement the rest of that code that I just did switch back and forth between world space right it's all good okay so with that out of the way there's only a few small things left to do namely the limiters right so right now it's just getting a bunch of it's just instantiate align render after line render and there's no way to stop that so we need to create a new public in max connections equals let's say a default value of 5 and we'll also add a max number of line renderers and we set that to maybe a value of 100 so what we can do now is first of all only execute the majority of this code if both of these values are over zero because if any one of these values is zero then we know we're not actually gonna be rendering anything so we can just save up and say hey listen if you know both of those values are zero don't execute all this expensive code so we'll do that around let's just find a good spot I can be put okay so we'll keep this we don't need to get the particles in this case we will need the line renderer index for this code here which won't be inside so we'll just move the line renderer index here and we'll do it here so if max connections is greater than zero and max line writers is greater than zero as well then and only then should you be doing all of this expensive stuff here I don't think I missed anything do I need all of this here I guess so we'll leave that out there so we have that first of all set up we also need to monitor the number of connections that we make so we can do that here so we can do int connections equals zero and after that we need to check right here and add connections plus plus because we've made another connection and this will always be reset to zero on every loop board the single particle that's being compared to the other particles and then that way we know how many connections for only that particle have been made versus the entire number of line renders so if connections equals the max connection value [Music] or if the LR index is equal to the max line renders then we break out of this loop we also need to put another check here right after we do right at the beginning the thing for the max number of line renders and we'll break out of the second loop as well if this has been reached so I think that's good let's help I missed that one okay so I should have put this outside as well somewhere here probably and that's just useful for that okay so now we have the limiters in and we can hit play and it should be much more performant because it's not gonna be having a ridiculous number of line runners you see that's much better right now what happens if you want to decrease the maximum number of line renders well the ones that you instantiated are still there which maybe not an issue for you maybe it's fine but in my case I'm actually going to destroy them again this is optional you can figure out if you think it's worth it to get rid of all those extra game objects that are in the scene or if it's just a waste of time and you'd rather just have the performance so in this case I'm gonna be implementing if line of renderers dot count actually again this can just be underneath this part right here if line render out it's greater than the max line there's fans or in I equals zero I is less than line renders under count I plus plus destroy the game object with all those line renders and then we need to remove them from our list as well so line renders dot remove range from max line renderer to line renderer hate saying that word so many times count this case would just be this basically starting at this index to remove these many the difference between the two basically right and then what I can do is now that we removed the difference between these two I can also reassign the line renderer account to be the difference or we could just save the difference so I can't we move counts equals difference here [Music] count and count that's good before so let's set play and quickly check that out and that'll conclude the tutorial if everything works so there it is not a problem let's decrease this oh I ran into a problem so let's see what's happened ah this should be max line renders right here so let's hit play again okay looking good so far we can set this even to a negative value and then of course it creates a problem but once we have maybe liked let's put like before here see what happens one two three four right so this works you can just limit it to make sure it's not less than zero but otherwise you can see everything seems to be working and in the next part of this tutorial we'll start implementing this final stuff right here like the width from particle color and whatnot so that way you don't have to use the color from the template which you can do as well so for example if you wanted the template to be maybe going from yellow ish to red you could just set that up here and if you want it to be thicker you can also make this point five point zero five so it'll be double the size and you know that's what happens it's right so now what we're gonna do is basically be changing those in the next tutorial gonna add parameters to change those from script rather than having to specify it in the in the template so we can also make this maybe a thousand so they're not constantly jumping around let's see what happens set the max connections to one to test that out and I can see they're only making one connection for a particle and I think that's pretty good alright so thanks for watching guys please subscribe leave a comment and a like if you want to let me know what else you'd like to see if you need clarification you know just let me know in the comments ask away I'll be happy to answer thanks for watching and I'll see you guys next time bye
Info
Channel: Mirza
Views: 60,711
Rating: undefined out of 5
Keywords: unity, five, unity 5, effects, tutorial, particles, vfx, particle, shuriken, free, download, game engine, ultimate, particle pack, particle system, particle systems, mirza, beig, particle effects, unity 5 particle effects, unity 5 particle tutorial, 5.5, lightning, 2016, unity vfx, beginner, 2017, programming, custom, component, behaviour, optimized, optimization, after effects, plexus
Id: ruNPkuYT1Ck
Channel Id: undefined
Length: 24min 4sec (1444 seconds)
Published: Tue Jan 24 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.