 Welcome back. All right, so in this video, we're going to actually take it up a notch and get a little bit more, I would say intermediate, because what we're going to do is we're going to put in the ability to allow the user to pick whether or not they want drawers or doors or some sort of decorative elements on the cabinets here. So if you take a look at the reference, I want the end user or whoever is using this HDA to be able to determine whether or not we get drawers or we have some double doors or a single door like this and even like change the counter of the amount of drawers that you have. So stuff like that. So to do that, we need to utilize multi-parms for this. All right, so what I'm going to do in this video is just show you how to set up the multi-parm such that we can basically store the data on a per primitive basis. Remember, we have these primitives and they all have IDs. So we can actually isolate out each primitive and let the artist change parameters on that particular primitive and make it completely different. So we're not just treating every primitive the same, and that is going to require a multi-parm. All right, so what I'm going to do first is I'm going to drop down a null node here, and that is going to be my out cab prims like so. And then the next thing I want to do is I want to go and set up my controls here. So I have my left and right panes and I'm going to pin this one. That way I can just work on the primitive or the parameters over here. And I'm going to go and open up the parameter interface and in the cabinet folder here, I want to put in another separator. So let's just drag and drop it there. And then we're going to add another folder to this. So we can actually turn these folders into multi-parms. So we have a bunch of types of multi-parms. In this case, we're going to use the list. In most cases, you're going to be using the multi-parm block list for Houdini Engine. All right, so I'm going to call this my cab overrides. By default, we're going to make it so that all the cabinets get drawers. But I want obviously the artists to change that. So we'll call this for the label, we'll just say overrides, and we'll get rid of that. There we go. Cool. So just by turning this into a multi-parm block list and hitting apply, we get this type of parameter right here that allows us to add certain instances, but we actually haven't added any parameters to any one of these overrides here yet. So to do that, we just start to nest parameters into this particular multi-parm folder. So the first one that I want to put in there is the parameter to let the artist decide which primitive to override. So I'm going to call this the cab prim id, and then we'll give it a label of prim id, like so. All right, so now if I hit apply, and I hit plus on the overrides, we now get this prim id in here. So the artist will use that to decide which primitive to override, right? And you can keep adding these guys. So in this case, we have three primitives. So if I wanted to override each one with some different, you know, parameters, I would just set it up like this. So this one's going to override primitive two, this one's going to override primitive one, and this one's going to override primitive zero. All right, and you can just clear them all out when you're when you don't need any overrides basically. All right, so then the next thing that I want to do is set up the ordered menu in this case. So I'm going to call this the cab type, and we'll just put type for the label. And this is where the artist is then going to select what type of cabinet this is. So zero is going to be drawer. So that's just going to be the default. All right, and then one is going to be doors. And then two is going to be decorative like so. Hit apply. There we go. And that's pretty much all we need right now. We're going to add a few other parameters to that as we get further into the development. So now you can see here if I added three, and I wanted let's say primitive one to be door, so I'd set it up this way, right? And then primitive, you know, zero, we'll just leave it on drawers. And then primitive, let's say two is going to be a decorative element, right? So that's how we set this up so we can customize each one of these primitives. All right, so let me clear this here. Cool. So let's get all that going. So I'm going to drop down another object merge node, put it over here, and I'm going to say get cab primes like so. And let's just drag and drop this null node into there. All right, cool. All right, so the first thing we need to do is drop down a for each number. This is how we're going to loop through the amount of overrides that we set on this multi-param list here. So I'm just going to wire this guy in here. Cool. And the first thing that you do when you're setting up these multi-params is just copy this parameter, this overrides parameter here, that multi-param parameter, and go into your for each end and paste relative reference to the iterations. So in this case, we have no iterations. So nothing's going to happen. All right, very cool. And we also want to set this to a feedback iteration. And on the for each begin node or the block begin node, we want to set that to fetch feedback. So for each loop, this node up here is just going to fetch the feedback, whatever comes out of this node, just comes back up and into the block begin, and that way we can keep processing it over and over and over again. All right, so if we add a override, you can see now our iterations is one on our block end node. All right, cool. All right, so in here, inside of this loop here, this is where we're going to add our data. We're going to add more attributes now on a per primitive basis. All right, and so I'm going to call this set overrides. This is where we're going to set all of our override data. All right, so then let's go into this wrangle node and just set up the code. It's really basic. Nothing crazy so far. Trying to take you through this step by step. These multi-params can be quite confusing at first, but what I'm going to do is get the prim ID from our override. All right, so I want to have the ability of getting this user defined primitive ID right there, and we also are going to need to get the type. So first off, we're going to do a CHI for an integer channel. And I'm going to just call this prim ID. Then the other one is type. Again, it's an integer, so we want to do CHI and we want to do type for the label. These are the spare parameters right here. So I just hit this little button right here to expose those. Very cool. Okay, so how do we set this up here? So how do we get the current data from the current iteration that we're working on? So the current override that we're working with, how do we get that over into here? Well, it's not too difficult. The expression goes like this. It goes CH, right, and then you do a string cat. So we use the string cat functionality. And then inside of here, we're going to put in the name of the node where we want to get the data from. So in this case, it's going to be this controls node. So we just type in controls, right, and then we want to get this cab prim ID for this particular one. But you'll notice that it has a little one after it, right? And that's how these multi-parms work. So they basically append the ID of the override or the multi-parm instance to the attribute name or to the parameter name. And so I'm going to select this, but we can't use that one in this case. This needs to be dynamic. And so that's why we're using the string concatenate function because we want to concatenate two strings. So the second string in here needs to be the current iteration, right? Remember, this block begin node over here, this metadata node actually stores the iteration attribute as a detail attribute. And so we need to get that value into here. So the best way to do it, in this case, there's lots of different ways you could do this. But what I'm going to do is just add a new spare input, like so. And then just drag and drop this node in here. So now we actually have access to the data. And you know that by this purple line here. So that means the data from this node is coming into this node right here, this attribute wrangle node, as a spare input. Now these spare inputs are indexed negatively, right? So you refer to this in expression as negative one. Rather than you might have seen before, another wrangle node is where we use like zero one for these inputs. All these spare inputs are negative values. All right. Cool. So now what do we do? So what I'm going to do is actually put my cursor into the prim ID here and do an alt E that opens up the expression editor here. And I'm going to finish up the expression here. So now we need to do a detail. We want to get the data from negative one, right? That's that spare input right here is negative one. And we want to get the iteration value. All right. And then what we want to do is add on one to that. And the reason for that is because these for loops start with zero, but the multi palm lists start with one. And with that, let's just hit apply and accept. And now if we take a look at the number here and move this guy, you can see it's moving that prim ID attribute. So we've successfully hooked up our multi palm attribute or parameter to our wrangle node here on a per override basis. Cool. All right. So let's do the same thing with our type. Now that we've got the expression set up, you can just copy and paste it. And all you need to do is just change out this one parameter name now. So we're going to do cab type. So you can see it's, it's appended on a one, which is why we add that one to the detail expression here. Cool. And we actually need to get rid of the one there. There we go. So now if we were to take a look at the value here, you can see it's moving up an index as we change the type. Very cool. Okay. So now we need to take that data and we need to put it onto the primitive that we actually want to override. So it goes with the primitive. And that's easy enough. All we need to do is in this case, we just need to store the type for now. So I'm going to do a set prim attribute. That's how we set a primitive attribute, which is what these guys are over here. And I'm going to set it on geometry zero. That's the incoming geometry. And we're going to set it as the name type. And we're going to give in the current prim ID. So this guy right here, we're not going to use app prim ID. We're going to use this one. This is the one we want to override. And then we're going to set it to the current value of type, which is this guy right here. So that's the current selection that the artist has made or the end user has made. And then finally, we just want to tell it to explicitly set it like so. And now we have this type attribute on the primitives. So for primitive one in this case, since I've set the prim ID on my multi-param list here to one, I'm currently overriding one. So now if I set the type to doors, right, you can see now the type has switched just for primitive one. If I add another override in here, and let's say I want to override number two over here, and I want to set that one to decorative, you can see now that one's been set to two. All right. So hopefully that makes sense. And that's how we start to put on all this custom data. So let's just kind of stub in the network now for actually performing the operation, the custom operations that make doors and tours and decorative elements, right? So for this, I'm going to loop through at this point. Let me actually turn that off. That's on the keyboard. There we go. I want to do a for each primitive this time. I want to loop through all the primitives that we have. Because at this point, we actually have all the custom data set now. So now we got to loop through each primitive and decide what to do, right? All right. So now if we turn on our single pass, you can see now it on this pass, I have primitive zero, but its type is set to zero. So that means you're just going to be some some drawers. All right. So let's let's get all that functionality set up. So I'm going to create some subnets here. And the subnet is going to be called build drawers. All right, we'll just pump that in there like so. Then we'll put down a switch node. Then we'll call this the type switch. And we'll wire that into the output there. All right. And inside of here, what I want to do is I want to put in a null node. Again, this is just, you know, what I do. And I call this prim in. Usually, I just put a null node there to indicate what kind of data is coming in to the subnet just to keep it clear for myself. And all I'm going to do at this point is put in a color node so we can see things changing. So drawers are going to be red at this point. All right. Then I'm just going to do an alt left click drag to create a copy of that. And this one's going to be build doors. There we go. So I'm just going to wire that guy in there. I'm going to alt left click and drag that guy. And this one's going to be build decorative and pump that into the type switch there. Let's make a little space. And one thing I want to do right up here is I just wanted to use an attribute promote. Now you don't necessarily have to do this. I prefer putting all the attributes onto a detail at this point because remember at this point you just have a single primitive and it's a lot easier to use the detail attributes at this point. All right. So I'm going to or I'm going to promote our primitive attribute to a detail attribute and that's going to be type. So now it exists on the detail level. So we're going to say promote type adder. Very cool. And then in our type switch now we can go and get that detail attribute per pass or per iteration of this loop. So all I need to do is just put in the detail and we want to get the information from our promote type attribute. There we go. And the the attribute we want to get is type and it's because this is a single value we just put in zero there. All right. So now this guy is switching this switch here is switching on the type that's been set by the user for this particular primitive. All right. So in this case we're going to get red. So if I turn off my single pass now by default they're all going to be red. So by default when you first instance this into Unreal using the Houdini event or it's going to be all drawers. But now let's say I want to go and customize and I need to change the colors here. Sorry. There we go. So now we'll be able to see the customization working. Put that one to blue. There we go. So now as I change these guys around you can see that I'm customizing all this stuff. So I have doors over there and now I've got drawers. Maybe I want you know primitive one to be decorative. So I have doors here drawers and a decorative element there. Or if I wanted to send that over there now I have drawers for one decorative elements for there. So that basically is the fundamental concept behind using multi-parms to let users override aspects of your procedural model. It makes it very powerful because you can start to really build in deep customization to your HDAs. So I'm going to call this out cab overrides and we'll pump it into our assemble node here. Like so. And there we go. So now we are on our way. We're starting to make a really full featured HDA. All right I'm going to put a null node down here. It was called out final. There we go. All right so hopefully that wasn't too confusing. Definitely let me know. Send me a message or email whatever you're most comfortable with. I'm going to call this cab prims and this is going to be called our overrides over here. Very cool. All right so I'm going to close the video out there and move on to the next and we're going to start building drawers. In the video after that we're going to do our doors and then we're going to do the decorative elements. Thanks so much.