Beginning Unreal: Spray painting walls

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right my friends let's go ahead and get started tonight we're going to implement sprays to implement sprays we're going to build a new component we're going to put that on the player character that we've been working with um and we're gonna do some line tracing because we need to be able to trace from our character to a wall to determine if we can spray to it so line tracing is a pretty fundamental concept that you'll see all over the place um and in fact like that's how you implement like a hitscan weapon so you know if you want to go and implement your own shooter uh this will be relevant the other big topic we're going to cover today is decals um let me actually pull up like an image so decals are are basically um just materials that project onto another mesh um and so you can use these for like putting blood splatter on wall you can do posters uh basically anything that like kind of dirties up a wall decals are a good choice for that uh and then you can reuse the same mesh and materials underneath it and just put stickers on top of it so to start with let's go ahead and build some some decals and then we'll talk about how to spray them in real time um i am going to be using tonight our emotes as our as our sprays so let me go ahead and import those into the engine real quick i'm gonna start by making an art folder here and let's make a sub folder called sprays and let's go ahead and import our textures and that's all it takes to import textures so these are just png files um they import straight into the engine and now we can start doing stuff with them so the next piece that we're gonna need is an actual material that uh is gonna use our sprays here let me i think yes there is a button i can just create a material from a texture so we're going to call this uh material spray decal and that is going to give us a starting point our material right now just takes the base color from a texture sampler which is mostly what we want actually um i also want the alpha to go into my opacity and i need to set the material domain to defer decal for it to show up as a decal so let's oh why doesn't it compile what's it mad about ah blend uh blend mode has to be translucent that's why all right all decals have to be translucent and unreal it doesn't support opaque oh my goodness i'm clicking all the wrong things here all right so we now have a spray decal uh and i can create a decal actor from that i can put it in the world so you can see this is just kind of like the placeholder image here and in fact um you can see that blue arrow is where it's pointing right now uh the reason it looks stretched and gross is because it's pointing in the wrong direction if i turn it 90 degrees so it's facing me you see we get kind of like this basic template material i can just drop mine in right here and uh right now it's upside down which we don't like but we can fix that so if i looks like if i go zero on the x direction it's upside down but we can bring it in there um something that is interesting that i actually didn't know about unreal until i was doing a little prep for this let me see if i can reproduce it uh out of the box if you use the defaults for decals with static lighting uh they don't appear correctly in dark places uh in our version of the engine this is not true we've made some modifications but i didn't realize this was a behavior in bass unreal but i'll show you what i'm talking about here you see how right now uh let's change the rotation on this guy so that he's facing the direction he should be facing what you're going to see here is like my decal is basically invisible you can sort of very faintly see the outline on the wall that might not even be coming through at all in the stream um but it's not what we want and it's because for whatever reason they don't work with static lighting if i put a movable light in you'll see it it shows up but with static lighting by default it does not so the way we fix that on the decal is instead of doing a uh a decal blend mode of translucent we use uh debuffer translucent and we just need color we we don't need the other parameters so i'm going to use uh debuffer translucent color and i'm guessing this has a small perf cost let's see here so our stats window is going to tell us how many instructions it takes it's actually the same number of instructions so i haven't dug into the engine code to figure out why you need to do this but uh for some reason the default settings for decals don't work with static lighting and probably you want them to work with static lighting so i changed it we recompile shaders and now our problem is fixed great uh i'm not gonna do a missive we're gonna do something very simple tonight spy okay so we've got our decal uh i've decided that i'm lazy and i don't want to have to rotate every decal i want it to look good when my rotation is uh just generally kind of facing the correct direction so you know i think this level of rotation is okay but you can see that our texture is rolled 90 degrees so let's just fix that in the material real quick this is a material editor the material editor is like a special blueprint graph just for materials and you have all these different parameters based on your shading model and your blend mode and everything else um but we're going to make a very simple material here so i just want to rotate in my material uh and i think i need is a texture rotator yes i think this is what i need here so i'm going to rotate our uvs we're going to wire this up to just texture coordinates and then i believe zero to one so maybe i need like .25 if i want to rotate 90 degrees let's try this and see so i click the apply button it'll apply in the world after recompiling my shader so my shaders are recompiling let's see if this is right no we rotated the wrong direction let's do 0.75 i bet that fixes it we'll apply we'll see again here new question if you change the depth of the decal the weird edge effect will be as wide as the depth yes that's correct chick all right so now our decal is rotated correctly i do think i do think our our big red guy here is a little bit big um we'll we'll probably change that here let's let's make him 32 by 32 by 32 ah it's too small let's do 64 by 64 by 64. all right so now we have a new he's on the wall and uh we can plug in whatever texture we want to here if we want to make him a new that's eating a potato instead like it's that simple and in fact i'm gonna make this texture a uh parameter we're gonna use that later let's call this spray texture so we'll use that later so that we can we can change between our uh texture selection at runtime all right so we can now place decals in the world that's all good and well but that's not what we're here to do we are here to make it so that we can spray decals onto the wall uh so let's talk about how we're gonna do that well you'll recall last time we talked about how you can add behaviors to our character by adding components so let's go ahead and create a new component i'm going to call it our spray component and we'll call that bp spray component we'll get that all set up here we're going to open that we don't even need to do that yet let's just put it right on our character even though it doesn't do anything yet so we have our interactor component from last time we're not going to mess with that today but basically we're going to do the same thing we did last time and just put a spray component on it and uh when we get a little further along we're gonna route input up to the spray component but all of the logic to put sprays on the wall are gonna flow through this new component that we're creating and actually i've decided that i don't want to deal with spaghetti tonight so the other thing i'm going to do before we really get going is i'm going to turn on an additional plug-in everything that we are going to do tonight you can do without this plug-in but this plug-in makes it a little bit nicer when you are laying out your blueprints uh it's not free i think it costs like 12 dollars maybe it's called electronic nodes it's going to make me restart the editor let's save everything we'll do that let me let me kind of show you what what it looks like and why i like it uh they've got an image here so the default style for the blueprint is up here in the top left as you can see um and that's where we get all the spaghetti uh this this plugin automatically lays out your blueprints in a fairly neat fashion electronic nudes no that's not correct all right so i think we've now got that installed i probably have to go and turn it on in my editor preferences let's see yes electronic nodes plug-in um i have all sorts of settings that we can manipulate let's let's put our settings over here and let me fire up a blueprint and i can show you what the different settings kind of look like let's see i think our our garage door had some logic let's look at our garage door real quick [Music] yeah so look how clean that is now compared to if we just have uh it on default i'll show you what default looks like we can just tab between these so you can see with default you have all the noodles we can do manhattan style it automatically lays everything out we can do subway style it also lays things out i think i want to do manhattan and i also want the ribbon on uh you don't need to worry about all these settings but you can play with them make everything look nice and clean which is what i want all right so let's start writing our spray component line traces can be kind of complex and i want to also use this as an opportunity to show you guys how to do debug visualizations so the very first thing we're going to do is we're going to create a variable we're going to call it b debug sprays it's just going to be a boolean we are going to make it editable we are going to make it public and i'm going to throw it in this phrase category and every tick if this is set we're going to print a bunch of debug information and draw a bunch of debug information and we'll walk through this as we go but basically we are going to build like some robust debug functionality so that we can see what's going on later and if we get confused we can fix it uh and i am going to call our function draw debug information we're going to implement this function a little bit later oops don't worry about it just yet come back to our event graph here if our debug mode is turned on we're going to go ahead and call draw debug information so the very first thing that we're going to need to do is ask a question when we want to do a spray and that is can i currently spray that is going to return a boolean which we're going to call b can spray and again we're going to implement this function a little bit later the other function that i think we're going to need is request spray which is what our player character is going to call when we press the spray input and the very first thing that he's going to do is he's going to check can spray and if we can spray we're gonna go and do some stuff that we're gonna implement later uh the other piece that i think we're gonna need is figuring out whether or not we are currently up against a wall because if i'm out here in the middle of the level i should not be able to spray any surface i want to make our player character be relatively close and the way we are going to get that done is using a line trace so a line trace can be fairly complex i'll show you what the function looks like i think we want line trace by channel here but basically we're going to give it a start point an endpoint a channel which in our case is just going to be visibility we could do other channels if we want but we don't need to worry about that here we can do a complex or simple trace a simple trace is going to be faster so generally we prefer those it has some debug drawing options um we're actually not going to use it here we're going to build it ourselves uh and we have this ignore self boolean and this is useful because uh it says hey i should ignore the component or the actor that i'm actually shooting the trace from it returns two values the first value is hey did i hit anything and the second thing is this hit result structure and the hit result structure has a whole bunch of information which we're going to talk more about a little bit later we we don't need to drill too much into this but uh there's a bunch of good stuff here that we can learn about whatever we hit but before we do that we need to figure out what are our start and end locations for our trays so i'm making another function that computes that and we're going to call it get line trace start and end we are going to have that return two vectors because uh we need a point in 3d space for the start and the end so let's call this line trace start and this should be a vector and we need line trace end which is also going to be a vector and you'll recall from our last gameplay programming stream we talked about how vectors are just uh three floats uh x y and z right so this is what a tech artist might do a tech artist could do this this is also uh considered gameplay programming um so you know i designers are also going to interact with this type of stuff basically anyone kind of building gameplay logic is probably going to deal with some of this stuff so what is our start position well we want to start from our character's eyes and thankfully unreal has a function that can tell us that but basically we want to shoot a beam right out of our little mannequin's head and see if we can hit a wall so let's write the logic for that first we are on a component you'll recall and we can get the actor that owns us using this get owner function and from that i believe it's like get actor eyes let's see here eyes get actor eye's viewpoint uh this is going to be our starting location and that's easy right very simple so far the end is a little bit more complicated because our end location we need to start from the eye viewpoint and we need to trace forward by some distance so let's put a configurable parameter on here and let's call this max spray distance and we'll do all of our math based on the max spray distance because that is going to allow us to come in here later and change the tuning without changing all the code i am going to default to let's say 200 centimeters so we'll call it 200 centimeters for now so the next piece we need from our owner is what is the forward location and you can get that by just asking for the forward vector this returns a normalized vector and what normalized means is if you take the distance of the vector it's always going to be one um so it has a length of one uh if you were to to draw a line in the direction the magnitude's going to be one it's just moving across one centimeter in 3d space uh and it turns out we can scale that to our max spray distance by just multiplying it so if we multiply our vector by a float we now have a forward directional vector [Music] that is stretching a length of 200 centimeters and the last piece we need is we need to move it from that starting position so we're just going to add that to our new vector because when you add two vectors it goes from one point to the other and i think that is going to give us a pretty reasonable trace here we will draw it though to make sure [Music] let's do that i'm going to compile and this can actually be pure because it is only reading state we're not writing any state math and blueprint yes exactly we want to spray right new at five kilometers distance that would be too far how do you know the unit is centimeters is that the unit scheme unreal uses yes uh unreal's default unit is centimeters uh all right so let's figure out how we're going to draw that well we have a whole bunch of debug functions here the one that is important for this is called draw debug line and much like our line trace it gives us a start and an end and it draws a line so now that we have a function that computes start and end let's just call it right and we can give the line of color for now i want to make it let's say yellow i'm going to change this later i think i want it to be green if we hit in red if it doesn't you can also specify a duration and a thickness um we're gonna set duration to zero which means it will only show up for the frame where we draw it but that's fine because we're gonna draw our debug information every single frame because we're doing this on tech so let me show you with uh right now i don't have debug information turned on so we're not doing anything but if i come here and if i change our debug sprays boolean to true we should now be drawing a line and we are i'm gonna make the line thicker because i bet that is not coming through on the stream so let's set our thickness to like two for now i will try one first and y'all can tell me if you can see it you should now see a yellow line shooting out of his eyes can you see it how does it look now as i move around that yellow line is going to move with our character all right any questions so far everybody with me what we're doing how we complete computed the line trace start the line trace end and what we've got here the other thing i'm going to do is i want to show you how to draw debug text um let's actually create a little sequence node here just so that i can lay things out a little bit more cleanly i am going to capture line trace start and end in some local variables let's do this let's call this one line trace start we'll call this one line trace end [Music] will trace collide with player model yes since i'm tracing on the visibility channel it will collide with anything that uh is visible you can also there are a bunch of collision channels you can use um so you can say hey i only want to trace on things that collide with weapons or hey i only want to check for a collision with other players you can uh you can do all sorts of traces but visibility is like one of the simplest ones so that's what we're going to be doing tonight all right so let's set our local variables here and then we can just reuse these later and i'm just going to go ahead and kill these lines because we don't need them great we have that getting captured we're going to neatly lay these out here look how clean the electronic nodes are y'all it's so nice i like it a lot all right so then we want to draw our debug line which we're going to put right here and i will use a rewrote reroute node here just to make it a little a little neater and we're going to reuse our start and end here that we just set above [Music] the other thing i'm going to do is i'm going to save frequently because the other night i had an unreal crash and lost about an hour of work and i definitely do not want that while we were on stream it it annoyed me off stream it would be catastrophic on stream all right so we've got our line next thing i want to do is i want to put some text on the screen so the way we're going to do that is with i think it's actually just print string draw debug line and print string are development only functions which means if you try and use these in a shipping game it won't work which is generally what you want because this is just stuff to help us debug this is not something we want to show the players ever it seems like the origin of the line is the head at rest which moves forward when walking running does that mean all the math is only ever based on the model at rest does that cause difficulty when you are designing solutions that have to work with more complex animations so the real answer is your start point can be anywhere in 3d space you want um we're just doing a very simple example here ziko so we don't have to we don't have to worry about you know being exactly at the right position we're just tracing forward uh print text i believe allows you to use a format stream actually i can show you that too so hold on let's do let's do uh spray component debug information or debugging enabled we'll print that to the screen but before we do that let's print out oops i didn't mean to go that far with my reroute node we're going to print out uh formatted information about our line trace so let's create another one of these pull this one down here and then we're going to make another one here and i want to format text or there's i don't want draw text i want format text format text is that right uh okay let's try here format text there it is okay and my format string is going to be line trace and we are going to have it take in you'll see this is my text too small we're gonna have it taken line trace start and we're gonna have it draw an arrow to line trace end and when i press enter here on my format string it's gonna give me two pens i can then take my start and end and it might yeah it's gonna force me to cast this to a string before i do that so i can plug in like that same thing here so we're now formatting text and that will show us our line trace information as the actual xyz values on our screen and then we will print string that again here let me get it all wired up here and again we're going to use a little reroute node to make it a little cleaner uh something like that's probably okay and let's move this back of here perfect and then this result just goes into our string so the other thing that i need to change here is i want the duration to be zero because we're again printing every frame and also i believe this has yeah print to screen and print to log we do not want to print a log and i'll show you why in a minute we only want to print a screen because we're calling this every frame so i think this is going to do what i want uh hopefully my editor's not crashing right now it's doing something i'm going to hit compile and save here so the basic version is text is for like localized strings that are going to show up in real games and it has it's a lot more feature rich than just uh the debug string okay so you see over my editor's hanging what's going on little editor visual studio is doing something it shouldn't be doing anything okay my computer just freaked out it's fine so y'all can see at the uh the top left of our screen we have spray component debugging enabled and we have the line trace information and as i move around my x y and z change now the real way i debug spy if i'm actually doing hard debugging is i set break points and and look around um but for the purposes of just seeing what's going on having tooling like this is super useful because sometimes visually it's much easier to see what's wrong rather than having to try and figure it out while paused at a break point i want to get rid of the lighting needs to be rebuilt warning so i'm gonna build lighting here real quick yes we built ascent a on the very first unreal stream this is our our attempt to pretend to be a level designer and block out ascentae all right we have lighting getting built here it's running it's running come on on a level this small thankfully lighting is not very expensive to rebuild on a bigger level that can be a big operation all right now you can see that text is a little bit easier to see we don't have the red anymore and as we move around the x y and z coordinates of our start and our end vector update and then we draw that line in 3d space which is the yellow visualization that we see now i mentioned that we don't want to have a duration or print a log first let me show you what happens if i put a duration here and this will make it abundantly clear why that's not what i want see how it's flooding the screen and that's because i'm i'm updating it every frame so i don't need to draw it every every frame or i don't need to have a duration rather since i'm drawing it every frame right now these are sticking around for two seconds and just flooding off uh so let's change that back to a duration of zero same thing if i were to print to a log if i look at my my log here if i clear this out and i've got print to log enabled i'm flooding out my log that's not what i want so if it was like a one time event that would be totally fine but since we're doing it every frame we don't we don't need to put that information there does that all make sense let me need in this up a little bit okay so now we have our line trace start and our line trace in right now we are we're just debugging let's actually do our line trace and determine if we can hit something so we're going to use our same get light and trace start and end and we're going to do a line trace call like we talked about before and what did i say i said by channel right yeah let's use my channel tonight okay so again start and um probably we're gonna want a little bit more checking beyond just hey did you hit something um i i wanna i think i actually wanna pass on my hit result so let's do that here and that should be of type hit results so we can pass that on which is going to be useful but before we do that let's check hey did we even hit anything and if the answer to did we even hit anything is no then like we're done we uh we we don't need to return anything we we know that we have failed out i'll put that down here for now if we did hit something we have more work to do let's store this guy in a local variable we'll call him local hit result so if we hit something we're gonna store away our hit results so that we can inspect it uh in a couple places without it getting too confusing and i still don't like the way this is positioned so let's do this instead put a reroute node there ah i recently upped my dpi on my mouse and i'm not used to it okay cool so let's uh let's start looking at this hit result let's uh let's go ahead and split him out i think one of the things that we want to know is whether or not we hit a static mesh if we didn't hit a static mesh i do not want to [Music] treat it as a hit i did not update the command check the math works out the same i moved up to 1600 dpi and i divided my sensitivity by four so it works out the same so i want to try can i cast this to a static mesh component cast to static mesh component we'll see if this works like i think it will and then this guy has a receives decal method if a static mesh does not receive decals what that does is it makes it so you can't put a decal on top of it and this is useful because if you look at our button you can no longer see our button new is eating our button that is not what we want chat we do not want new to eat our button so we can come into our wall switch actor and on his static mesh components we can set receives decals to false at which point you can see the button again new is no longer eating the button say much better much better that's what we want i'm also going to check it for the purposes of casting the spray i'm not going to let you cast the spray if you are right on top of static mesh that does not receive decals similarly if you're not a static mesh i'm not gonna let you spray it i'm just gonna make you uh fail right out here and return false and again we're gonna set up a little reroute node keep this nice and neat if it did succeed then we're going to check our receives decals flag we just talked about if that fails we're going to return nothing just like before you could also do things here like implement a cooldown system have a max number of charges there's like all sorts of good stuff you can do here but like this is a pretty good starting point all right so at this point we've confirmed that we have a hit we've confirmed that the thing that we hit is a static mesh component and we've confirmed that the static mesh component is configured to receive decals which is the default in that case we're going to return yes you can spray and we are going to forward along our hit result so that we can do something with it in the function that is calling can spray so there's no behavior change that's visible yet but if we come to our debug information here now what we can talk about is hey i want to make this line green if we have a valid target and red if we do not so let's write the logic for that [Music] before we draw the debug line let's call can spray and again we can reuse the trace start and end oh wait i don't have to i don't even have to do that we already do that never mind this is even easier than i thought we'll just call can spray i'm gonna bump this up just a hair uh can spray we're gonna do a branch operation if we can spray then we are going to make it green and if we cannot spray we'll make it red and that will give us a pretty good visualization i think of whether or not we're hitting a valid target that satisfies our criteria for being able to spray let's put that there bring this in just a little bit great and we're going to copy all that we're going to do the same thing here on the negative case wire that up reroute it so that it's clean change green to red and we're not doing anything with the hit result yet we're just uh we're just changing the color based on whether or not our line trace hits something okay so you see we're red now and when we walk up to a surface we're green is that coming through okay on the stream y'all can see my commitment to no blueprint spaghetti is admirable thank you gabe i appreciate that all right so green and red it's updating every frame nice and easy now the thing i want to be clear about what we're visualizing right now is not the actual line trace we are casting a separate line trace on the exact same uh the exact same vector um so our line trace that we're casting is exactly identical to what we're visualizing but the thing we're visualizing is not that same trace and the reason that's relevant is because when we do this for real we're not going to be doing it every single frame we're only going to do it in response to player input right now that's correct i can't spray on ground because i am choosing to use the physical location of my pond's head i am not using camera i could use camera and in fact i can show you what that looks like and the reason i didn't want to do that uh if we use the camera it will shoot backwards when i spin around uh in third person but that's easy to do basically instead of using the forward vector here i wonder i don't know what this is going to do actually let's find out let's find out chat we're going to convert our rotator or convert our rotation on the eye viewpoint to a vector then multiply that then add that and i bet right now what we're going to see is the line trace uh goes wherever my camera is pointing which is why you can't see it because it's a straight line down the dimension of my camera you might be able to see there's like a dot um but this is not what we want that would allow us to spray on the ground though i think in in 3p that that's not what i want though instead what we would do is we would um build out actual functionality around moving our character's head around but yeah and as our game gets more advanced maybe we'll make it so you can tilt the head around okay i think i've got it all working again here [Music] yeah you can see the little dot exactly all right so uh let's let's do more debug drawing um like we're going really deep on this but that's just because i want to show you everything you can do here uh the next thing i want to draw is i want to do more stuff when you get a hit uh we're in a draw box draw debug box okay uh the center of that box is going to be the point where we hit the extent which is basically how far out the box goes let's set something small like five centimeters and uh does my visual studio keep opening i think i'm like moving my mouse up to my monitor that's above the current one and accidentally popping that up again we're gonna stay at duration zero we're gonna do thickness one uh we have our hit result from before let's uh i'm actually going to cache this in a local variable here real quick uh hit result can i do that is that going to work yeah it does good and so before our branch i'm going to just store away actually i don't want to do that i don't want to store it away if we don't have a valid hit i'm going to do this like so and we'll move all this out just a hair cool cool cool cool and i could be really ocd and lay that out a little better great so now we're going to take our hit result and from our hit result we're going to break it out into all of its component pieces and we are going to draw at the hit result impact point hit result impact point is where our box is hitting the surface [Music] you can see it now that black box right right where it hits is that coming through on the stream yeah all right good stuff good stuff okay so we have almost all of the pieces that we need to to do our spray here the one thing that's missing is we got to get the rotation right for our little new guy here because if i were to say uh turn him let's just play the rotator and see what happens as i turn him around he stretches and distorts right this is not what you want it needs to be pointing the correct direction in order to project properly onto this surface otherwise you're gonna get all sorts of weird stuff going on here that one actually looks not too bad but anyways we uh we we gotta find the correct direction and the way we're gonna do that is we're gonna use the normal of the surface that we hit um in a normal so if you have a plane the normal is the point on that plane that is perpendicular to the plane um same thing on like any mesh vertex normals this is an example of what that looks like you can see each little vertex here there's a little red line coming off of it that is the normal for that vertex and it's perpendicular to that point on the surface i've got another image here which i'll show you that visualize it similarly like on each face of this cube the green line is the normal pointing off of that point in the cube you can change those in the vertex data yes exactly so if you're if you're doing 3d environment art you're very familiar with this if you're uh if you're just like a lowly programmer like me it comes up but you know i'm not i'm not messing with normals too often so it's not a big deal for me let me get back to my correct view on stream here all right so one of the things that our hit result gives us is the impact normal and the the hit result normal i'd actually check what the difference is here but i think what we want is probably the impact normal this is going to give us that that normal vector so before uh before we do anything let's also draw that this time let's draw with an arrow and our vector in this case we're going to start from our hit impact point and our end point is going to be i think the normal is normalized so it probably also has a total magnitude of one but what we're going to need here is vector addition and we're going to need to scale our impact normal up let's make it always be 100 units so we'll say our normal drawing regardless of the max spray distance is going to be uh one meter so we add that to our starting point and that's going to give us our end point here i think that's going to be right again i'm going to set my size to like 1. let's uh let's make this one be yellow and i'm going to make my thickness b1 again so this is basically just matching all of our other parameters again we got some spaghetti let's clean it up as you all know how i feel about that i'm actually gonna get rid of this line and we can draw from our reroute node here just have two of them going in clean this up a little bit you know it's not perfect but this is probably good enough so let's see if that gives us a good visualization of our normal hey there it is so you can see that yellow line is perpendicular to the hit point doesn't matter where my character's standing it just matters where uh on the surface we're hitting and this should also work well with slopes and stuff let's uh let's make sure that's true i've got a lot of like easy 90 degree scenarios here but i want to show you what a normal is going to look like on a sloped surface so let's drag in a static mesh that is sloped uh where is that i think that is all under my super grid content source meshes and yeah let's get a slope here so i need it big enough that i can actually hit it from my my character's head we're gonna make it super big here oops yeah that should work all right let's see if i don't spawn in it there we go okay so here you can see the normal is perpendicular to the surface still so in this case it's pointing up everybody with me on normals here all right let's uh let's make it actually do the spray we're very close to having this implemented but the cool thing here is like so let's say we've implemented it and we have a bug like now we have a nice visualization for what the code is actually doing and if you try and compute this from uh just like the debugger all you're gonna get is that line trace xyz stuff and you can do a bunch of math and like figure out what's going on but i'm not smart enough to do all that math and figure it out i like having the visualization um and so it's pretty common that if you're working on stuff that's operating in 3d space you can use all of this functionality that unreal engine provides to make it easier to figure out what the hell is actually going on you would actually do the math instead of visually debugging yeah yeah being able to reason about this stuff geometrically uh makes your life a lot better better and then when you can draw it it's really easy you don't even have to reason about it you just be like oh what's it actually doing all right so let's go implement our request spray function out of all of the capabilities that we've built so far if if we can't spray we're not going to do anything [Music] if we can spray then we're going to take our hit result and from our hit result we need our uh well before we do that actually we're going to spawn at decal spawn decal at location and for now we are just going to use our decal material that we created before i think i called that spray yeah spray decal material uh our decal size we said that 64 by 64 looks good actually like let's be good here let's uh let's make this a tunable spray decal size so now a designer can come in here and change it up if they want to um it's going to be a vector we need to compile so that we get defaults let's make it 64 by 64 by 64 and we can come tune that later the location that we're going to spawn it at we already talked about is going to be our impact point so that's where we're drawing the box right now and then the rotation we can just make from our impact normal and i think that's going to be rote from x so in general in local space on an object in unreal uh x is the forward vector so this ought to do what we want uh you can also set the life span the life span controls uh whether it despawns or not if it's zero it will never despawn if i set this to like five seconds uh it'll despawn after five seconds so let's let's do that for now we'll set to five seconds all right now the other piece that's missing right now is even though we have implemented the function to do the actual spraying we haven't wired it up to input yet so we did like a lightning tour of that last time we're gonna do something similar here um basically i need to go into my project settings i need to come to input and create an action here so we have jump and interact from last time i'm going to call this action spray and i want to bind it to my t key by default oops not s i actually wanted to there we go all right so that is now bound then the next piece is i need to have my oh that's my game mode i needed my controller i think let's save everything before the editor crashes we're gonna oh oh what did i just do no i do not want to open gpa thank you uh okay so i want to go into my controller here and if we press the what did i call it the spray yeah input action spray if i press that key i want to get my controlled pawn which is the thing that is controlled by our controller and then on our pawn i want to find components maybe it's called git component get component by class that's what i'm looking for if it has a spray component ep spray component then we're gonna do a valid check and if it's valid we are going to request a spray so now any actor any controlled pond that we create that has a spray component now has the capability to spray and the thing that's cool about this is i didn't have to write any code in our character itself i just added this component to it so if i want to take away the ability to spray i just delete this component if i want to make a super cool vehicle that can spray i just put that component there as well very easy now if i come up against the wall and press t we should spray and we do right now we've only got the potato spray and i think we said we've got the five second fall off oh the other thing i'll show you because somebody asked about this uh that spray exists in 3d space and so when the mesh it's projected on goes away it will disappear but when the mesh comes back it will also come back let me take away our lifespan so that it sticks around i might have needed to compile we'll see all right so you can see that part of new goes away but as soon as i bring the door back it comes back and yeah we can spam spray all right well like this is pretty cool right this is this is all pretty basic and let's make sure that what we said about this works as well yeah so you can see we automatically rotate based on the normal of the plane that we're spraying onto so it'll work on sloped surfaces similarly if we had implemented the ability for our character to look down we could spray the floor and everything would just work uh this also is going to have the same bug that you have in valorent which is if you do it on the edge it stretches right uh because we're we're using the normal for the surface that we're hitting not the normal over here unreal has another uh kind of decline called a mesh decal that is more complicated and can wrap corners but i have never used it for anything um but the engine does have some tech for for scenarios going around corners if you really want to get into it but yeah similarly here if i think i can probably go over the top of the box and we can stretch out his hair but your mental model for this is like hey you just have a can of spray paint and like if you fire your can of spray paint right here yeah it's gonna streak on the edge um and as you mentioned the amount that it streaks is going to be determined by the uh depth of the decal so if we come to our new here that is still just sitting in the world and if we bring him into a position where he reproduces that behavior if i come here and what is that is that my y dimension if i cut this in half the oh it wasn't the y dimension what dimension is that maybe it's this one nope this one so if i if i cut the x dimension in half uh the amount of streaking is going to shrink as well so you do have some control over that with basic decals do valerian spray have emissive on their material i'm actually not sure spy i would need to check i would need to check all right well now we can spray um but i don't like that we can only spray new eating potatoes um as you all know this is like my worst emote and it never comes up in actual gameplay because i never miss shot you know just stone cold killer every time head shot tap tap tap never need that potato emote let's uh let's make a spray randomizer right so right now we're just we're just spawning a decal using our fixed material instead let's uh let's have it so that we can have a set of textures here and let's make sure i select the right type today because we struggled with that on the last stream i think what i need here is just a basic texture just a texture yes and we need an array of them all right so let's call this array spray textures we're going to compile and hopefully the editor is not gonna crash we're gonna make this configurable uh i think we have seven emotes so let's have a seven slot array and let's just load it all up and we got that aim we've got exercise we've got the heart we've got hype peak i forgot hype let's fix that this is actually the most tedious part of this it's just like loading our array with all of the different types that we need that's okay all right cool so we've now got our spray textures here and we are going to i think it's set material parameter ah what's it called let's promote this to a variable we'll call that decal material sure that's fine spray decal material i believe we previously um set a parameter what's it called set texture um all right let's try this we're gonna get rid of context sensitive set texture parameter that's on a retainer box that's not right set texture parameter value this is what i wanted context sensitive wasn't finding it so sometimes if you don't have the right object selected blueprint is trying to help you by like not showing you stuff it thinks you don't want but i actually did want it here so that's what my problem was all right and if we look at our material let me see what we named that value i think this is over in our art folder it's loading up our shaders are recompiling spray texture is what we called it okay so what we want to do is we want to change the knit the value used for spray texture and i think i want to pick a random one what up saran yeah we sprang let's uh let's see oh this is cool i didn't actually know under a blueprint has a a random select a random value from an array helper which it makes since they would have but i was about to be like yeah let's get a random ant between zero and the uh the size of the array but we don't have to do that unreal did that for us hell yeah cool uh all right so it gives us an index we don't care about that it also gives us the item which is what we do care about so our target i see we need a dynamic material instance so let's do that dynamic material instance i actually don't need this variable anymore let's go ahead and get rid of it here it says it's in use i don't think it's in use it's fine we're going to say m spray decal then on our dynamic material instance we are going to set texture parameter value to a random texture and we instead of doing all of this stuff we are going to use our new dynamic material instance okay we got to fix the spaghetti though still have a little bit of spaghetti but it's less with electronic notes and that's what's important y'all turn on storage sense no i don't want to do that leave me alone windows i'll tell i'll come to you windows all right let's put this over here so we're creating our material instance we are setting the texture to a random texture from our array that we just created which has all of our individual textures and then we are going to spawn a decal and we need to use the material instance that we just created and i believe now i believe now chad we're gonna get a random spray every time let's check it out oh we got the aim spray i hit it twice got a potato we got our heart we got a potato again got another heart all right let's let's get that aim one we got the rage we got our peak hard again um you'll recall um we also made it so that you can't spray over the button so when i do this you can see the button draws on top of our decal which is what we want hey there's our am1 so everything's good the last thing i think i want to do here is set the lifespan to 5 seconds because i don't want an infinite number of them i think that might be everything that i want to show you on this one any questions any questions y'all i can spray they'll clean themselves up this one that i left in the world at the start is not going to clean itself up because i didn't cast it dynamically but all the other ones are just going to clean up right new spray and valerian when i maybe i could sneak that in make that a battle pass reward that'd be pretty cool you missed it do it all again [Laughter] how do you know all the blueprints you need to use um experience like when when you're learning right like like the point of this stream is basically to tell you that line traces exist and to tell you that debug drawing exists um when you're starting out probably the hardest thing is figuring out what to google for um but like once you have kind of a good foundation of like hey these are the individual building blocks you can you can figure figured out how does the gui work in the lobby i'm gonna save that for another stream i i do want to do gui so i thought about with this one i think the next topic i want to cover is i want to take the spray component that we've built here i want to implement cooldowns and recharging which will teach us about timers and i think that will also give us a good opportunity instead of using this debugging stuff that we've used we can we can build actual ui for it in fact you know i mentioned that our debugging doesn't actually do anything for us right like it just makes it easy for us to see what's going on but i'll confirm that now right i can still spray here all of my magic lines are gone if i'm standing in the middle of the map and i press my t key i don't spray so it's all working the way we expect any other questions make the spray a projectile ah we could do that that would be more complicated probably what we would do there is we would have the spray itself wouldn't be a projectile we would shoot a projectile and when the projectile collided with a surface we would then spawn a spray at that point um so you know another use uh you know we did this with sprays but um let me fire up valerian actually all right first i'm going to close this out i'm going to save everything i'm going to fire up valerian i'm going to show you another use case where we can do something very similar to what we just did here which is bullet and impact decals like it's the the same basic idea implement sprays cool all right let me let me fire up the game and i'll show you what i'm talking about uh no this is uh this is console z i'm i'm actually though i'm soon gonna move over to the microsoft terminal i really like the microsoft terminal but i've used console z for years and i haven't updated on this machine so as soon as valerie starts i'll show you but uh yeah bullet impacts are just uh are just uh decals is it a private repo yes it's a private repo on my computer and on my network it's not on the internet at some point we might uh if we do a bigger game project i can probably make it public um but for like these little toy projects i'm not really doing it up to a standard where i'm comfortable just like throwing it on the internet i would want to put a little more thought into it i think all right so let's go into the range here so the like one gameplay feature that i actually implemented you'll can be proud of me here but you know the uh the little uh shooting target in the range where you can set the distance right over here see those yellow circles those are just decals so when you have a hit impact based on the material that we're targeting we spawn a decal right so like if it's unpenetrable you get like this little impression but if you got like the odin and you can go through a corner right like we spawn a different decal so like this is a real world example of where like what we just built is super relevant and you'll also notice over time or uh if i create too many of them the old ones start despawning so like we literally just implemented the tech for bullet decals pretty cool right like some of these basic concepts allow you to do lots of cool stuff right out of the gate you see hours of immaculate blueprints that could be framed followed by public how does the system for keybinds work um so i mean we we talked about um in our project settings we can we can configure input right we did that and uh to implement keybinds you basically just built some ui that that changes the value of those binds in your local settings i didn't do all the bullet decals nick i i specifically did the shooting range bullet decal that was my pet project i i saw it in some other game and i talked to carney and i'm like carney let's build that and so i built a new physical material and i built some programmer art that is still used in the game it's just that yellow circle and then i did like six hours of plumbing through the various systems to teach the bullet impact system about our shooting range physical material that we didn't plan for um so input right like if you go to your project settings and if you come to input these are the actions i've defined um i can choose to expose these action mappings in a piece of ui and then allow a player to rebuy them in their local settings so like me setting this to t uh you know it's just the default we can we can change it to whatever the heck we want and so maybe we'll do that in another stream we can build out the ui for that but yeah what else y'all any other questions or do we rap and unreal and play some valor in cool i'm gonna get in there then that was your favorite part of the practice range i'm i'm happy to hear that so another feature that i want to implement that i haven't implemented because it's like slightly hard like it's not real hard but it's like slightly annoying and uh the value isn't clear um but a feature that i'm going to build someday if i ever have a project to do like a little or if i ever have time to do a little hackathon is i want to make it so that the color on that material changes every time you start a new spray so you can imagine you're sitting here spraying with your vandal and you do like four shots and then three shots and then four shots and like the first time it's yellow then it's like blue then it's like green we just like pick a random color for each tray and so you can really visualize your spray patterns as they overlay one another but it'd be lightly annoying to implement in our current system not because it's hard to implement in the abstract it just uh would take a while do i plan on doing networking things you noticed almost everything in val is server initiated i'm curious if there are any other accurate approaches involving prediction um so we have lots of things that predict on the client for example uh i need to turn off infinite ammo
Info
Channel: Nu Makes Games
Views: 3,591
Rating: undefined out of 5
Keywords:
Id: M7n3YSVqxRA
Channel Id: undefined
Length: 61min 29sec (3689 seconds)
Published: Wed Mar 17 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.