Blueprints 102 - For Loops

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
right hello and welcome back to another video so today we're going to be carrying on with our blueprint series um carrying on from where we left off last time so if you remember we made a blueprint um put a light inside it and then we used some parameters to be able to edit that that light directly in the editor on the instance of the blueprint which is really powerful for building up tools um being able to sort of edit things live so today we're going to be continuing with that but we're going to be spawning some meshes inside the blueprint dynamically taking that little bit further and we're going to get into some loops and some sort of programming so um right let's get started so new blueprint um again as i said last time most of the time we're just dealing with active blueprints and that's what we're going to be doing here um and i'm going to call it mesh spawner um because that's what it's going to do so i'm just going to drag that into the world and then open up the blueprint editor so we're still going to be working with constructionscript uh we're still doing things on creation uh we're still using this to make things so it's only a one-time construction script run and we'll get onto event graphs eventually so we could go in here and add a static mesh and then set this i'm going to be using the chair from the starter content um just as a mesh um and this would work we'd add our mesh to our scene but um this isn't very dynamic it doesn't give us any uh flexibility to do anything else with it so rather than adding our static metal components i'm just gonna delete that and in the construction script i'm going to do a node here called add static mesh component and that's going to do the exact same thing it's going to take our blueprint and run construction script add the static mesh component and rather than add component here it's going to add it on run time so here static mesh what do we want to add well it's sm care and if i compile that nothing happens up here but if we look in the viewport we've got our care so we are dynamically adding to our blueprint via the construction script um during yeah during sort of like editor time and this is pretty cool this allows us to do this uh and this because we're adding it dynamically there's a few things we can do uh to push this further um if i just look in world there it is so one thing we might want to do is set the mesh so this add static mesh component we've got this thing here called return value so this is a reference to that object so if we added the static mesh this way the way we got references to that last time we just dragged a copy in and if you look this is a static mesh component object reference this is also a static mesh component object reference so we can refer to things in the blueprint or the components in the blueprint directly if they're there and if we're creating them dynamically we get this return pin and so what i'm going to do is pull off that and i'm just going to do a set mesh command set static mesh here and this is going to let us override what that mesh is so we can set it here we can set the chair we don't have to if we leave that as a default as nothing it's just going to be a mesh with no or a mesh component with no mesh in it and then we're now going to set the mesh there if we do that as i said there and compile that that's going to now set that chair to be back where it was i don't need this so this is really powerful now we're two separate components we're adding the mesh and then we're also setting the mesh but this can be something that we can promote to a variable so if i set this and i just call this static f uh i can now make this variable instance editable if i just quickly compile that we're adding a mesh setting what the static mesh is via this variable still this chair oh that doesn't appear to have worked why is that not worked that should give me a chair it does if i make this instance editable oh excuse me i don't know what happened there maybe got a little bit confused with the compilation but that should definitely work um and now if i go back to my viewport if i take my chair i can set whatever static mesh i want in here and it's just going to set that oops yeah um on our mesh in our blueprint now this is basically a static mesh actor um it's just being able to set a static mesh so it's not that useful um but we can take it a bit further and what we're going to do rather than just spawning a single static mesh uh we're going to introduce this concept of a for loop so i bring this over and create a little space in here uh right right click for loop and it's not a for each loop we'll get onto those later um but a for loop and what this will do uh it'll run our code as many times as we tell it to and so we're going to plug our execution pin in first and then we've got this thing loop body so this is our loop what it's going to do how many times are we going to run this through and then it's just going to keep running once then twice then three times or as many times as we tell it um now the way for loops count uh they don't start at one and count up they start at zero this is a very common thing in programming and we'll see why in a minute um but we want to set how many times this thing is going to go so the first index is zero and then the last index i'm going to put this in just as four for now um and so i'm going to get five chairs because zero two zero one two three four that's five chairs so you start counting at zero and then the last index is the number minus one um so i compile that and actually look at my viewport uh it doesn't look like there's five gears because they're all exactly on top of each other um well it is doing five chairs i can tell you that that is true uh and if i go in and actually select the blueprint not going to appear as uh components here either um so you have to take my word for it there are five chairs there well let's do something to them to make them visible so rather than having them all at zero zero zero all at local zero in this blueprint i'm going to add a little bit to my um to my transform so when i create my static mesh component there's an option here for transform if i just split this so any kind of time you see a well most data types you can right click you can split them out into their components so transform is made of a location a rotation and a scale and i'm also going to split out my location as well because i'm just going to move my chairs across horizontally and so i'm going to move them in in this case the y-axis now if i put a a movement in here let's say of 50 and compile this my chairs have moved but all five of them have moved but that's not really what i want what i want is them to move sequentially and each one to move a little bit further than the one before and luckily we have this thing here called the index so we saw here first index last index this is a number that tells you how many loops you've done which loop are we on um so if i take this value and i multiply it just using multiply here in by float this is an integer you can't have half a loop and we want a floating point value and 50 looked a bit small so maybe let's do 150 and i'll plug that into y so what's gonna happen first loop we go through we're gonna have zero multiplied by 150 well that's zero next loop we go through now one 150 next one two is going to be 300 450 600 and each one of our chairs is now going to get sequentially further and further away so the number of players we have in this case five are being offset and this is where we count from zero so you could start by counting from one and do one to five and it will compile it will cope with this but now if we look um the origin there is no chair at the origin so generally we want to start our loops from zero so that we get something happening on the zeroth loop at the origin so any offsets that we're doing don't apply until we get to that first chair which is why we start with zero and go up to four just a quick look in viewport there it is starts here moves across uh pretty cool pretty powerful so a couple more things we want to do uh just sort of add some more functionality more uh variation to this um or more controls to this i should say so if we go back into our blueprint this value here i'm going to promote promote that and i'm going to call it my offset y and make that editable so that i can adjust that and then also here this last index well i'm going to promote that and i'm going to call that i could sort this out i'm going to call this one num methods and i make this instant syllable instance editable as well so now we'll be able to go into our our blueprint in the world and uh adjust all of these values and we can dynamically spawn a number of meshes at different offsets in the y-axis which is pretty powerful now you might notice there's a bit of a mistake here it works functionality does exactly what we want it to do but there's a small issue in that the number of meshes is actually wrong for the number of measures so here we've got um it's what called an off by one error very common in programming whenever we're dealing with things that start at zero we start counting with numbers physically at one but the programming way of doing it starting to count at zero so the number of measures we've got here isn't different from the number of measures we're actually seeing now maybe that doesn't matter this number's never going to be exposed to the pro to the player or whatever it is you're doing but it's also a very simple fix as well so what we're going to do is take our number of meshes and then subtract one before we plug it into last index and now if i say i want five cares five chairs is going to go from zero to four and so that now will be correct if we come back to world here a number of methods four well i can see that they're before and now we've got the correct thing happening here pretty cool so let's take this a little bit further so uh this initial setup uh is good i like this um but let's say i wanted to do um something to the later one so when the mesh is spawned i get this reference and then i can set the the mesh there this is all fine but let's say something in game play happens and all of our messages change we want to set a new mesh or we want to i don't know delete them scale them anything like that well we haven't kept a reference in memory we've used the reference when it was first spawned um but as soon as the next loop comes along that's going to have disappeared because the reference wasn't stored so we're going to introduce a new concept which is going to be an array so if i just take my return value here and i promote it from active variable this is going to be set to be my let's just say uh meshes not do it that way let's just do it this way so now this is setting that mesh but then again next time we go through the loop this was connected at least um we're going to overwrite that mesh we need some way of storing multiple references within the same variable and we can do that so because i've promoted i've got the right variable type but now i can delete this so that there's no reference to that variable anywhere and i can change that variable type to be an array and so you've got your variable type so this is actually what the the variable is so this is the the data type and at the end we've got here um a single instance or single variable an array and then a set and finally a map or dictionary so we won't be dealing with sets or dictionaries uh we'll be just dealing with an array uh if we compile this you see how here down in our default values meshes and we can add lots of instances of the same data type to this array so we're going to create an array of meshes and i'm going to call it mesh array make it nice and clear so i know the variable type was correct because i did it through promotion if i'd promoted this and then tried to change the variable type we're going to get this error here saying are you sure you want to do this because it might break things in the future or it might break things that you've already made in this case i know it's fine so i can click change and it's just going to search through all of our blueprints um which in this instance is very few um and just pick up if there are any errors much easier though to just make sure that when you're creating this and when you're changing that variable type make sure you don't have any references to it anywhere and then you can make that change without it having to uh to complain at you so how do we use this array well in this case we're going to go in and we're going to take our mesh array we're going to add we're going to add the output of our of our add static mesh components and we're going to add it to this thing right here that i've called mesh array this link needs to go through there this is fine so now if i compile this save let's have a look in the world i've not exposed that parameter um we could do that just temporarily we don't need access to this but if we just expose it just to see if i open this now well it's picked up a bunch of errors if i move this it's going to go through it keeps adding new meshes to this array but we can see we're getting those meshes added in it's got a lot of errors in there these last ones node and static mesh so these ones are to be deleted well that's fine um if i just bring this in once i've still got loads of errors why aren't you doing this to me here we are but you can see it's adding lots of references to this mesh um if i turn off instance editability it's now not going to keep adding those things so we're only going to get the references to the meshes that we've uh we've actually spawned through and we can test that so now i've got my um my mesh being populated so i've gone through i've made my four chairs i've got this data and what i'm going to do uh just on begin play um i'm just going to put in a quick delay let it load fully and i'm going to use that for each loop so this was the other type of for loop and rather than happening a number of times it's going to happen once for everything in the array so in this case if i load in a reference to the mesh array and plug that into my for each loop this is going to have four chairs in it or five cares whatever i've said it to be uh and i'm just going to go through and in this case i'm just going to print let's do it this way print print string and it should just convert that name yeah so it's just going to print the name of those four meshes or five meshes for me when i quit the game so quick to game begin play uh wait a second just to load in and then it's going to run through those five meshes four meshes and we'll see if this works so i'm bringing my mesh spawner have a copy of this finally turn it around so i can see the chairs but i am now i've got four meshes in there if i click play one second later there we are i get my reference to those four chairs that flashing's a bit annoying let's get rid of you so for each loop will run through everything in the array and the the array is populated during the construction script and if i make this longer i have eight measures obviously dynamically that array is going to get longer my loop is now gonna loop more times and i'm gonna get references to all eight chairs um which is really cool really powerful so when you're doing lots of spawning uh or using kind of like a generation script to create lots of a thing you want to keep references to those later on that you can refer back to best way to do that uh isn't an array or often the best way to do that is in an array and then we can get access to those things so one last little thing we're going to do today get rid of get rid of this that was just a quick test uh maybe not get rid of it maybe just do this and comment it out and move it up here remember this is an infinite plane of code and something like that and we can come back and always hook it back up later it's not doing anything if it's not connected so there's no overheads to this um i'm going to create a little loop now i'm going to delay for a second now we're going to just use this delay loop as a proxy for gameplay code um obviously when we're building a proper game we're going to have other kind of interactions and things happening but a nice little loop will work for us um as an example and then i'm going to get a value from that array so mercury i want to just do the get get a copy and so i can access any individual entrance or entrance an entry that's the word um from my um from my array file would get so before we did a loop for each loop and this time i'm not going to do that i'm just going to get a random mesh from inside my array and so i need to know how long that array is well i do know how long of the array is because i've made it myself here via the number of meshes but i can also dynamically use a length command so the length of the array is how many items are in it and in this case uh like i say it's going to be 5 or whatever my default was for and i want to get one at random so i'm going to do a random integer in range now this would work except for one thing we've got another off by one error so the length of the array is how many actual items there are well that counts at one as a one item starts counting at one the random integer here the the um the index of the array that starts counting at zero so we need to have another minus one in here uh increment integer minus one so now whenever we call this command well yeah this node gets calculated it's going to go through find the number of metals in the array in this case it would be four four minus one is three and it's going to create a random number between 0 and 3 and that's going to give me my my random mesh and what i'm going to do is i'm going to do a set um scalar parameter value on materials now let's do vector and we're going to randomly assign a color to the seats of our chairs now if i um have my reference to my mesh here this this node here is set vector parameter value or material so it's going to read that mesh find the materials and then find a vector parameter and if i actually open up a copy of the chair material let's go this way i know that we have this parameter here called color seats um spell the american way but that's fine we can copy that so the parameter name that i want is color seats and the parameter value i'm going to do a random and i'm going to do a random unit vector this is going to be a random direction or a random color and it's going to set on one of my random chairs now this happens after a second delay then i want it to loop and the way we did that before was to go in and sort of drag that pin around and that works that's fine nothing wrong with that as a sort of loop um and let's just test it let's try that as for now and see where that that works um here we are so every second we get another random color on one of our chair chair seats pretty cool pretty cool so um either using for each loop to create everything in to access everything in an array or just using here where i'm using a get random value and obviously if you've stored something very specific in index 2 and you know that that's the thing you want to access you can just get that directly as well but um but one last thing i wanted to do now this this loop works we've just shown that but what happens if we've written loads and loads of code we don't really want to have to like drag this back we want to jump around directly and so we're going to introduce one new concept for today and that's going to be what's called a custom event now we've used begin play we just begin play we talked about begin um sorry event tick so any of these things are events so these are ones that are built into the engine and can just be called via code via the engine but we can also build our own custom events and this one's i've just named it loop color swap and it's going to go around and it's going to happen before the delay and so beginplay is going to happen once on startup and then we can also call this event from anywhere else in our blueprint or in fact from other blueprints and so you can build up kind of events and logic across multiple blueprints and the way we do that is now i've created that event i can just access it via the normal way as a uh as a node and so this is the calling of this event and if i just click play i can actually just watch it in the debug and so every second it hits here and it loops back to there so it's the exact same as we had with the two reboot nodes um but now we're not tied to having a small loop we can go off and put as much code as we like in there and we can call functions between different things and if we look in world we'll see that's still working and we're still getting our chairs randomly changing color every every second cool so a few key takeaways from today um firstly we can dynamically add things to our blueprints um at one time uh either construction script or through gameplay um if we do we probably want to keep a reference to it and so if it's just a single thing fine we just create a variable and set that but if we're adding multiples we probably want to use an array and then once we are using arrays we can either access everything in the array via before each loop or we can just access an individual item in this case at random using the random integer based on the length of the array pretty cool stuff right that feels like enough for one lesson as always if you have any questions or comments or anything let me know um big thanks to everyone supporting the channel uh especially my patrons um and i'll see you all next time for some more blueprints
Info
Channel: tharlevfx
Views: 946
Rating: 5 out of 5
Keywords: ue4, vfx, materials, unreal, tutorials
Id: Vv1cPX5RuCk
Channel Id: undefined
Length: 24min 16sec (1456 seconds)
Published: Tue Sep 29 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.