Demystifying Soft Object References | Inside Unreal

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
>>Amanda: Hello everyone! If you haven’t yet, take your first look at Unreal Engine 5! In the new demo, see two new core technologies: Lumen, a fully dynamic global illumination solution that immediately reacts to scene and light changes, and Nanite virtualized micropolygon geometry, which empowers you to directly import film-quality source art comprising hundreds of millions or billions of polygons into Unreal Engine—and it just works. Unreal Engine 5 will be available for preview in early 2021—watch the full demo with commentary from Epic’s Technical Director of Graphics, Brian Karis, and Special Projects Art Director, Jerome Platteaux. And we hope you’re ready for more big news—starting today you can download and use Unreal Engine to build games for free as you always have, except now royalties are waived on your first $1 million in gross revenue, retroactive to January 1. Head over to the unrealengine.com blog for all the details! We are also thrilled to announce that Epic Online Services are now available to all developers across PlayStation, Xbox, Nintendo Switch, PC, and Mac, with support coming soon to iOS and Android. From player identity and friends, cross-play, and achievements, these services empower you to create the best experiences for players with complete freedom of engine, store, and platform integration choice. Want to see what Epic Online Services can do for your game? Head over to the Developer Portal to download the SDK and get started today. With a near five-star user rating, Lies Beneath is one of the most highly-rated VR games designed for the Oculus Quest. The title exemplifies how a AAA quality experience can be tailor-made for Oculus’ mobile VR headset. The game was developed by VR veteran studio Drifter, the studio behind Gunheart and Robo Recall: Unplugged for the Oculus Quest. Read our interview with Drifter’s team to discover their inspirations and how they executed on the game’s stylized comic-book aesthetic. In a new hands-on presentation, Epic's Sjoerd De Jong breaks down how to render a beautiful and fully dynamic sky utilizing the robust Sky Atmosphere system that’s now available in Unreal Engine 4.25, with the added help of Quixel Megascans. Check out his full presentation on our blog, then learn more about Quixel’s mission and the future of the Sky Atmosphere system in a short video from Quixel Director, Teddy Bergsman, and Epic Games' Senior Rendering Programmer, Sebastien Hillaire. Thanks to this week’s top karma earners, doing a lovely job helping others on AnswerHub: ClockworkOcean, Everynone, Xyah_, Detach789, T_Sumisaki, BamaGame, QUANDINI, EvilCleric, mrteuy, and GoldenYoann3D, Heading over to our community spotlights, here you see THE INVITATION, a PvX MMO shooter about the joy of adventure, tough decision making, and harsh consequences. In the Invitation, the players and the environment dynamically create quests. Find out more about The Invitation on their website. Storyteller, VFX artist, and animator Samuel Walsh began learning Unreal Engine to explore new ways of telling stories. Dogfight was designed to tell a story in the most filmic way possible, not focusing on realistic movement, but on composition. Go behind the scenes of Dogfight and learn more about the project on Walsh’s website. After four years of development, Nifty Llama Games revealed "Ruth's Journey," a preview of their upcoming interactive story game, The Long Way Home. Set in the same universe, Ruth’s Journey follows Ruth as she sets out to photograph the rare Golden Finch. Watch the full trailer at niftyllamagames.com. Thanks for watching our News and Community Spotlight! >>Victor: Hi, everyone, and welcome to Inside Unreal, a weekly show where we learn, explore, and celebrate everything Unreal. I'm your host, Victor Brodin and my guest today is our Evangelist, Christian Allen. >>Christian: Hello, hello! >>Victor: Thanks for coming on the show. We are going to cover, or demystify, soft object references today. But I did want it to take just a little moment to talk about the announce of Unreal Engine 5. Difficult not to be excited and to mention it. As you saw as part of the news, there is plenty of information available online. If you have not yet checked out the Lumen in the Land of Nanite tech demo that's running on a Playstation 5, you definitely should go and do that. But for Indies, I think one of the bigger announcements that we made is that we are now waiving the royalty fee for the first million dollars that your game makes. How do you think this is going to change how indies approach the use of the Engine, as well as shipping their games? >>Christian: Well, I hope it's going to be a game changer. My focus at Epic is on Indies in North America. And so, I interact with them a lot. And previously, we've waived the first $12,000 a year before we started calculating royalties. And now with this move from that $12,000 a year to a million dollars for the entire lifecycle of the product, ideally what it's going to do is just allow Indies to do what we want them to do is really focus on the game. So they're not worried about royalties and calculating that in the first few months as projects come out. They can just really focus on their product, and their customers, and the quality level. And then once they start generating significant revenue for themselves, then we can talk about collecting royalties. So I think it really just reinforces our company wide goals across Epic, both for Unreal Engine and our other services, to try to get this content and these tools distributed as broadly as possible and try to lower as many barriers as we can to allow new content. And that content is king, so that's what we want to focus on. >>Victor: Yeah. Empower everyone to be able to be as creative as possible and then worry about the financial details later. >>Christian: Yeah, exactly. >>Victor: If you get there. >>Christian: Yeah, exactly. And again, just taking that off the table with developers, we started-- we've gone through a lot of permutations of royalties. We had fee structures over the years and we've just found that just allowing developers to focus on development first, not worry about having different tiers of subscriptions and things like that when it comes to the technology. If your game is hugely successful, then awesome. That's where we want you to be because we are royalty-based. That allows us to share in the success. And really, the thing I like about it as Evangelist is it really helps to align our goals. While I'm helping a developer, I don't have to worry about well let me check and see if there are a silver member or a gold member. Let me-- oh, you just launched your game a month ago. Let me make sure and check it that you've paid royalties until I can help you. It just aligns everybody together. So, again, focusing on high quality content, good content and gameplay for the consumer because that's what's going to help make the product successful. And so, it aligns our business goals with all our other goals, too. >>Victor: I also want to make sure if you haven't noticed that or in case you just joined and you missed the intro, we just did a huge public release of Epic Online Services, which will allow you to-- and it's just to mention that it is completely free, which is just huge. It's like a whole back end of online services that you're now able to use for your game. And that's going to empower a lot more developers to implement what previously could have been a rather expensive or a rather difficult thing. Any comments on EOS? >>Christian: Yeah. I mean, the big thing about EOS, Epic Online Services, is that one, it is free which is kind of a running theme. But the big thing about it is it's engine agnostic. So obviously, we want Unreal Engine developers to check it out. But regardless what kind of core technology you're using, you should look into it. I mean, one of the big focuses on it is to break down the walls in the garden, to open it up to things like cross-play. Obviously, cross-play we feel is hugely important as you've seen with the development of Fortnite, to allow developers to have that access to online services that aren't specific to the platform that they're launching on and aren't specific to a certain storefront, whether it be Epic Game Store or other stores. Again, give that power to the developers. So it is a standalone SDK compatible with major engines. So regardless of whether using Unreal, I encourage you to go check it out. And we're going to be continuing to launch additional services with that. Additional support. There'll be roadmaps published of those as they come online, as well. >>Victor: There's a lot more to come. This is just the initial announcement. And as we work our way towards release, there will be a lot more to come. And on that topic, I'd like to mention that tomorrow if you have more technical details regarding the technology that we announced yesterday, there will be tech talks released on YouTube. Two of them, specifically. And so, make sure you tune into our social media channels and you can see when they are live. Moving on, we are also-- we will of course be covering UE5 on the livestreams in the future. So stay tuned for that, as well. Moving on, I think it's time to get onto to today's topic. >>Christian: Yes! Exciting times. The exciting stuff that everybody wants to talk about, besides Unreal 5 and Epic Online Services. >>Victor: Memory management! >>Christian: Memory management! Hard object loading and soft object references. >>Victor: Well, it's a good topic to cover because it's something that affects pretty much every single game and something that you should always keep in mind from the moment you start. And the more practice you get to do this workflow, the easier it's going to get for you to spend less time in the end refactoring and looking at some of the problems that you have. >>Christian: Yes, definitely. And it's something that has come up a lot. As an Evangelist, I travel around to our various Unreal Engine meetups that are community run groups all around North America. And obviously, there are other Evangelists around the world. And when I'm doing my presentations of the various demos that I've done, I've referenced this every once in a while. And every time I bring it up, a lot of hands shoot in the air. And a lot of people start asking questions because it's not a super complicated concept, but I think there's just a lot of misconceptions. And it's not necessarily readily apparent, especially when you're just getting started and you're using a lot of the default settings and just rolling forward. And generally, it doesn't become an issue or a problem until one, you get very far along in development and you've got a lot of content or you're trying to optimize for a platform, such as mobile or low end PC where users might have not as much memory available. Memory management can be a relatively complicated aspect. But as a game designer, which is my specialty, game design and Blueprint scripting, there are a lot of things in the planning phase as you're setting up your Blueprints and structuring your objects. And so, I've got some just simple tips and tricks to get started with that today. >>Victor: Awesome. Well, let's get started. >>Christian: Cool. Cool. So I'll just jump and talk a little bit before I get into the demonstration. I actually made a video version of what I'm showing today that I released a couple of weeks ago. And the popularity and the response to it is really, I think, what got you to invite me here today. >>Victor: Sure was. >>Christian: So that's really good. The general idea is that when you think about memory management and object oriented design, you're thinking about controlling when and where you are loading objects into memory. And really, in Blueprints specifically where that comes down to is hard objects references and soft object references. And the key concept to get your head around that is essentially, a hard object reference is you're essentially attaching the object to your Blueprint. So when you have a hard object reference, that Uobject, that actor or whatever it may be is going to be attached to the Blueprint. And then, it's going to be loaded into memory whenever the Blueprint is accessed, whenever the Blueprint is loaded. And that's a hierarchical cascading effect. So if you have a hard object reference in a Blueprint, you open that Blueprint, that's going to open the Blueprint of that hard object reference. If that object also has additional references, those are going to be loaded and so on, and so on, and so on. So you can see the cascading effect. A soft object reference is basically-- I like to think about it as the web. A soft object reference is essentially a web link to the object on the user's hard drive or on your hard drive. And so, it's storing the location of that object and then, you're going to control when it is actually loaded into memory. So that's the way to think about it. When it's a soft object reference, it's just sitting there on your hard drive until you reach out and tell the game or the Engine to actually load it up. So the demonstration, I'm going to go and share my screen. So the demonstration I've got here is a very simple project that I built. This is just-- >>Victor: One second, Christian. >>Christian: OK. >>Victor: I have a little delay in OBS here. Just went completely black. Trying to figure out what happened there. >>Christian: It's live, baby. >>Victor: It is live. All right. We're good. >>Christian: OK, cool. So what I have here is just a very simple project that's set up. We've got a scene just with some static-- some various different mesh objects in the background. But the key for this demonstrator is this Blueprint object that I have represented by the Shinbi skeletal mesh, obviously available for free on our Marketplace. And so, I've got a very basic Blueprint that contains two references to skeletal meshes. One is the one that you see here, the default skeletal mesh of Shinbi and another is a variant of her skeletal mesh with the different materials set. And what I'd like to do to demonstrate this is a fresh version of the editor that I've opened. And I'm going to use a console command to show my object list. This is console command is object list class. And in this example, I'm just using skeletal mesh. Object list class basically displays all of that type of class that you have loaded into memory or open in this scene at any one time. So you can see, if I span this upward, down at the bottom here you can see that basically, it's showing that I have one skeletal mesh in memory. And that's the Shinbi.Shinbi object. It shows memory usage, things like that. Obviously in a larger project, this list is going to be much bigger. But for this example, I just have the one. Now something to consider when you're looking at this is that this is going to display anything that the editor currently has loaded into memory. So if I go and go into my content directory and start opening up a bunch of different skeletal meshes out of the content directory, the editor is going to load those into memory. And if I then run that console command, it's going to show all of those objects. So generally when you want to test this, you either want to be in a fresh version of the editor that you've just opened up, that you're not opening up of various bunch of things, or you want to run these tests in a cooked build. There are various different console commands that you can use to display memory dumps. You can do dumps [INAUDIBLE] the text and things like that. There's lots of information about that online. So I'll jump over to the actual Blueprint here and talk a little bit about what I've got going on. So when I say hard object reference and soft object reference, essentially in your variable in your component. So here's the components that I have. Basically again, super simple. Up on the upper left, it's basically just this skeletal mesh. It's a skeletal mesh component. And on the right, you can see that it's set to the one that's being displayed. So that is, by default, that component and that reference is a hard reference. That means every time this Blueprint is accessed, that's going to be loaded into memory. Obviously, it needs to be loaded into memory because it's displaying it here and it's going to be displaying it in the game. And then in our components, we've got variables. And if I go down over here, I've got another variable reference to a different skeletal mesh. This is this Shinbi Dynasty skeletal mesh. The difference here between these two is that one is a hard object reference and one is a soft object reference. And if you see if you mouse over it, I'm showing that it's a skeletal mesh soft object reference. And the way that you control that-- the basic way you control it is when you create a variable-- I'll create a new one here. I'll just call it dummy variable. And I'm just going to move my Zoom display, which is in the way. OK. And I go over to variable type in the upper right. Move that a little bit more. And I'll bring up skeletal mesh. And so, sometimes it gets a little hard to see because the pop-ups are jumping up and giving me the information, but we've got the different reference here. So we've got object reference, class reference, soft object reference, and soft class reference. By default, everything's going to be an object reference. Again, that's a hard reference. Generally, it just says object reference. That's defaulting to being a hard reference. Same with the class reference. That's going to be a hard reference that's going to load that class into memory. Now these selections down here are the soft object references. So basically when you create a variable, the basic easy way to do this is just you click onto soft object reference. When I compile it, now it's a soft object reference. So you interact in this phase with everything almost exactly the same. You can go through your content browser. You can choose various different selections. However you want to do it. And so, that's how you do the basic setup. Now because soft object references are essentially just web links to materials, there is a little bit of a difference in how you access them. The first thing that you're going to want to think about is how they're actually loaded into memory. And let me just move display again. So what I've got here is very simple-- in the event graph, a very simple Blueprint that's essentially loading the reference that I created earlier, the soft object reference of the other skeletal match. Pulling some information out of it-- i.e. the string, the name-- casting it and then setting it as a hard variable so that I can continue to interact with it beyond that point. So async load asset. Asynchronous loading nodes. This works both for loading individual asset or the one for an entire class is, I believe called async load class-- is essentially your way through Blueprints of loading the class up. And there's a few key terms. One, asynchronous. Asynchronous means that it loads the object asynchronously while the rest of the game simulation continues to run. So when you activate a async load, it's not going to pause everything and wait for you. It's just going to start loading it. And then when it's done, it'll be available. So you want to keep that in mind either having delays-- or you can use just the nodes right off of this. The completed node will only fire once the objects actually loaded into memory. Sometimes if you want to string right off, that's the best way to do it. Or if you have a bunch of assets that you want to load to stage things out, you can do your time control through that. It's kind of up to you. >>Victor: Something that's good to mention is that that timer indicates that that Blueprint function is an asynchronous function and that is across the board. If you see that timer, it means that the function is asynchronous. >>Christian: That's a great point. Yeah. I have these delays that I just put in. These delays aren't necessary to the actual functioning of this. They're just so that when I actually show the demonstration here in a minute, there's enough time for your brain to actually process what's happening because it'll run too fast. And you'll see they have that same pop-up just to let you know that that's running asynchronously. So that's a great point. So the next thing to think about or to get your brain wrapped around is that essentially because this is just a link to a location of an object, the Engine and the Blueprint don't actually know the data that's contained in it. It doesn't have all the information. That's one of the reasons why when you make a default, a hard object reference, the object is by default loaded into memory because the Engine is assuming that when you're placing a hard variable into your Blueprint that you're going to be referencing that, you're going to be using it for something. Either loading into memory and activating it or you're going to want to be pulling data out of it. So it needs to have all that information loaded. So the first thing that we need to do if we want to interact with it in this case once it's loaded into memory is actually cast to it as the class that it is. And so, what that's doing is telling the Engine hey, this link to this object is a skeletal mesh actor. And so, we're going to cast to it as a skeletal mesh actor. And then, that allows you to reference the various different things, whether it be materials, variables that you have, and public variables that you want to interact with. So once this is loaded into memory, I'm casting to it as a skeletal mash. I have another delay built in again. That's just for viewing after the print string is delayed. And then, I set the actual skeletal mesh component to that new skeletal mash that I have loaded into memory. After that, I am actually setting it to a hard variable. So I have an empty variable that I've created here. You can see nothing's referenced in here. And now, I'm actually setting it to that variable. So after this is done, if I want to reference that variable like I normally would, I can just go out and start referencing it and interacting with it. So once you do that, then later on in your Blueprints you can just treat them however you would a normal variable. You don't actually have to worry about it at that point. Another thing I get asked usually about this point in the presentation is about unloading the assets. Well, here's how. I've showed you how to manually load the assets in a memory. What about unloading them? There's not a Blueprint node to manually unload the objects. Once they're loaded into memory, they're going to be treated like any other Uobject. So once the actor is destroyed and it's no longer referenced by anything else, then your garbage collection will come and remove it out of memory when that's appropriate. So once it's loaded into memory again, you can treat it like any other Uobject when it comes to memory management and garbage collection. >>Victor: We did have some questions about garbage collection and when it gets collected. Could you go into detail a little bit about when-- how would I go about it? When would garbage collection come in and actually nuke that from memory? >>Christian: Well, the memory manager is going to control that. I don't have a lot of specific details. You can force garbage collection. That is a Blueprint node. So if you know, for example, that you're going to be doing something very specific where maybe you want to stay in the same level, but you've had a bunch of objects that have just been destroyed. And you want to have a new set of objects. You can force garbage collection. Generally when you open up a new level, that's obviously a point where garbage collection is automatically going to happen. And also as the memory manager that runs in the background is keeping an eye on the memory and recognizing the things that garbage collection can be run. It's going to be handling that. Obviously, if you're getting into C++ there's a lot finer control on garbage collection. And there's a lot of documentation on that side of things on our documentation. So yes. Does that answer your question? >>Victor: Yeah. And then, I think to add to that I believe if you were to, say, destroy this Blueprint that was actually the Blueprint that loaded the soft object reference and then, you stored it in the empty skel mesh variable. If you were to destroy this Blueprint, that would eventually get garbage collected as well, right? And if you were to spot that again, you would have to asynchronously load the asset from the soft object reference again, right? >>Christian: Correct. Correct. Although, that does touch on one thing that I should talk about. And that's the hierarchical nature of Blueprints. And let me go ahead and show the demonstration and then, I can get into the class parts of things and the hierarchical part. So basically, I walk through the Blueprint. It's nice and simple. Essentially on begin play, you're going to see it waits a few seconds. Once the asset is actually loaded, it's going to pop up a string in the upper left and say hey, this has been loaded into memory. And then, there's going to be another delay and then you'll see the actual character swap over. So you'll see that I'm going to run this console command one more time. If I can click on the right button. So there's my skeletal-- the list of the skeleton meshes. Again, even though you saw me interacting with those variables, placing the variable, creating new ones. Even though I created that new skeletal mesh variable as a soft object reference, it's still not loaded into memory. So you can see it's still right there. Now when I hit play, you're going to see essentially what I described and then we'll come back and see what's loaded into memory after that. It's going to be a pretty exciting surprise. So here, we have the demonstration. On the upper left, you're going to see a text pop-up. There she is. She's loaded into memory. And then a few seconds later, she switches over to the Dynasty model. Whoops. I'll run that one more time. >>Victor: Get to see it again. >>Christian: Yeah, you can see it again. There it is loaded in memory and now it's popped up. You notice the second time it went a lot faster because it was already loaded into memory. So the only thing slowing that down was that actual delay. That's why I had to put it in because otherwise, it just happens like that. So now when I run that object console command, you'll see now boom. Now there's two. Pretty exciting stuff. So we have the Shinbi and Dynasty. So now again, the editor by default pretty much keeps most things loaded in the memory that it's ever had open because that's just-- it assumes that you're going to be working with that again. So again, something to consider. If I just keep adding objects and keep opening objects, this list is just going to grow, and grow, and grow while I'm in this editor session. So again, the easiest way when you're working doing tests like this would just be close the editor, reopen a fresh setting, and then start from there. So let's go back to the Blueprint while I'm talking about the hierarchical stuff. So again, where this really comes into play is both the amount of memory that you're taking up with various objects. And where you start to get into trouble is related to what you were talking about earlier about destroying this specific actor, this Blueprint, and then it not being loaded into memory. The thing that you have to remember is in object oriented design, everything is hierarchical. So if you create a base class of an actor with just a default skeletal mesh in it that then has say 10 materials and a bunch of textures and a bunch of various different things, and that's a dummy that you're never going to use. And then, you start creating child classes of that actor. So you start creating children and you start setting them to different skeletal meshes, which have their own set of materials, their own set of textures, things like that. Every time you load one of those children, that parent's going to be loaded as well because the child inherits things from that parent. It needs to have that in memory. So if you put a bunch of variable, bunch of content, into that parent and then start loading multiple different children, that just gets bigger and bigger and bigger and more and more objects. So even if you destroy the children, the parent might necessarily not be referenced. The other thing that people forget a lot is when it comes to things like casting. So I mentioned casting earlier that you need to cast the soft object reference. But a lot of people don't understand that when you cast to an object, you cast to a Blueprint, it also gets loaded into memory. Just because you're casting to it from one Blueprint, it's not only loading that very specific thing. It's loading the entire Blueprint into memory because it again, needs to have all that information to pull out whatever you're trying to reference. So again, thinking about things hierarchically, if I have that parent class, then I have all those children classes. And then that goes from there. And I cast to those. That whole chain is going to be loaded into memory. And where this comes into play when it comes to memory management is not just the total amount of memory you're using, which can affect things like load time. So if in your scene you've got a bunch of Blueprints that cast to other Blueprints that have a bunch of references themselves and you wonder why you're load times take a really long time, it's because the game's not actually doing that until you open the scene, until you open the level. So if you open the level, it has a bunch of Blueprints and referencing a bunch of other Blueprints, all that stuff has to be loaded into memory. So that's increasing your load time. So you can, of course then, you can use soft object references in and stage that loading ahead of time to smooth that out or just reduce all those references so that you're not having that giant load time. The other thing when it comes to performance is the memory manager is keeping track of those objects. It's clumping them together into different chunks of memory. And especially if you have a lot of little-- I'd say like small objects in the course of like thousands of various different small objects, those are constantly being arranged and clumped together to be the most efficient use of your memory. But that takes that takes performance in CPU to do that. That generally doesn't hurt you too bad. But again, if you start getting into thousands and thousands of these objects being constantly managed in the background, that can affect performance. So let's see. Lost my train of thought there. So one of the ways to reduce this overhead is when you're setting up your dummy objects, you can reference lower impact objects. One of the things that I do is when I'm setting up a lot of my classes, I'll use the mannequin. The Unreal mannequin for most of my skeletal mesh references as just the default. And if you're always using that one thing is a default and then you just budget in that OK, I'm going to use the mannequin or whatever default character you may have-- if you're always using those references then especially something that's just always going to be loaded in memory anyway, then you can reduce your overhead just right there. And then, you can use your soft object references to then load up the very specific information that you want to have. For example in ParaChess, which is the game demo that actually brought me to this, I had the entire set of Paragon characters from the Marketplace available in that game. And when I started out, it's a chess game. So there's only, I think, 14 possible characters on screen at once. And I had all that set up just using hard object references. And that was totally fine that with the scope of the game that I was making. All the characters were loaded up in front because it's chess. You don't get more characters as the game goes on. You get less characters. So performance just improves the longer you played. But as soon as I went in and said oh OK. Well, I'm going to have all of the Paragon characters as well as all of the variants, that's upwards of 70 AAA level characters loaded into memory at any one time. And so if I in my basic Blueprints had all of those characters and all of their variants listed as hard references default references, every single one of those is going to be loaded into memory when I open that up. Now eventually, if those aren't ever-- if I destroyed that actor and it wasn't used, then garbage collection would clean that up. But if I'm not actually using those, I don't want all 70 of those characters loaded into memory just to choose 14 of them to actually use for the game. That's just super inefficient for the player to sit to wait for all those to be loaded up. And then, I might run into memory management issues. So instead of that, what I did is just have all the characters listed as soft object references. And then as the game loads and the player actually chooses the set that they're going to have, that's when I actually asynchronous load them and continue on from there. And of course with clever management, you could maybe always load the default that they're going to have. And then as the players open up widgets and doing different things, you could start to asynchronously load the things that you think the player might possibly going to be choosing. So you can just make smart decisions around there. >>Victor: And we did do a stream on ParaChess earlier last year. >>Christian: Yes. Yes. And I'm still working on that, getting through the chess rules. But I did a lot of work. A lot of the actual delay in releasing ParaChess has been through going back. I didn't do it initially. I just ran with it and until I started getting into 70 plus characters at high resolution. That's when I started realizing-- especially when I said oh I'm going to make this on the Switch or on mobile. It's like oh, I really need to start thinking about memory management. And that's where thinking about this ahead of time and starting to plan out how organizing your content in smart and efficient ways really comes into play. The earlier you do it-- even if you don't think that you're going to have a lot of these objects in a year or two, it's a lot easier to set it up smart and efficiently in the beginning than it is when you're in beta testing and you have to go back and realize that hey, when I first set up the system for weapon pickups, I was only going to have 12 different weapons. But we decided to add weapon skins and the weapon skins-- >>Victor: That happens all the time. >>Christian: --now attached. So now, you had one weapon with one skin. Now, you have 10 skins per weapon. And now instead of 10 weapon skeletal meshes being loaded, you have a hundred. And then you add another variant. Now you have 1,000. And now you have 10,000. And so, thinking about that ahead of time and structuring it, doesn't take a lot of time in the beginning when you're setting things up. But when you haven't touched a Blueprint in six months and you're having to go back and go, OK, now I need to restructure everything to do asynchronous loading and think about how these are going to-- how these are going to affect the player. It can become a real hurdle. So setting up the object oriented hierarchy, separating Blueprints, looking into things like Blueprint interfaces. A lot of people choose to use Blueprint interfaces for this type of management. And a Blueprint interface is something that just contains variables that sit in alongside your Blueprint. Some people use other methods. I personally like the soft object references because I can basically treat them just like any other variable within my Blueprint. I can organize them within my Blueprint. I can have everything there on the variable viewer. I can organize them that way. So thinking about memory management ahead of time-- It's interesting, I was reading an article by a developer that was doing a VR development. And working on desktop, everything was fine until they got to actual testing with actual hardware. And they were having like seven minute load times. And when they said this doesn't make sense-- the levels are taking seven minutes to load, but the levels aren't that heavy. What's going on? And then, they opened up a blank empty space, started doing memory dumps. And here, they have 1,000-1,200 objects loaded in an empty scene and they're like what's going on. And then, they start digging in and it's like oh. It was the hard object reference. They've got class-- they passed to other classes. They've got references to ponds that that then have-- or characters that have things like pickups that are referenced. And then, if you think about an RPG where-- It's really easy like in a player character file to say, well, I'm just going to have the 5 classes of weapons inside the character. And then when the player walks over a weapon pick up, it's already there and I can reference it. It's great. But again, you start expanding that in it in an RPG and now, you've got thousands of combinations with dozens of different materials for each object. And it just exponentially explodes. >>Victor: I'll say it's difficult to manage at that point. And if you're already prepared for that, then you will have a little bit of an easier time getting there. Yeah, I'm glad you mentioned Blueprint interfaces because they're definitely a good way because they're agnostic. They don't care what kind of object that you're trying to call this function on. They just care if the interface has been implemented or not. And even if it hasn't been implemented, you won't get an error because it's just a call that you're doing. And if it's not there, it will be perfectly fine, but that's also something you do need to think of. It won't tell you if you haven't implemented it. So definitely need to think about it. Something else that I tend to do. We talked a little bit about this earlier, is that if it's possible for you-- if you're only looking to access a piece of data inside the Blueprint that you're talking to that exists in the base level of actor, you don't need to declare that variable as the specific class of object that you're trying to talk to to save a little bit of memory. Because if you just instead say you need to-- you need a reference to that actor to destroy it later or something. That destroy function already exists as the base class actor. And so therefore, you don't need-- and it's easy to do because you drag out like from the cast or something. And you promote to variable. And if it's aware of which class that is and it was just not a cast to an actor or something low level, then it will actually create a piece or declare a variable that is now that specific class. And so therefore, it will be loaded once to the initial actor is loaded. And so, keeping those things in mind can help you keep the costs down. And once they become-- once you get used to it, you don't think about it anymore and it's just part of your workflow. >>Christian: Yeah. And I think that brings up another point. And that's a great one is-- yeah. By saying I need to cast to this actor class that is five levels down from a base actor, it has to step through each one of those children or each one of those references. Load all that stuff in a memory just to do a simple destroy function. And so, if you're casting to it, especially if you built a lot of hierarchy in with a lot of different references-- but the other thing is if I pop back over to do share screen again, a lot of people don't-- they don't really get the idea that any reference in the Blueprint where you're telling the Blueprint you need to know this information, it's going to be loaded into memory. So it doesn't matter. Let me stop my simulation. It doesn't matter if it's an actual variable over here on your variable list or your components. It matters that it's referenced. So if I do spawn actor from class and then I do a dropdown of the actor class and pick one here, let's say here's a default one that I created. If this is sitting in your Blueprint, that class is going to be loaded into memory. It doesn't matter whether it's been spawned yet. That's loaded in memory now because the editor is assuming that if you've got this object in, when you spawn it you want it to spawn instantly. So in order for it to be spawned, it's already going to be loaded in memory. Otherwise, you would have to wait for it to load for it to actually spawn. So a way around this, or the way to not have this loaded into memory-- and that's fine if that's what you want to do. But this class, this reference, is going to be loaded into memory. So if I wanted to not do that, then what I could do is come back over here. Create a new dummy var. And then if I go into the variable type, change that over. I just use skeletal meshes just because I'm using two soft class reference. And now when I place that in and link that up, whoops. Oh, let's see because I am just doing an actor. Let's just change that back to actor. >>Victor: Yeah. The data types are context sensitive, which is really nice when you start out but can sometimes confuse you when you haven't done it right. >>Christian: Yeah, but it stops you from doing things that are wrong, which is great. So I'll do that drop down. Soft class reference. Change the variable type. So it's going to convert the soft object to a class. Now, what I would want to do is actually do async load class. And then, I could run off of that. So the key is that any time you've got a reference, whether it's a placed variable over here or just basically any kind of reference. I'm casting to it. Casting is a class. Again, if I cast like you mentioned-- if I cast as an actor or if I cast a skeleton mesh, I go down that hierarchy. That information and all those references ahead of that are going to be loaded into memory. >>Victor: That's great. Are you ready for a couple of questions? See if we can-- see if we can tackle them. >>Christian: Yeah. I think so. I'm sure I will be dumbfounded on a couple, but I will take it as far as I can. >>Victor: Well, it is a rather complex subject if you go all the way down to the low level of what's actually happening. And so, it can be tricky. Let's see. One of the main questions I'll repeat a few times. You might have tackled this, but maybe we can just dive into it. What happens when you tried loading a soft reference asset that's already loaded? >>Christian: That's a great question. Essentially, the async is just going to immediately complete. >>Victor: OK. >>Christian: So actually, you saw it on that second time I ran through a round. I didn't get any errors or anything. It just said loading complete because it's already loaded into memory. So except for a wasted call, which is super minimal, essentially you're not going to get any error messages or anything like that. The completed is just going to fire off immediately. >>Victor: And so, even if you for some reason, you had two different functions. They both individually need to reference something that you have a soft object reference to. You are not sure which of the functions will be called first, so they both need to implement the asynchronous loading function. If one of them has already executed and the other one gets called later, even if you have two separate paths of that asynchronous loading, it will know that it's already loaded and just immediately execute, yes? >>Christian: I believe so, yes. You should definitely double test it, double check it, in your project. But, yeah. I believe that's the functionality that I've seen. And the other thing to keep in mind just on that note is that completed node is the important part because the default execution pin is going to fire as soon as that block goes by. It's going to assume that you want to just keep going. And so for example, if you run, not off the completed, just on the default pin and then immediately try to cast to it and it's not loaded yet, your cast is going to fail because it's not loaded into memory. So if you're trying to do a race condition, you could also have logic to double check that your cast has failed and then continue to cast. But you're going to need to have that logic in, just like anytime you're dealing with a delay. Anything that's asynchronous, the time management is really on your shoulders. >>Victor: We did have a question. If you could give a quick example of where the delay load technique would be useful. And I think you specified that it was specifically just for the purpose of the presentation of us being able to see the difference of the hard one being loaded and then the soft one actually asynchronous loading in and replacing it. >>Christian: Yeah, correct. In this example, I just put the delays in to have some time to process because my computer's too fast and it would be instantaneous. Where you would possibly want to use time delays in is, I guess, if you wanted to have a set of assets that you loaded up. Started loading first to make sure they're first in the queue. And then, you wanted to put it a delay in where before you started loading other assets that might be a time frame. But one of the good reasons for it or thing to think about it is when you're debugging stuff. And you want to put those delays in so that your brain can-- when you're debugging, you can put it in text pop-ups. Because if you just run text strings off of everything telling you when things are and then don't put delays in, you're just going to get a massive text dump. So I use delays a lot like that for debugging into personal things. So yeah. >>Victor: Someone was wondering if you can share any best practices to handle race conditions with asynchronous loading to make sure everything is loaded on clients before spawning players. >>Christian: Essentially, you can use logic in your Blueprint interfaces to put in stage gates. So for example, if I had 10 different objects that I wanted to make sure it was going into loaded into memory before I started doing anything else, I could essentially build a Boolean logic and have a set of variables, whether it be in increments or Booleans that check to see essentially, start the asynchronous loaded, when number one is complete, set to true or ink or increment an integer variable. And then when all 10 are true, then continue on. So just basic logic that you would use in any other case. >>Victor: Someone is wondering when will we use an actor soft reference versus an actor class soft reference? >>Christian: Essentially, when you want to reference a very specific thing. So the class is going to load up is also going to load up its children. An actor is going to load up the child and the parent. So the classes is going to load the entire thing and the actor is just going to load a specific object that you need. I tend to-- generally when I'm setting up the variables, I tend to work in references to the specific actors rather than the class. That's just how my brain works. >>Victor: It also depends a little bit on what kind of logic you're trying to execute there and what type of data those functions expect. >>Christian: Exactly. Exactly. The system is set up to be malleable and versatile, depending on how you're trying to set up your project. So there can be a lot of personalization based on what you're trying to do in specific cases. >>Victor: This question might be a little tricky, but let's see. Would you recommend digging into the asset registry and try and combine that with soft object references for asset streaming? Can you even do that? >>Christian: Well, yes I would encourage people to look into the asset registry. It's good information to have. As far as combining them, it's so dependent on what exactly you're trying to do. There's a lot of-- one of the nice things about the Blueprint system and object oriented design in general is that you can come at things different ways. Again, you can have this exact same effect using soft object references in your Blueprint or creating a Blueprint interface that only contains those references that you need to have. And then, attach that to the appropriate Blueprints that you reference. And asset registries are another way to do management that way. So I don't have a perfect like, yes, in this specific case, you should definitely do that. But the more knowledge you have about the system in general, the better equipped that you're going to have to be able to organize things. Again, with the logic that you want to use to build your project. >>Victor: I think that applies to a lot of things. Having a little bit of a computer science understanding of what you're actually doing has helped me a lot and that's something that came after I was even making things. It just makes you understand why am I going through this convoluted way of getting it to work like this? Why is this best practice? It's like oh, it's zeros and ones on a CPU that actually need to execute all of this and here are the reasons why it needs to do what it needs to do, which then leads us to when we do the abstraction of all the way up to Blueprints. That's far up the chain, as far as the abstractions go. Always good to know a little bit of what's actually going on behind the scenes. >>Christian: Yeah. And a lot of it comes down to again the logic that you're building and having it work with the logic that you're building. And there's not always necessarily one right way to do it. If you're making a mobile game, a space invaders game that's only going to have 32 actors variance at any one time, then you may never need to worry about this at all. But having the knowledge base and knowing the general way that it works can save you down the line when you decide to add those things. And I've never-- I don't think I've ever had a case where I thought, man I wish I hadn't spent that extra couple hours in the beginning researching this and learning about it and setting it up in a good way. Gosh, I wish that I had that two hours back. I have had a lot of times where oh, gosh. I have to go back and change this and I went in a direction that was incredibly challenging and now I have to spend days working on this. But again, there's not necessarily one right way to do everything. And that's what makes it challenging. And that's what makes game development hard is there's a lot of different ways a lot of times to accomplish the same goal. >>Victor: Please listen to another question I saw here. Is there a good use case not to use soft references wherever you can? I think you touched on it a little bit with sort of the small scale example of the space invaders project. >>Christian: Yeah. But also, it was funny because just yesterday, I think my tutorial might have made some impact-- because it was funny because yesterday, I was at the Facebook Unreal help desk. And I go through that every couple of days and to see if there's questions I can quickly answer. And someone was asking a general question about using construction script to build a roadside generator. And someone's first response was make sure you soft object references. Don't have all these references in there. And I'm like, wow that's-- that's a beginner having a better beginning question trying to set up a-- basically, learn the fundamentals of construction script. It can-- it does add complication to your Blueprints. And if every single time you create any variable, you're creating a soft object reference and then you're asynchronously loading that, and then you're going through there, that's a lot of complication. That's going to increase the actual load times on your Blueprints when you open them up in the editor. That's one of the reasons why you generally try to compress things and have things to be simpler. It's going to add complication to the logic when you're debugging things. And it can get quite complicated quite quickly. So again, if you know that if you know that this is going to be referenced and it's going to be used, there's not generally a-- Say for example, if I was making Super Mario Brothers, the first level. I wouldn't go and set each of those enemies as a soft object reference, and then try to-- right before he runs into a mushroom, go OK, well now, I need to load them up mushroom into memory. And later, OK, here's the turtle two minutes later. Now, I'm going to load the turtle into memory. I would probably just add all those enemies into the level, have them loaded into memory and not worry about it because I know I know there's only going to be 10 of them. I've budgeted for that. You don't want to get too caught up into like trying to constantly go OK, well there's no more mushrooms, now OK, you know let's get that out of the way. So I guess that's thinking about where am I going to go. So if you're budgets take into account that hey, we're budgeted for 20 enemies per level. We're good to go. We've got bandwidth there. We're never going to-- we know that as long as we stay below that, we're 100% good, then yeah. You don't have to worry about it. When it comes to those enemies, you can just have them all loaded up on load time. You're front loading that time onto the player to make sure that everything's in memory. And that way, everything's instantaneous as you're rolling through because everything's loaded into memory. >>Victor: So we had a specific question. So if you're doing an actor spawner, would you place the spawner in the level or have a soft reference to spawn the spawner, then soft references to spawn the assets as well? >>Christian: That's a great question. So assuming that your spawner is relatively lightweight, I would place the spawner in the level. I mean, that's the whole point of having a spawner is that it's lightweight compared to what it spawning. However, the thing to think about if that spawner actor-- And I actually have another-- I did a talk a couple of weeks ago at Vector where I did a really rapid prototype on an arcade style game that I built super simple spawners. And I actually have a video of that that I'll probably put out-- >>Victor: Yeah. Let's put that in the forum announcement post under resources. >>Christian: Yes. So I put spawners in there, even though they were basically just empty actors that spawned another actor, with the idea that later I would have more actors. So if your spawner has-- say you want a randomize enemy spawner and so, you have a Blueprint. And it basically says, hey when I'm activated, spawn an actor of this class. And then, you have 10 different classes as variables in that spawner. All 10 of those are going to be loaded into memory. And that might be fine. But in that case if you only want to have the spawner load the actor that's actually going to be spawned into memory, again going back to Super Mario Brothers as an example, what you could do is, I hit level 2, I know the types of enemies that are going to be spawned in and either I might have a special spawner that only contains those actor references or in that spawner, I could say OK, spawners in the level, here's the type of actors that we could have go into your soft references, load those specific actors into memory. That way, you're spawners ready to go, has those loaded on begin play. Only load those and then spawn from those specific classes. Does that make sense-- >>Victor: Yeah. >>Christian: --as an example? >>Victor: I think so. I think so. And we had a few more questions related to-- let's see here. That I think relates a little bit. How would one go about using soft references for assets referenced in data tables? >>Christian: Data tables get brought up a lot in reference to this. And I have to apologize because I'm not super familiar with data tables. I don't actually use them a lot. So, yeah. So I would have to pass on that one. I'd want to do a little bit of follow up on how specifically to reference those assets from data tables as variables. Unless you know, Victor. >>Victor: No, I don't actually. I was going to mention that on the first games I shipped, not a single soft object reference at all. >>Christian: Yes. >>Victor: Just entirely in Blueprints. Just all references to everything and-- >>Christian: Again, data tables are something-- Data tables, to me, are a little old school and I try to stay away from them personally just because I've had so many-- anytime something gives it a spreadsheet form and manual text entry form, I get scared. When it comes to QA, I've had-- If any designers dealt with localization tables in the past, I'm sure they had terrible horror stories about trying to track down bugs and things like that in there. So I like to minimize data entry by game designers because I know how ADD we are and how we have a tendency to screw things up in very little ways. So I like to have stuff in my Blueprints so that I can make sure that they're actually referencing an object and not using a text stream to reference objects. And that's a personal thing. >>Victor: Right. I was going to say that. And it's always important to sometimes consider your personal preferences over the possibility of a very, very, very minor optimization. You need to remember that we are all humans that need to work with these projects. And if you try to do to the best practice every single time everywhere, the amount of time you'll spend on that, the amount of complexity you might add to this for you as a human to actually work with this-- The production part of the game is sometimes as important, especially if you have a budget limitation or a time limitation sometimes. And there's 1,000 ways to do everything. But sometimes, take your personal preference into the plan for development as well. That can be important. As always, balance that versus the performance optimization and try to learn as much as possible about that so that you can make a qualified decision whether this is the right choice or not. Should it go personal? Should I go best practice, in terms of optimization? >>Christian: And think about the effect on things like test, as well. I actually shot myself in the foot a little bit in trying to do an optimization on ParaChess where right now, I'm working on some of the king threat logic to stop the king from being able to move to places where they're not supposed to be able to move. They're threatened by another piece. And I was running a check on the entire board to check every tile. So that was 64 checks every tick. And I said well, it'd be much more efficient to only check from the pieces that are actually occupied by the enemy because that would only be maximum 16. So that's 64 versus 16 checks per tick. That's going to be more efficient. I should do that. Meanwhile in trying to do that, I blew up my logic and essentially broke the game because the logic, really, was built around checking every tile. And then I went down this rabbit hole where then I had to go back and compensate for that and I'm adding much more logic to double check. But I don't think that in the end, I ended up with necessarily a more optimized project because yes, I was only doing 16 checks here instead of 64 checks here. But then, I had to add a bunch more check logic to compensate for that and it probably would have just been better, especially because I wasn't actually seeing a performance hit on it. My game designer brain went this will be more efficient. >>Victor: Yeah. >>Christian: And so, that can be a natural thing, especially with programmers and game designers where you can you can cross over that threshold of adding inefficiency while trying to do optimization. >>Victor: Let's see. We have a little bit more time. See if we get some new questions in. I think that's a good one. What's a one sentence summary of why soft object references are used? Now, we have to put the wordsmith hats on. >>Christian: Soft object references are used to put the control of when the object is loaded into memory into the designer's hands. >>Victor: I think that works. >>Christian: Boom. >>Victor: Next question. Do we need to unload the assets that we're not going to use anymore? I think I'd follow up with how would you specifically do that? >>Christian: Yeah, that that tags into something I mentioned in the beginning. Generally, there is no manual-- In Blueprint, there's no manual like async unload this object. That's because in general case, your garbage collection is going to handle that. So once you load it into memory manually through asynchronous loading, it gets to a certain point where the object is no longer needed in memory where it's not referenced by anything. It's been destroyed. Nothing else is referencing it. The garbage collection system is going to unload that at a certain point. It could be on a new level load, whenever garbage collection runs. So in general, this system should take care of that automatically. There are ways to create a specific functions for that in C+. I think Alex Stevens recently did a tweet storm on that. But that information is there, if you need to get into the really fine detail. But in general, your garbage collection is going to handle it exactly the same as it would for a destroyed actor that you spawn in and is not referenced. >>Victor: And that's another portion of memory management. Say for an example, if you have an automatic weapon of some sort that is firing x bullets a second. If you never destroy those projectiles, you're quickly going to run out of memory, right? And if they're all being somewhere drawn, maybe they're sitting on a wall or something. You're going to run into other issues. But if you do have a max lifespan which is a way that I like to not have to worry about manually calling destroy to just to make sure that, hey. After 30 seconds, this projectile has traveled five times the length of the size of my map. There is no way that this actor is being used in any way, shape or form. I'll add a 30 second data to the lifespan variable that exists in every actor. And so, making sure that you destroy them. And then once you destroy that actor, garbage collection will come in and remove all of that from memory. And so, that initial step could be all you need to think about and then manage what garbage collection is actually being done. >>Christian: Exactly. Exactly. So, yeah. Lifespan of various different objects. Yeah. And again, multiple versions of the same instances of the same actor, obviously, it's not a linear scale on memory usage. And yeah. So just building in smart things. Again, a lot of it comes into account when you have an object that references something that references something else that references something else. We've all built-- I think the first thing most game designers do is build an actor that spawns another actor that spawns another actor and then go, oh. That was not a good idea. Now, I have infinite number-- And most of the time, the Engine will try to stop you. Like, stop! You're doing an infinite loop. Stop it. But once you start creating things that create other things, that can help you visualize what it can do to memory management. If you have an actor that's randomly spawning an actor that has another reference to another 100 actors in it, you can very quickly get into the millions and billions of things loading into memory. Or your game just crashes. >>Victor: There's a lot to think about in game development. [LAUGHS] Think that's a good question. Let's see-- excuse me. If we can tackle this. If one were to stay away from data tables-- I'm sorry bringing data tables up again, but it's a good point. And it can be very useful. If one were to stay away from data tables, what's the best way to manage thousands of objects for a character customizer and you need to group specific objects by category? Hats, pants... >>Christian: I would think the interfaces would be a good way to do this. You can also do them in function. You can utilize your functions for your organization of your hierarchy. It's really, at that point it's-- outside of data management tables, it's you know, layering the things in, having a class of pants that has all your information for the various different pants, either as an interface or a function where you're going to access it. It's really about-- at that point, it goes into how you want to organize and manage that information. So you know, you can you set up your variables how you want it. You can organize them into different categories. And yeah, just build that to access the information. I don't know if that answered the question. >>Victor: I think there's a balance there as well. If you know you have thousands of actors, you know, it might be good to actually do it at a data table in terms of management. You might even have-- if that's the case, then you say you have-- RPG is a good example, right, because there's usually a lot of different pieces of equipment, skills, you name it-- what it could be. At some point, it does get easier to manage all of that. You know, you might even have a complete dedicated like, QA person just dedicated to making sure that all of the names in the data table are correct. You know, and at that point, it's easier for that person to actually manage CSV files, other than having to go in and open every Blueprint and possibly check them out, prevent the designer from being able to work on them. And so there's-- >>Christian: Yeah, and that's where you start getting into good source control management, right? Like, one of those stories related to this that came up was-- it was in a different engine, but they were using a data table-type information-- and they were actually getting ready for gold. And when they were building the final version of the game, at a certain point, the person that was managing one of the data tables did a check in, changed some of the data tables. And so half of the information was current and half the information wasn't current, because the source control didn't differentiate when it was checked in. So yeah, you know, you start getting into your source control, how do you want to manage that information, what works best for your team, you know, how many people you have, whether those people are onside or remote, all those kinds of things start to come into play. It really-- you know, it's funny, because I mentioned localization earlier. You know, when you start managing loc, if you think that RPG item management is complicated, you know, managing loc from multiple different languages for 10,000 lines of dialogue-- that can be a good thing. Any game designer should go read up on managing localization, because there's a lot of great information on there how to manage a lot of data, and especially a lot of data that you don't necessarily know what it is, right? >>Victor: Right. >>Christian: If you're managing localization in German, you might not actually be able to just inherently look at it and go like oh, yeah, that's right. So you need to set up systems within your team to make sure that you understand whether it's tags or how you do it, how you organize that information. And that can apply into the game systems as well. >>Victor: We did have Paulo Souza on the live stream a couple of weeks ago talking about localization. So if you're curious about that, and he did mention briefly sort of how to deal with contractors that-- because essentially, you're not going to have-- well, you probably won't have 12 people on your team that all speak different languages and know specifically how everything is spelled and the correct grammar and ways to change-- you know, whether they're pawns or possibly saying in one language have to translate them. You are going to have to use a contractor to manage all of that. And we did do a string where Paulo goes through how to do that in Unreal Engine and which tools exist for you to help with that. Good question about garbage collection that I think we can tackle. Following the projectile lifespan that we talked about, is the garbage collector run for every bullet destroyed, or will it batch them? >>Christian: I believe-- I mean, the garbage collection doesn't constantly run. Garbage collection gets to a certain point, and again, you can control some of that. So it's going to go through-- and as I understand it, it's going to go through and essentially say, hey, here's all the objects right now that I can get rid of. And it's essentially basically-- you know, so if you had 50 different types of projectiles coming out of your weapon, and they all lifespan expired, basically, the next time the garbage collection came through it would say, OK, all of these are ready to go, boom, dump them all at once. That's how I understand it. >>Victor: Yeah, when you do call to destroy actor node, it actually puts it in a list, and when the garbage collector does its tick, it will actually go and nuke everything that's in that list. >>Christian: Exactly. >>Victor: There are a few questions about sort of network relevancy and how you deal with soft object references when it relates to that. I'm not too familiar with that myself. Not sure if you've had a chance to tackle that yet. >>Christian: Not really, no. You know, once the object is loaded into memory, as I understand it, you're going to do your relevancy the same as you would anything else. But I would want to do-- if you're working in a multiplayer environment-- I'd want to do a little bit more research that maybe something I can follow up on is whether I need to treat those objects a little bit differently on you know, making sure whether they're loaded on clients and servers as well. >>Victor: Yeah, there could be some form of prediction there that you might want to implement based on that. So you can set the tick rate for the garbage collector to fire off? Yes, I believe that's in project settings. >>Christian: Yeah, I think so. And you can manually force garbage collection as well. >>Victor: Yes. There's a question about if we can give any prominent examples from any well-known games if they were using Unreal Engine, of when soft object references should be used. I think we tackled a couple of those use cases in general. I have no specific information about whether game A or game B used that particular method. >>Christian: No, I don't, not offhand. >>Victor: All right, well, this has been a really, really good and informational stream. I appreciate you coming on and doing the presentation. And for everyone, if you're curious and you want to share sort of a quick version of this, Christian did present-- or upload a video, which it's like 10 minutes long? >>Christian: 10 minutes, yeah. >>Victor: Yeah, on Vimeo. And I've gone ahead and linked it in the form announcement post already. So if you're curious and you want sort of this stream but in a quick format, and it's something you can share to someone who's like, what's soft object references? You can send that video. And then if they're like, I would like to work on this, you can go ahead and link them the live stream. Which by the way, I did see a question that usually comes up. All of our live streams get uploaded to YouTube once we're finished. Once Twitch is done processing and then YouTube is done processing, they will exist there. And usually every weekend we tweet a link to that as well. And you can find it archived. So if you're going through our forums, in the event section of the forum where we post all of the announcements for the live streams, whenever the stream is done and it's up on YouTube, we go ahead and we add that link to the livestream. And so if you see a topic that we've already done live, and you would like to check it out, the embedded version of the YouTube video should be there in the forum announcement post. I think with that, I think it's time to wrap up for today. Like I said, it's been great. Next week we're going to have Wyeth Johnson on talking about Niagara in 4.25. So yeah, it's gonna be cool. He's sort of our Niagara wizard here on the team, so all kinds of exciting things. Yeah, once again thanks, Christian, for coming on. I do want to mention for all of you who actually stream Unreal Engine development on Twitch that there is now a new tag. And you can see it as part of this stream, actually. You can now tag your stream with Unreal Engine, which is kind of cool. So that means that you can stream in whichever category that you feel entails most to you, whether you're doing art, or you want to be in science and technology or just creative, you can go ahead and add the Unreal Engine tag to make sure that if someone just searched for Unreal Engine, they'll be able to find all the current livestreams and streamers that are using the tag, which is a pretty neat little thing for them. So thanks, Twitch. As always, we are still looking for more countdown videos. If you've been here from the beginning of the stream, we appreciate you watching and staying with us for this long. If you saw that little countdown video, it is 30 minutes of development that you record, and then speed it up to five minutes. Send that to community@unrealengine.com, and we will put the little countdown. Don't composite or add anything to the video itself. Send that with your logo, and we'll add a little countdown to it, add some nice little intro music track. And you might be one of the people that we showcase at the beginning of the stream. Make sure you follow us on social media for all news related to whether it's Unreal 4 or Unreal Engine 5, which you can see-- also, I should mention that Christian's virtual background is actually available if you would like to use that in Zoom, which is kind of fancy. I like it a lot. I think you did a good choice. >>Christian: Yeah, I like it. >>Victor: Yeah, it's almost like Stargate. >>Christian: So awesome. >>Victor: Yeah, I think that's it for this week. I appreciate everyone for coming on. Everyone in chat, say goodbye to Christian. And I hope to see you at some point. Oh, I'll make sure to add the link to the stream that you did on ParaChess if anyone is interested in watching that as well. A little project Christian's been working on there. I think it's pretty cool. >>Christian: Awesome, thanks very much. Thanks for having me on and yeah, see you online. >>Victor: Yeah, we'll see you all online. Have a good rest of your week, everyone, bye.
Info
Channel: Unreal Engine
Views: 81,736
Rating: undefined out of 5
Keywords: Unreal Engine, Epic Games, UE4, Unreal, Game Engine, Game Dev, Game Development
Id: K0ENnLV19Cw
Channel Id: undefined
Length: 87min 50sec (5270 seconds)
Published: Sat May 16 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.