Getting Started With Procedural Mesh Generation | Inside Unreal

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
ARRAN: Yeah, this is a demonstration of just some of the Procedural Mesh tools that you can use inside Unreal. So it uses the Procedural Mesh Component that you can kind of add to any Blueprint that you're doing, and in most of the instances that we've seen, it's kind of been used for doing lots of kind of slicing, so there's another function that lets you break up a mesh into multiple pieces so you can do that kind of Fruit Ninja-style cutting items in half. So what I've been kind of doing is doing lots of experiments with the Procedural Mesh Component, and, yeah, these are kind of some of the results that I've come up with. So I've ended up using it to kind of build kind of a stylized tree generator, so that it basically lets you create these things inside engine, which is useful because it means that you can actually see what it's looking like in engine as you're building it, and it just kind of gives you a way of kind of building these tools easier. I've always found that this kind of stuff is a bit of a pain to do inside things like 3ds Max and Blender, so, yeah. It seemed like a good use case to kind of get this thing going. So what I'm going to do is kind of run through some very kind of easy starter content for getting to grips with the Procedural Component and then do a bit of a walkthrough of how these particular assets were made and then talk about where the plugin could go and kind of if you want to download it and add to it, then that's cool. So am I okay to start off with the intro content? We all good? VICTOR: We are good. Sound good, looks good. ARRAN: Awesome, so I'm starting off with a triangle because that is ... It's probably the easiest shape you can do. It's kind of the basic bare minimum that you need in order to get some geometry rendered on your scene, and I've got this little kind of example Blueprint here that lets you pick between a few different kind of key shapes, so we've got a triangle. We've got a quad. We've got a cylinder. We've got a cone, and then we've also got a custom mesh as well. So this Blueprint is kind of like just that nice base starter, and it all operates inside the construction script, right? So all of these assets are running entirely inside the construction script, which means that you can edit and build stuff without having to go in and play in editor or anything like that. You can just do it straight in the editor. So starting off with a triangle, this one is super, super, super simple, right? All I'm doing is, I'm specifying some vertex positions, and then I'm getting the triangle order, and then that gets fed into this bad boy over here, the Create Mesh Section. And all this done is it takes in arrays of data, so we've got vectors. We've got integers, and we've got kind of UVs as well, so it's a vector 2D, and then it uses that array information to build the mesh. So inside my component here, I've got a Procedural Mesh Component, and if you want to kind of build this stuff yourself, that's super easy. You can just kind of go in and add the Procedural Mesh Component as you need, and then all you need to do is figure out where those points go and then build your assets. So the easiest thing, I would say, to do is actually building your vertexes. That one is not really that much of a problem. The thing that's quite difficult to do or can be quite difficult to do is figuring out how to build your triangles because you need to figure out how to sort those things, sort that order out so that it's drawing correctly, and that's kind of why I stuck with the foliage aspect of it because actually, foliage, it's all simple shapes. It's just about the placement of those simple shapes as they kind of stack forward, so with almost all trees, you're only ever really dealing with cylinders and cards, and that's kind of all you really ever have to worry about, and it can get more complex than that. And we've got a few demonstrations of how you can get a bit more complex that that, but for the most part, it doesn't get past kind of those cards and cylinders. So once we figure out how to draw a card, we can figure out how to draw a cylinder quite easily after that, and then once we've figured out how to do those two things, all we have to do is start stacking them on top of one another until we get a tree. So my draw triangle, again, really simple. All we're doing is, we're specifying three points in space, so that's going to be my vertex positions, so the first one is 000, so zero access, and then we're doing one of set up in 200 and one asset in X200 which gives us our two points on either side, and then all we need to do is have our triangle build around that, so I have my triangles sort order. And all the integer is doing here is it's specifying the vector position in order to make the triangle. So here I'm specifying 210, which is going to equate to 210 inside the vertex array, and then it will build a triangle based on those particular points in space. So once we have a triangle, it's not a difficult step to build a quad, and in this case, I want to build a grid of quads. Right? Because we can step up from there quite easily. So in this particular instance, I'm doing a nested loop. Please forgive me, and we are basically getting an X length and a Y length which is going to be our, in this case, our number of vertexes in the X and Y coordinate, and then we're looping through, and we're adding a vertex in X and Y, so getting these particular coordinates, multiplying that by 50 which is going to be our gap between our vertexes. And I'm also doing a UV position as well, which is basically normalizing my X length, so the max number of vertexes that I'm going to have in my X and max number that I'm going to have in my Y and then dividing that by the current number that I'm on to give me a normalized value. And that means that when I create my material, my UVs will be correctly scaled across the X and Y access for my grid. Now, if you're doing a basic grid, we actually have a function built in called Create Grid Mesh Triangles. What this will do is, it does all of that kind of difficult triangle-calculation work for you, so you basically just put in the number of X and Y coordinates that you're going to have, and then you set the array of triangles, and it will output those triangles for you in this particular array here. And then we also have a function for generating your tangents and normals, which are important for giving you an accurate tangent and normal-facing shape for your faces, and that's just done in the calculate tensions for mesh, and what we need to do there is input your vertexes and your triangles and your UVs, and then it will output the normals and tangents for you. So all of that stuff is quite easy. So with draw quad, we get all of our vertexes. We get all of our UVs. We get all of our triangles, and we get all of our normals and tangents, and then that gets plugged into here. So the grunt of the work is all done in figuring out where all the vertexes need to go and where all the triangles need to go. Once you've got this kind of basic information, the rest of it will kind of fall into place quite nicely. So once we have a quad, it's a fairly easy step to turn that flat quad, which we've got over here ... And I can kind of show you the Y frame of this as well so you can come see the shape. So you can see, we've got that X and Y coordinate going in there which gives us our grid pattern. And then all we need to do is wrap those vertexes because our triangle calculation doesn't need to change. All we need to do is wrap those vertices around a point in space rather than just doing it on a single axis. So if I switch over to this one here, you can see that that's all we've done, right? Instead of doing it on the quad, we're basically using our axis here as a center point and then expanding out from that shape radially to give us our final object. So if we take a look at the draw cylinder, we have a rotate about vector, which is how I'm doing that kind of simple axis around our vector, and for the X, all I'm doing is getting the number of components again, so that's just the normalization of X, multiplying that by 360, so I get my coordinates correct for the 360 degrees, and then I rotate my forward vector around my up vector. Right? So if we're thinking like that, that's my up vector. That's my forward vector, and all I'm doing is, I'm just twisting that round and then putting a point in at those kind of increments as they go around. I'd have to break my hand to show you properly, so you'll just have to take my word for it. And then we're multiplying that value up by 100 because the forward vector is still just a vector, so we want to increase the scale of that particular vector. And then that gets plugged into my add value, and then by Z is actually exactly the same, so it's just Z times 50, right? Which is just my vertical increment, and then my UVs are the same. My triangles are exactly the same, and so are my tangents and normals. So that basically gives me my cylinder shape, and then once we've got the cylinder shape, it's a fairly easy step to then modulate the width of that cylinder over the height of that cylinder. Right? And this is where the cone shape comes in, so if we switch over to this one here, like so, you can probably guess how we're building that particular shape. So all we're doing is, instead of multiplying it up by a single value which was 100 in the cylinder, we're now taking into account the normalized Z value, so the normalized height of our cone. Sorry, and then we're inverting it as well, so instead of it going between kind of zero and one, it's going between one and zero. So we add the base. That scale is going to be at one, which we can multiply by 100, and then as that value goes down, we can then multiply that down so it becomes smaller until you reach nothing. Now, this is just one way of doing it. You can also, then, multiply this by a curve value over time as well, so you can control exactly how you wanted to do this, or you could do it by something like a spline if you wanted to expose that value out and create kind of a lathe approach. And then you can see here, all of the other code is still exactly the same. We haven't changed. We haven't changed any of this stuff. It's literally just changing how we calculate that initial outward value. So that's quite a bit of information. I don't know if there's already questions or not or if I can carry on going. Victor, do you want to ... VICTOR: I think you can keep on going for now. We're collecting all the questions, and ... ARRAN: Keep on going? VICTOR: Yeah, yeah. We're still good. ARRAN: Cool, so once we've got our cone shape, that's kind of like the basics of generating our mesh data inside our Procedural Mesh function. There's one extra one that I want to show you which is really useful if you want to grab anything that's more complex. So this is called the Get Section from Static Mesh, and what that allows you to do is, it allows you to specify a Static Mesh that you want, and then it will output all of that data for you, the vertex, triangle, normal data. So if you want to start adding in more complex shapes into your procedural generation but you still want to be able to get the normal data or the vertex-color data and specify that, then you can still retrieve or set that particular data using this function. So for that final demo, this one here, I'm actually getting a mesh that already exists and then just replicating that to the Procedural Mesh Component. Let's close out all those. So there's one extra function in here that I haven't covered yet, and that's just clearing the mesh data. So this is a really important step that you do need to make sure you're doing as you're going through and building your content. I've run into this quite a few times where I forgot to clear my vertex data and then all my triangle data, and I was trying to figure out what was going wrong for ages. My computer was getting slower and slower until I realized that I had just been stacking my vertex data on top of one another until I ended up with just an insane array size that was making my computer very sluggish. So the first thing I do when I start building these components now, I've learned through hindsight, is I just build a function that clears all of the relevant data that I'm going to be kind of setting and updating. You might notice as well, for the eagle-eyed viewer, that I'm not clearing all of my data, and that's because some of this data is set manually, so for these two data sets here, normals and tangents, I don't need to clear that data because I'm setting it manually in here, so it would get overwritten anyway. So that's the very, very quick basics of the Procedural Mesh Component, so that gets you from going from a triangle all the way up to a cone which is the magical world. VICTOR: Hey, Arran. ARRAN: Yes. VICTOR: Do you want to go and hide the grid? We're getting some flashy artifacts here. ARRAN: Oh, yeah, sure. Sorry. I did have that hidden, but it has ... VICTOR: Thank you. ARRAN: ... clearly come back. Yep. Thank you. So once we've done those particular sets, we can start building some more complex data. So I've got a few different tree examples over here, and I'm going to try not to edit them because I've got quite a lot of examples in this project open, and if I make any changes to anything, it's going to have to rebuild all the trees. Now, for this particular project, if you're interested in downloading and trying it out, just a few quick notes. They are all inside the Trello plugin, the Trello doc, so make sure you go through all of that stuff first, but just in case. It's all inside the plugin, so you do need to put the downloadable content into a plugin folder. It will work in 4.25, even though we're on 4.24 here. I have tested it. It's a content-only plugin, and none of the content that we've been building is experimental, so it should be reasonably stable, kind of fingers crossed going forwards. I have run into a few issues with building out the final asset. So one thing that I recommend doing is actually going into your project settings or your editor preferences and just increasing the max-loop count for your project, just for this. Obviously, you don't want to really do that for any game projects because you don't want your loops to be getting that big because you'll end up with some frame hitching, but for this, where we're just kind of playing around in editor and it's never going to see the end consumer, it's absolutely fine to kind of whack that number up. So the project itself is a number of Blueprints which are kind of snappable onto one another. So there's three in total. There's a trunk, which has a base-spline component which you can kind of go in and tweak and edit, so I'll do that on this one here because it'll be a bit quicker. So it kind of uses this spline shape to build its geometry. Then you can kind of go in, and you can edit that and make it look kind of ridiculous. Then there's a branch component, which is built on top of that. So for this particular one, if I just hide these leaves, there's these kind of branches procedurally placed on top, and they can stack. Right? So you can put a branch Blueprint on top of a branch Blueprint on top of a branch Blueprint, and that will be fine, though you will get into scaling issues because it will put X number of branches on each layer of branches as you do it, so that does get exponentially more expensive very quickly. But this will basically take in either your branch or your trunk data, and then it will spawn other branches along that particular point. So you can kind of see, I've got my trunk here. I'll just get rid of that bark as well. I've got my trunk here, and then off of that, I have my next layer of branches, which I've got a set number of. So if I go down here, you can see the spawn count is set to five, and I can increase that if I want to, so I get more. And then off of that, I have more branches which are spawning off of those branches. So for this particular one, I have five branches that spawn off those branches. Now, the way this works is that it's going to spawn five branches on each branch which is, again, why it gets exponentially more expensive as you build. And then finally, I have my leaf layer which actually uses the Static Mesh to build. So for this particular one, it takes in a mesh or an array of meshes. So in this case, I've got this little thing here, and it will then scatter that mesh across whatever its parent is in the hierarchy, whether that's the trunk or the branches itself. So for this one, the leaves sit right at the end of the hierarchy, right? So we've got eight branches spawned across five kind of times six branches, so that gives you all of the kind of leaf cards that you'd need on top of that, so you can kind of turn these on and off. And kind of the reason why I broke this stuff up was because I wanted this tool to be componentized, right? So you could build multiple trees, and I could copy and paste this particular leaf setup over to another tree, and it would just populate that other tree. So you can kind of try this out with the plugin when you get it. So each of these sets has a load of different setting that you can apply to it. So if I start back off with the trunk, I've got the number of length and radius segments that you can add to it and how thick that branch is, so I can make this trunk much thicker if I want to, and it would just kind of update, and you'll see that that information actually propagates across, so even though these are different components, they still interact with one another. Just going to make that thin again. I've got some material settings, which again we'll dive into because the material is doing some interesting stuff as well. I actually have got a displacement texture implemented in, though it's still ... It's not particularly performant, so that does still need a fair bit of work, and then I have my references, so you can kind of see here that this has a reference to a parent and a root, and then it has its child references off this, so this is how I'm updating all of the objects inside this particular tree even though they're separate components because they've got these references to that class, and then finally I've got some exposed buttons on top of this here, so it let's you add particular components to this, so if I want to add another branch layer or a leaf set, I can do so just by pressing one of these particular keys, and then the same with the branch data. I've got some variation controls that give you some curl and some just shape controls that you can get some nice variation, some length control for that as well, again, spawn count, length and radius. A lot of this data is shared, and then some location, rotation and scale parameters to allow you to control how those objects are doing, and if those objects have a parent, then you can modify the range of that as well, so for this particular one, I have a parent range, so it basically clumps the spawn location for all of those branches, so at the moment this is at 0.4, so the branches only start spawning about halfway up the tree, but I can have that happen way lower, so if I set this down to 0.1, then these branches will start spawning much lower down on the tree. Actually, it looks quite good. I quite like that. Anyway, let's pop that back up to 0.2 just so we don't get any clipping, and then finally on the leaf component, that has again very similar data. It's got location, rotation and scale, and my location has gone up there a little bit for some reason. It has its references as well, but what it also has as well on the mesh side is an option to render as instances. Now I added this as I was running into some performance issues because this is running all on construction, and that loop count can't get quite large, which means that you can end up with a fair bit of pausing and freezing as you're tweaking and changing those values, so I've got this brilliant option here. You can see it kind of stops the foliage from moving. Let's go back to that, but this is really useful because I can actually set my spawn count much higher without having to worry, so I can set this up something like 100 or something. That might have been a bit high, but I can set it ... VICTOR: It looks great. ARRAN: It looks amazing, doesn't it? VICTOR: That's the alien world, right? ARRAN: I think my computer might be dying. It might by dying. I'm just going to knock that down a bit. That might have been a bit mean. VICTOR: Take everything by 30 percent less because this already eats up 30 percent of your GPU for streaming high quality. ARRAN: The stream has already tanked, but yeah, so I can control that, and that's really useful if I want to just see what it looks like without having to worry about it having to recalculate all of that geometry every single time. What did I have it on before? I'll just put it back to six just so it's ... Keep it reasonable just for this stream, so yeah, and that's the basics of it, so I've got these individual components, and then I can slap those onto one another just as I need, so let's open up the Blueprints and let you take a look at those, so I go back to my construction script, all my construction script does is run a function called Draw Me, which is how all of that stuff is calculated, and Draw Me is an exposed function as well, so you can call this manually, and that's actually how the updating children works, so if I go into the Draw Me function and call Update Children, you can see that all it's doing is it's getting those child references and then looping through and telling them to redraw, so it's telling them to call Draw Me, so even if you're editing one step lower in the hierarchy, it will work, and again this is another reason why I can broke these up into separate components because I didn't want to have to redraw the entire tree if I was editing things that were higher up in the hierarchy that wouldn't get affected, so the benefit of having this broken up, again, is that I can edit my leaf Blueprint, and it won't have to redraw any of this stuff underneath because none of that data has changed, so if we go to my construction, my correct Blueprint, you can see I'm calling that function, that first thing that's clearing all my data that I don't need, so in this case, I'm clearing all of this stuff. And then I build my branch data, which is this thing, and all I'm doing here is I'm checking to see if there's a parent. If I have a parent, then I need to modify my workload because I need to account for the fact that we've got ... It could be just a single trunk that these branches are spawning on, but it could also be the case that it's spawning across multiple branches, and at that point I need to be able to identify that, so the parent will get identified first, and then I have this thing called my tease array, which is basically just an array of transforms and scales which will allow me to get that particular data, and then I look through, and I build all of my branches, so all of this stuff in orange here, that's just figuring out the spawn point of my branch, so as I'm building this ... Let's just hide these, so what I'm doing is I'm finding my parent. In this case, it's the trunk, and I'm grabbing the transform data, the transform array data, of this thing, of this trunk, and then I'm scattering spawn points onto that based on data that I'm setting, and then once I have that transform, I can make my branch, so all my branch is doing is again it's figuring out where it needs to spawn, so using that base location, and then it's drawing that radius, so if we go to the radius, that's going to look the most similar to you as we were looking at before, so that's where we're building our vertices and building our triangle data and then also building our UV and our vertex color. I am working on getting Pivot Painter working as well. That's still a big of a work in progress, so you'll see a lot of stuff on Pivot Painters that's just tucked away. That's not working yet, so you'll have to wait for that one I'm afraid. I need to get some more help with Jonathan Lindquist to get that one working I think. So once we have our branch data, we can create our mesh, so again that one is quite simple. All we're doing is we're grabbing that data that we've calculated, and we're feeding that through to the mesh section, setting our material for that Procedural Component and then setting that to this standardized data set that I'm using to pull data back and forth between lots of different Blueprints. It's probably going to be a little bit easier to see, so this is the trunk script, so what I'm doing here is again it's the same thing. I clear that data. I calculate my segment distance, so this is going to be the scale that I'm going to be offsetting along that spline, and then I do the ... If you've done anything working with spawning stuff along splines, then this will be fairly familiar to you. All I do is I find my points on that spline, so I get the transform at that distance, and then my draw radius does exactly that same thing as we were doing with the cylinder, so we have our radius segments over there, and we just go through, so again getting my vertex data, getting my triangle data, my UV data and vertex color data. And then for my leaf, I think this one is actually the easiest one of all because we actually don't need to do much of that calculating the mesh because I gives it to us, so all I'm doing here is I'm getting that mesh array variable, which just defaults that to this cube here, and it gets that triangle data and vertices data, all that good stuff, and then it sets it to a data collection, so I'm just grabbing all of this information here. And then I can go through and build that mesh, so again clearing my old data because I don't need it anymore, finding my parent and finding the transforms for that parent, so this is my tease array here, and then I have to do that nested version again because I might have multiple branches that I need to spawn across. Then I figure out my location, exactly the same, and then go through, and this is where I've got the branch here, so I can choose between rendering instances or rendering the mesh calculation, and the mesh calculation is, again, it's doing pretty much the exact same thing except in this instance I'm offsetting my vertex data so that I can stack it all together, and that gives me the tree component, so if you're going through building some of this stuff yourself, the hardest thing to actually get working is stacking this data so that it works with the Create Mesh section, so in order for this to work properly, you need to be able to offset all of your data correctly, and this is why the Create Grid Triangles doesn't work, so the grid mesh triangles, because this needs an offset in order to work properly, so this data output doesn't work, so you actually have to build that function yourself when you're going through. Now I've built it so you can technically just grab it from here, so if we go to my branches and go to my construction script and make my branch data and drop my radius, this is the function that basically does that, so this is all I'm doing. It's really, really dumb and really, really simple, so all I'm doing is this is creating a quad, so this is my first triangle, and this is my second triangle, and yeah. It's pretty simple, but the main reason why I had to build that was because I need that initial offset because otherwise the triangle data won't match up with the vertex data that you're trying to build, so just keep that in mind when you're trying to build your content. And that's the basics of it, so we can go into a bit more detail into how this stuff works. I can give you an overview of the upcoming features of the things that I ... VICTOR: Can we tackle a couple of the questions first just to sort of go over ... ARRAN: Yeah, absolutely. VICTOR: Sweet, sweet, sweet. So in general there's a little bit of conversations in chat around ... So specifically for trees, what's the specific use case for doing this in-engine, and could you maybe also talk a little bit about the possibilities? Why would you do it this way instead of using Houdini or just model the trees yourself? ARRAN: So absolutely. You can do it any way that you want to do it. There's no reason why this is any better or worse than the other tools available, so Houdini is great because you can export that out to an engine plugin and then bring that into engine. The main reason why I built it in here is so that I can see the content live so how it's actually going to finally look inside the engine, so if you're building it inside something like Blender or 3ds Max, then you have to approximate what you think the tree is going to look like, and this is quite difficult because 3ds Max's viewport especially is not very good at rendering this kind of geometry in real time, so it's quite difficult to get an appreciation of what this tree is actually going to look like until you've actually done it, so on the building it manually front, you've got that as an advantage. It also takes a lot of time as well. This stuff is quite annoying to build because the tool set doesn't really exist to make these trees particularly nicely. You have to go through and do a lot of finicky work and a lot of cleanup in order to get it working, and this plugin will do a lot of content for you, so if we take a look at this one here, this actually an exported mesh, and one of the benefits of doing it this way is that you get all of the vertex color assignment done for you, so for this particular tree if we look in the paint view. Don't want that one. Give me red. So I've got a red channel, which is a gradient that works outwards from the radius of the base of the trunk, so what this will do is it allows you to control the wind strength if you're doing anything of that stuff in shader, and then in green, I've got another variable that will color these outwards from the spawn point that they're coming from, so you can see that starts black, and then it comes out to green, and then I've got a blue channel which gives me a random color gradient, and this stuff is really difficult to do inside something like 3ds Max. You'd have to go through and manually repaint that stuff for you, so that's quite tricky, and then going through and actually painting these foliage sets on and seeing how it looks is quite a pain to do, so ... VICTOR: And if you have 30 different trees, you have to redo that, right? ARRAN: Yeah. Yeah. Absolutely, so you'd have to go through and manually edit it, whereas with this one it's all seed-based as well, so once I've made my tree and I'm happy with that, I can export it, and then I can duplicate it out and then do it where I could just make a new instance or a new seed off of that base data, so I could go in, go to my random seed and then just change this value. VICTOR: And so there are essentially two different use cases for this. One is to actually export it as a Static Mesh, and that's possible with the tools, right? ARRAN: That's the only really intended purpose. You'd always want to export it out as a Static Mesh. VICTOR: What you could also do is essentially modify that run time, which is something that you wouldn't be able to do with a pure Static Mesh, right? ARRAN: Yeah. Absolutely. VICTOR: Just talking a little bit more in general about the Procedural Mesh Component and the idea of why you might want to use that for other purposes than just trees, so in case you wanted it to grow in very dynamic ways that you can't really do with bones or vertex offsets, etc. You have that power prior to exporting it, right? ARRAN: Yeah. Absolutely, so the Procedural Mesh Component works in-game as well as at the editor level, so it would be work, but it would be reasonably easy for you to take this base code and have that run over a tick so that your tree was growing over time, so you kind of start at that trunk and then build out into branches which build out into leaves, so you could definitely build this as a procedural tool, and there's lots more that you can do with this as well. One of the other benefits of it being built inside your level is that you can expand this tool set so that it works. It takes into account the world around it as it's building, so if you wanted it to build up against the side of a building or the side of a wall or something like that, you could add line traces in to do checks and let this thing grow out a little bit more intelligently rather than how it's doing at the moment which is just based on random data. VICTOR: Let's do a few more of the questions, and then we'll dive into the rest of your presentation. makuzmakuz asked, "How preformative is this?" and then the follow-up question was, "Is it possible to regenerate the object every frame?" ARRAN: In terms of performance, it completely depends on the size of the asset that you're building. If you're doing it every frame, yeah, it does completely depend on how big a mesh you're trying to make. You can see even when I was rendering this as instances it took quite a while for it to process it, so as you're getting up to those large-scale objects like trees, you might run into performance issue as those things get larger. VICTOR: As it does when you're playing with a lot of instructions at one time. ARRAN: Yeah. It's all about how many loops you're going through to build this thing. VICTOR: Ylly was asking, and I'm not entirely sure what this is but, "How to set up a custom vertex factory?" ARRAN: Yeah. I don't know what that means either. VICTOR: I'm not entirely sure. If you want to go ahead and clarify that, we'll try to answer your question. TLuisRS asked, "Is the Procedural Mesh Component still experimental?" ARRAN: Oh, I need to double-check. I don't think it is. VICTOR: I think it might say in the list of plugins. ARRAN: Yeah. It would say on the Docs page, so you could have a look at it there. VICTOR: TLuisRS also asked, "Is it possible to generate different LEDs for procedural meshes, or this is handled automatically by the engine?" and I think we can dive into that a little bit of sort of how you would ... We touched on it briefly, but how would you go ahead and do that? ARRAN: Yeah, so for this particular instance when you build out your Procedural Mesh Component, it's only making one Static Mesh. I've got a billboard component, which has just gone white, but that actually does the demo of how you can also generate a billboard for it, which you could then export and then assign that to be allotted for that particular instance, so you can see this version here is just a Static. VICTOR: Impostor! Very sus. ARRAN: If I just take that, leave it off to the side, so this is doing a live capture, which is why it's moving. You obviously wouldn't get that in the captured view unless you stored it as a flipbook, but this will do a capture to a card, which you could then do it, and you could also use this to pair it with Ryan Brucks's OpTree Capture to give yourself more faked-3D sprite for this particular effect. VICTOR: And then Onnion_dev asked, "How do you deal with duplicated vertices when stacking meshes?" ARRAN: I'm not sure what you mean by that either, so do you mean when we're spawning multiple meshes like I've got here? I've got 12 instances of the same mesh? I'll just assume that, and then I'll answer that one, and if that's wrong ... VICTOR: Go ahead and with that. Please let us know if it's wrong. ARRAN: ... we'll find out, so the way that this works is that it gets the base data for that particular mesh, so in this instance it's this palm frond mesh type, and it gets all of the vertices and triangle data for that particular asset, and then when it wants to make them, it will use the transform of the spawn point to offset those vertices and then add them to a new loop, so inside my Make Mesh, this is getting my transform, so I figure out where I want to spawn my palm frond, and then once I've got that, I can use the transform location from that base to offset my vertex spawning, and that then gets added into my new vertex count, and the way that that avoids, they don't overlap. They have to basically add one on top of the other, so my array has to store the vertex data for every single instance of this particular one, so it will go through each count, and it will do it each time for that, so here I'm getting the vertices for this particular mesh, and then I'm looping through and transforming it, so it's transformed to a new position, and then that gets added to the new vertex data, and then I have to do the same with my triangles as well. So that's done here, so I get my triangle data from my mesh, and then I have to add it including the offset, so this is where it gets to be a bit of pain because you can't just ... Otherwise I could just duplicate this data, and it would be much easier, but I can't do that. I have to account for the offsets as I'm storing it into a single array. VICTOR: Someone else asked ... ARRAN: I hoped that answered the question. VICTOR: If it didn't, please let us know. ARRAN: Yeah. VICTOR: Someone else asked, "Would this be a reasonable method to use for foliage in a large area, or should this be limited?" ARRAN: So you should use it, if you use it at all, to generate single assets which you convert to Static Meshes, and then once they're Static Meshes, they're the same as any other mesh you'd have in your game, so you can use them however you want, so for some of the image content, we had that island scene, and that's built entirely using ... All of the foliage in that is built entirely using this, so I build each component. I export them out, so you can see my palms. I've got a few different examples here that I've gone through and created, and those are all just normal Static Meshes like anything else. VICTOR: And then you can use the autoLED tool to generate new LEDs? ARRAN: You can. You can. Yeah. You could use it to generate those, though I don't think it generates a card in this unless they've updated that, which would be awesome. VICTOR: All right. We have a few more that came in, but why don't you continue with what you were planning on continuing, and then we'll get through questions that are coming in later on. Okay? ARRAN: Oh. Okay. VICTOR: And I'm still going to be live, but I need to go mute my fire alarm that's been beeping for the last 25 minutes, so please go ahead, Arran. The floor is yours. ARRAN: Sure, so I've got a load of these examples here, and this stuff can look really complex, but the main thing that you've got to keep in mind is all it is this data. It's just these quads and these cylinders just stacked on top of one another, so I think the main thing I want to get across is even though this might look like it's really complicated, all this stuff. This looks terrifying spaghetti code, though I have tried to clean it up as much as possible. I'll just move that out the way. All of this stuff is still doing that same base component. It's just figuring out its vertexes, figuring out its triangles, figuring out its UVs and its vertex colors, and then it's passing that data through, so I would ... If you're interested in trying this stuff out, just take it one bite at a time, and you'll get through it. I promise, so next up I wanted to cover the materials, so for this, I'm heavily using the material instances feature, which is really useful for this kind of data, so I have my base tree type here, and this script basically represents every single material type that you've got here, so for absolutely everything, and it gives me quite a lot of power in what I can do, so I can choose whether this thing is masked or opaque. I can choose background and two-sided tinting, normal data, and most importantly getting some reasonably nice foliage wind for this particular object, so you can see I've got this little, wobbly, animated ball, and this is my base type, so when I'm going through and creating a new tree, the first thing that I do is create a new instance off of that kind of base parent, so this kind of base material, and then from that, all of my other kind of material types that I'm using inherit from that instance, right? So we have a hierarchy of instancing, and what that means is that I can share my wind data across all of my instance types without having to redo it every single time. So if I open this one up again, you can see I'm kind of setting the parameters, pardon me, for my leaf wind and my wind layer one and two. And this is all derived from a custom function that I've built called Tree Wind, which basically lets me kind of turn on and off these particular functions, so I've got some static switches, as well, which lets me control the particular strength of whether I use each of these layers. And then I set up these parameters on that kind of base-material instance, and then from there, I inherit from that, and you can see that this data, I'm not overriding with anything. It's just kind of being left as its original, and then all I'm doing is overriding my data, so I set my diffuse texture. I set my normal texture. I set my opacity mask texture, and then I override my material properties so that it's masked rather than opaque. It uses the two-side foliage model rather than the default lit, and it's listed at two-sided, as well, so I get it two-sided. And that way, even though I've got a really different material for both of these particular types, it's using the same base material parameter, and the way that that benefits it that I get that kind of propagated data, so that's all kind of really, really useful stuff for me as I'm kind of going through. So the wind itself is again quite a simple thing. I'm just using world position offset. It's not doing any of the kind of smart Pivot Painter data that's one some of the other examples, so if we kind of open that up, I can show you that material, just open up that tree base and open up tree wind. You can see that it's just feeding straight into world position and offset, and I'll start with wind layer one. So I have the texture sample here, which is just some kind of simple turbulence, and that's in world space, and it pans, so that gives me some kind of nice kind of cheap noise that's kind of moving through the world, and what's also nice about this is because it's world space, when I place my trees around the world, it'll have that kind of unified wind movement that kind of moves through it. That gets multiplied by a wind-direction parameter, which is basically giving me a vector direction, and then that kind of gets multiplied by the alpha, which lets me control the strength of that particular value. And then that gets multiplied with a power of to kind of give me some control of the fall off by the vertex colors green channel. And then inside my blue channel, that's my random variation. I have kind of an offset to that, as well, and that gets multiplied in. Now my finally parameter here is the red channel, and that was that gradient that you saw, and what I'm doing here is I'm kind of using that red channel to control the fall off of the wind, so at the kind of the base trunk, I don't want any wind movement at all, right, because the base of the trunk shouldn't really ever be moving unless it's been uprooted, which we're not accounting for in this. So I use that gradient that I have created for the tree to control the strength of the wind over time, and then I use the green channel and the blue channel to allow me to control the turbulence that we're going through here. So you can see my kind of leaf-wind layer one and two. That's using that red gradient to control the strength, and then as I move to leaf wind, I'm accounting in for some extra turbulence, which uses that kind of green gradient. So if we go back onto here and just do the color preview, you can see that gradient again, so we have that black to red, which gives me kind of the base wind control, and you can see that some of these things are just rendered in black, and that's because I don't want any of that kind of wind movement on it at all to start with, so these little kind of bark-peel meshes are rendering in black so that they don't kind of animate. Then that green channel is controlling the leaf, so you can see that's kind of where this comes in here. We have that kind of leaf-wind property, which we can control. And then we have our blue channel, which gives us that random variation, and you can see that's kind of coming in here, and that's what gives each kind of leaf instance or leaf-mesh instance its own turbulence, so you can get some nice variation there so it's not kind of repeating every single time you have it. So you can kind of see on that one. You get that nice kind of variation, so it doesn't look like every single leaf is moving in tandem. It looks like they're each being impacted by their own turbulence. Now, this is reasonably nice, but as I said, it's not the same as Pivot Painter, so you don't get the advantages of Pivot Painter, which is that kind of individual movement. That is something I'm working on, and if you're interested in checking that particular element out, you can go to the root Blueprint tool where I'm kind of working on that particular type. So this script is basically running through and grabbing all of that stored data that I'm building as I build each of my components, and then it builds a Pivot Paint texture, which I've got an example of in here, so if we just zoom in to this little texture here. This builds a 16-bit location for my pivot points, and then this forward vector builds a vector position, so in theory, I should be able to render out these textures and use them to generate the Pivot Paint material data. But as I said, I'm still working on getting that one working, so it's going to take a little while. VICTOR: You've come a pretty long way, though. I did find your article from 80.lv. I should share that, as well, if you're interested. ARRAN: Yeah. So go on. VICTOR: I was going to say, if anyone is interested in being able to share this in a little bit more concise form, there's also an article that Arran wrote for 80.lv. I'll go ahead and paste that. ARRAN: Yeah. The article covers all of this stuff, right, and it covers it in a way where you can probably digest it a little bit more easily. It kind of goes through each of these steps, so same as kind of building that triangle, quad, cylinder and cone, and then it kind of goes on to explain how some of this stuff works, as well, so you can kind of go through and build that stuff yourself. And, yeah, that's kind of the big stuff. I'm happy to go through some other bits again. I realize we kind of ran through that particular stuff, so we can re-cover some bits if there's any confusion, and I can answer some more questions. VICTOR: flowerhat had asked, "It was mentioned turning these into static meshes. Do you have to export them first and reimport? Also, do they keep all the vertex data that you'd shown earlier?" Perhaps could you show the export workflow? ARRAN: Yeah, absolutely, so that's a great question. So the root, which is why the Blueprint is called Root, of each of these trees, I have kind of a base component, and what you do in here is you specify the components that you want it to build, so here I'm specifying kind of the trunk and the palm bark and fronds that are coming off of that. And then you press the collate and build button, and what what will do is it will build a single-mesh version, so it takes all of these individual components, gets all of the data for them, and then it rebuilds all of that data into a single set and optimizes it. So I kind of had envisioned that there might be multiple instances where you'd use the same material, and I wanted to make sure that that would still work, so even though I've got two separate components here ... So let's just turn on these. So these two components are both different, but they use the same material, right, so they need to be collated into the same instance. So in order to fix that, I have to go through each one, check to see if the materials are the same or different, and then I can build a different index. So once you've pressed that collate and build button, we've got our single Static Mesh, and then you can click on the Procedural Mesh Component and press create Static Mesh, specify your location. So I'm just going to drag this to my content folder, example_live, and then you press okay, and that's it. It's done it. VICTOR: And that's just the built-in function in the Procedural Mesh Component itself, right? That wasn't anything custom that you implemented? ARRAN: Yeah. No, I haven't done anything to make that happen. That's all done inside the script, and all of that data is shared, so you can see all of my vertex colors information is preserved. I get some super funky trees from that. VICTOR: There you go, ship it. It's done. ARRAN: And then you can do whatever you want with it, right, because it's just another Static Mesh. This is now a UAsset, so like Victor said, I can tell it to generate lots, if I want to, so I can tell it to do some custom or generate it some other way. I can change these materials if I want to. I can drag it into the scene. I can drag lots of them into the scene, and there's no performance issues with this at any point right now because these are just normal meshes just like anything else. VICTOR: You can pop them into the foliage tool painter and ... ARRAN: Yeah, absolutely. So we can go into the foliage tool, just drop them in and then paint them out. VICTOR: As you can see, though, it runs just fine. ARRAN: Yeah. Once you've kind of got it out, it's just another Static Mesh, right? So it's not having to calculate anything live or at any point. It's just another mesh, just like any other. VICTOR: Marc_J asked, "Could this be used with Quixel Megascans to make your own tree assets?" ARRAN: So yes, absolutely. I would add some caveats into that though that this is more aimed for kind of stylized foliage generation, and the reason that it is that is because it can't support, or it gets very slow very quickly if you're dealing with very dense geometry, so very complex geometry, so the Quixel assets tend to be very, very high detail, which means they're super high-quality, but if you kind of took the leaf examples that they have in there and used that to build your own tree, then you would probably find that you'd run into some performance issues quite quickly if you were doing it that way. So that's why this is kind of more intended as more of a stylized tool where the geometry count can be kept kind of relatively low. That being said, the materials, you could apply them to any of these assets. It's just because you're just making another material, but in terms of actually generating kind of more realistic assets, this is probably not the best way to go, and actually, you probably wouldn't want to build these in this way anyway because it's just using randomized data in order to get it to kind of look right, whereas if you wanted to build really realistic trees, you probably want to do some kind of simulation where you're getting the kind of slightly more accurate result. VICTOR: You could still use some of the textures and mixer to sort of stylize the textures. ARRAN: Yeah. All the materials would be absolutely fine because again the complexity doesn't come from the material with this particular thing, right? I could swap this material out with anything, so if I had a realistic palm frond or even a stylized one that was built in Quixel Mixer, I'd just apply that just like I'd apply anything else in the world. VICTOR: Nice. Well, since that was sort of the end of your presentation, we haven't gotten too many more questions in chat. We have a little bit more time, so if you have any other questions for Arran, please let us know. But until then, is there anything else in sort of the evangelism world that you want to share with the audience? ARRAN: Sure. So on the evangelism side, we're kind of scattered all over the world, and we're here to kind of build cool content that kind of shows off what you can do in the engine but also to help developers kind of with their projects that they're currently working on and just kind of helping them navigate the Epic ecosystem and help them out in any way we can. So if you're not in contact with your local evangelist, then I would recommend you do so. If you're an indie developer and you're working on a game or you're working on a cool project, you should get in touch with either me if you're in the UK and Ireland or with all the other evangelists that we have over there. If you go to the Unreal Indies section, we actually have a list of all of the evangelists who are kind of operating and where they're operating, and you can e-mail the Indie Evangelism e-mail address, as well, and basically say, "I'm in this region. Who can I talk to?" And you'll get hooked up with the right person. We're really useful people to know a lot of the time. We almost all have very techy backgrounds, whether that's on the art side or whether that's on the code side, so we can often help not just with that kind of ecosystem navigation but also with any kind of techy, dev question, so if you're kind of banging your head against a particular thing and you want to talk to someone, then you can talk to us, and we'll try our best to help you out. VICTOR: Yeah, and that also comes especially when it gets time to ship your game. There are things that you might not have come across until that point sort of in terms of finding a publisher, all kinds of questions in terms of royalty, which at this point is fairly easy if you're a small indie studio because you need to make up to $1 million before you owe Epic any money. But even then, there might be questions, and we want to help you making sure that you can ship your games, not only develop them but also ship them. That's an important step for all of us, and so the evangelists are a great resource that you can reach out to in terms of those questions and just awesome people in general. I know I've had a few of you here on the livestream, and I hope there will be more of you to come. I know I have one planned with Sjoerd in a couple of months. ARRAN: Oh, that's going to be a good one, I think. VICTOR: Yes, it is going to be a good one. No spoilers. Anyway, let's see here. ARRAN: I'm just going to zoom in on my mushrooms. VICTOR: Well, I didn't actually see them. They're fairly new to the project, right? ARRAN: So they're not actually in the downloadable sample. I need to update it so that they get added there, but it's one of the benefits of just using a mesh, right, is that I can throw any mesh I want in there, so I built just a little mushroom in Blender and then threw that in, and then I did a little bit of scattering underneath, so these are kind of two separate components, so I can kind of exclude them, move them away if I don't want them, and then these get kind of scattered onto that mesh. I'm working on a few extra bits, actually, so this is probably worth mentioning. VICTOR: Yeah, show us. ARRAN: The leaf tool, I'm also working on a scatter tool, as well, so this kind of tree is actually built using not the leaf component but the scatter component, so the leaf component is used here, which generates a shape, and I'll just get rid of this material so you can kind of see it a bit better. Ooh. It's having a think. VICTOR: Oh. Having a think. ARRAN: There we go. So this is using kind of these little meshes here, which I wouldn't actually include in the build, but I just use them to create volume and shape, which I then use to scatter these cards over it. And then these cards have got some different properties on them, so I've got kind of my base input going in here, and then I can specify how many I want, so I'm scattering 1,000 cards across all of these leaves, and I can change kind of the world axis, as well, so if I want this to be a specific axis only, I can switch that out, see what it does there. Or I can change it to just be local and let that build. VICTOR: Speaking of ... ARRAN: So it's using all the same kind of base stuff. It's just using some extra properties to kind of build some stuff, so I'm kind of tinkering away at different bits and pieces to try and make this a bit more useful to more people. VICTOR: Not bits and bobs? ARRAN: Bits and bobs, as well. VICTOR: All right then. Speaking of the sample, flowerhat is asking, "I was able to get the project file of Trello, but how do I get it into engine?" Could you walk through just real quick how to use the project file that is available for download? ARRAN: Yeah, sure. So all you need to do is make a folder in your project. I can do it over here, tree_gen_demo, and this one is actually nested a few times by accident because I kept on unzipping it into it, so you only need to this once, but you make a folder called plugins inside whatever project you want to put this in, and if you want to it into the engine, then you can put it into the engine plugins folder, as well. And you basically just export the .zip file into this folder, and so it'll go to there. And then you get your tree_gen folder, and then inside your plugins, you just need to enable it, and you might need to restart it, though you shouldn't have to in theory, but you might need to restart it. And then once you've done that, inside your content folder, you'll get a plugin folder called tree_gen_content. You might need to enable your show plugin content for that to work, and sometimes you also need enable show engine content for it to work, as well, so if it's still not showing up, turn that one on, as well, and see if that works. And then inside tree_gen_content, we've got the example map, which is this map here which has all of the kind of examples that you can use to kind of start picking up the tool. Inside example, I've got all of the kind of the static meshes that you can use, all the kind of textures and meshes that I've built that you're free to use however you like. And then inside the components, that has all of the Blueprints to kind of get all of this, that kind of consist of all these bits, so the tree parent has the kind of base Blueprint type that all of these things are instanced off, and then you've got branch, leaf and trunk, which are kind of the Blueprints that we've already covered. You won't have scatter in there yet because that's not been uploaded because I'm still working on it. And then all you need to do when you want to start building your own tool is, you just drag and drop this root Blueprint type into whatever project you're working on, so you won't have anything show up straightaway, but you do get these buttons when you click on it, so you can then add a trunk, and that will give you this trunk that you can then start working from, so you can kind of start building this up, and you can kind of scale up and down as you want to, as well. So you can kind of start building these cool things. And then off of that, you can then build a branch, and you'll then get branches, as well, so you can kind of see these branches have spawned here. And then you've got all the different properties for that, as well, so you've got how many branches you want to spawn, whether that's eight or three or two or however many, and then you can control all of the parameters for these particular ones, so a nice, simple one to get started is rotation per index. I always recommend setting that to 137. That should be the basic number, and that will give you nice rotation around your branch, and then you can also do your rotation along parent, as well, so this will ... Sorry, let's not do that. Let's do some minus 60, and then I'll set my range up, as well. So that lets you kind of control how these branches are spawning and the angle that they spawn at. Let's see if we do some 0.9. Okay? So you can see we get these nice branches, and then we can increase the length of them. Let's increase that a bit more, something like that, and then what else can we do? If I increase my number of length segments, we can add some curl to it, as well, so if I start putting some numbers into these curl values, you can get some kind of interesting shapes and patterns appearing. VICTOR: So I think it's worth perhaps clarifying that it is a content plugin and not necessarily a project that is available on the Trello for download. ARRAN: Yeah. It's just the plugin file, and the plugin file will give you all of this content. So you can add it onto whatever project you're currently working on. It's just a plugin, and then build your foliage as you need. VICTOR: That's super neat. That's a really nice way to share assets like this because it is just like you said. You can just use the plugin inside your project. You don't actually have to merge or migrate or do any other form of asset migration to take assets from one project into another. ARRAN: Mm-hmm. Yeah, and if you put that plugin into the engine folder, it will just be there for every project that you have that uses that particular engine version, as well, so that's really nice if you just have anything like this where you might want to use it across multiple projects. You can just have the plugin work, and anything you add to that plugin, it will again propagate to all of your versions, so it's quite useful for that. Created a bit of a monstrosity here. VICTOR: Works for me. There you go. ARRAN: That's [INAUDIBLE]. Call it a tree. There we go. Done. VICTOR: Ship it. Let's go ahead and go through the two last questions, and then we'll wrap up the stream. BobsDefinitelyNotYourUncle asked, "How far can you see this tool going in the future? How far will we be able to push it in creating even more procedurally driven scenes?" ARRAN: So this tool was created as just a bit of an experimentation for me. I was really interested to see what kind of procedural content I could build, so in terms of updating it, this is definitely a pet project of mine. It's not an official Unreal project that's going to be shipping with engine versions or anything like that. It's just a bit of fun. That being said, I'm going to try and keep working on it and keep adding to it, so if you've got any kind of feature requests or anything you'd like to see or if you want to do some work on it as well and add to it, then that would be really cool. I might push this to Git and make it public just so people can sync it and makes changes and things like that, so, yeah, it's a personal project, but it's a useful one if you want to learn the Procedural Component and kind of pick up that kind of stuff. VICTOR: BobsDefinitelyNotYourUncle asked another question: "Could you use this tool to benefit early block out of level in some way, perhaps in order to create more varied, dynamic block outs?" ARRAN: Yeah, absolutely. Again, you could even use it as a way of just quickly making the right-sized placeholder meshes, and it would work fine for that. It is literally just a way of generating these kind of stacked meshes more quickly, so yeah. VICTOR: And with that, we are going to wrap up the stream, but not just yet because I have my little spiel that I go through at the end of every stream, and, Arran, you're going to have to sit through it just like all my previous guests before us. ARRAN: Yay. VICTOR: If you're watching from the beginning of the stream, thank you so much for hanging out today. We hope that you've learned something, even perhaps you knew almost everything, but perhaps you learned something. If you are new to Unreal Engine and you would like to get started in game development, go ahead and go to www.unrealengine.com, and you can download the Epic Games Launcher, and from the Launcher, you can download the latest version of Unreal Engine, and there are plenty. I should remember these stats, but I think there are 160 hours of content on Unreal Online Learning. On Unreal Online Learning, you can find courses related to different aspects of developing games and other things in Unreal Engine. You can go ahead and sign up and then start teaching yourself through the help of our instructors of how to became proficient at using Unreal Engine. And oh, look at us, now there's two of us in the stream room, but I do know that Arran wants to see me while I'm just sitting here talking. No, no, no, you're good. You're good. You're good. I can just go ahead and close your stream down if I'm able to, apparently not. Stop watching, there it is right there. Apparently, that doesn't work. Anyway, it will have to be doubled. We don't have any in-person meetups going on in the world right now because of the pandemic, but that doesn't mean that the meet-up groups are not active. If you go ahead and go to communities.unrealengine.com, you can see if there's a meet-up group close to you in your area, and some of them are throwing virtual events on Discord, which is nice to join, get an opportunity to talk to fellow devs potentially in your area, see what they're working on. Some of them even let you do your own presentation. At least, that's what we used to do back in Seattle. If you do not have a meetup group close to your area, you can go ahead and-- blah blah blah... refuse to talk now. You can go ahead and hit the Become a Leader button, and with that, you will fill out a form that goes to us, and we will check it out and then potentially help you spin up a meetup group in your area. We all hope that this is going to be over, and then we can all go back into seeing each other in-person and talk about these amazing things face-to-face rather than virtually like this. Perhaps we'll even be back in the livestream studio one day. That would be nice. If you have seen us from the beginning, we do a community spotlight as well as our countdown. These are assets that we find around the community, but you can also go ahead and add us on our forums, on Twitter, Discord, unrealslackers.org, great Discord community. If you are new to the community and you would like to talk to more devs little bit more broadly, globally other than specific to the virtual community groups. The community-- Sorry. The countdown video specifically is 30 minutes of development. Fast-forward that into 5 minutes and send that to us together with your logo, and you might go ahead and be featured at the beginning of our livestreams. If you stream on Twitch, make sure that you use the Unreal Engine tag as well as the game development tag. That is the best way to showcase your content for people who are interested in seeing specifically Unreal Engine development on Twitch. That's what we do. You can see the tag down here below if you're watching this on Twitch. If you're not watching this on Twitch, you are probably seeing this on YouTube. If you do, make sure you hit that notification bell so that you can see all of the latest updates that come from the Unreal Engine channel. We not only do these livestreams, but there are also plenty of virtual events that are all now being put on YouTube, the last one being Unreal Build: Virtual Production, very exciting if you haven't seen that yet. Make sure you follow us on social media, and next week, we do not have a stream because we are observing Thanksgiving here in the US, but the week after, Arran, what's happening the week after? ARRAN: We're going to be doing some stuff on accessibility, so all of the cool engine built-in tools that you can use to make your game more accessible we're going to be covering along with some extra theory on how you can kind of build some content or change your game content so that you can make it more accessible for more people. VICTOR: And who's going to present this? ARRAN: It's going to be me. VICTOR: Yeah, damn right it is. ARRAN: You're stuck with me. VICTOR: Awesome, and with that, Arran, thank you so much for coming out today, showing off your procedural tree generation tool. If you want to know more about the Procedural Mesh Component, you can go ahead and go to our documentation. I also believe there are quite a few community tutorials or tutorials made by the community around, so you can go to YouTube and search for some of that. With that said, thanks to all of you for watching today. I hope you have a good rest of your week and rest throughout the weekend, and then we will see you again in 2 weeks. Take care, everyone.
Info
Channel: Unreal Engine
Views: 75,312
Rating: undefined out of 5
Keywords: Unreal Engine, Epic Games, UE4, Unreal, Game Engine, Game Dev, Game Development
Id: 1ksgB6hYGrE
Channel Id: undefined
Length: 84min 33sec (5073 seconds)
Published: Sat Nov 21 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.