- Category: Unrealengine
Today's tip relates to another common, but particularly insidious error in Unreal code that can end up costing huge amounts of frustration and lost time.
Consider the code below:
class ATestActor : public AActor
You have a struct which contains a UObject pointer (yes, this should be TObjectPtr<> in UE5), and an actor that has two member instances of that struct, however, only one of them is marked UProperty.
Let's say you spawn in this actor in your game, and you create a UObject, and Data1::Object and Data2::Object to point to it. Then, you destroy the UObject. What happens?
Answer : The engine will zero out Data1::Object, but Data2::Object will remain as a dangling pointer.
Why? Because UProperties need to exist in an unbroken chain from the top-level object (usually the world). Because ATestActor::Data2 doesn't have a UPROPERTY() specifier, that chain is broken, and Data2::Object does not exist as a property in the engine, so it can't deal with nulling it when the object is destroyed.
This leads to all sorts of potential issues. The worst kind of non-obvious, intermittent, inconsistent, issues with object lifetimes, cooking, unexpected garbage collection, and potential memory stomps.
Best of all, you won't get warned that this is a problem! So make sure you keep an eye on your property chains, and if you have any weird intermittent property issues, double check them.
- Category: Unrealengine
Common scenario: You're in a playtest session of your multiplayer Unreal title, it's all going well, but suddenly...."has the server died?", "I'm stuck!", "I'm lagging"....and then "Oh, no, it's fine again now".
You'll more than likely come across this scenario several times during the early phases of a project's development. Particularly working in AI, this is something I've had to fix more than a few times, as there's a common culprit that comes from Unreal's AI system.
If you're taking profiling snapshots of your server builds, it's easy enough to see the problem: You're churning UObjects, that is, something is creating new UObjects every frame, and every 30 seconds or so, the garbage collector is having to clear up the thousands of accumulated objects, which gives you this huge hitch on the server.
In order to find these issues, there's a useful option in Editor Preferences -> Show Frame Rate And Memory. This gives you a little extra information on the title bar of your editor window, showing framerate, memory usage, and critically, the number of UObjects.
Normally, when you're playing your game, you'll see this object count climbing rapidly as the game loads and everything initialises, and then fluctuate up and down, but settle in a steady range over time.
If you have a churn problem however, the number will be flying updwards like the altimeter in a crashing place, but the other way! It's very easy to spot so having this editor option turned on by default and catching it locally will help prevent this ever being a submitted issue. Obviously there are other tools such as Stat UObject to find more detail.
To then find out what the offending UObject is, you can simply stick a function breakpoint in UObject::UObject(). Once you hit it, continue a few times to make sure you haven't picked up something that is legitimately being constructed that frame.
Chances are, if you have AI in your game, the culprit will be UAITask_MoveTo. This is the object created when the behaviour tree system (with Gameplay Tasks enabled) requests a new move. Early on in the development of your title, it's likely the AI configuration is pretty rough, the navmesh isn't always up to date, the world isn't marked up correctly, and for whatever reason, you have an AI agent that has got into a position where it can't move, and every time it requests a new move, it fails. Every frame.
Ideally, your AI never gets properly stuck like this, but even so, it's a good idea to put the MoveTo task into a Selector node with a Delay after it, so if a move does fail, the agent waits a second, before trying again. No more new UObjects every single frame!
Obviously the issue won't always be AITasks. UI is a common culprit, as it's very easy to make interfaces that inadvertently create new UMG widget containers every frame. Fortunately though, whatever is causing UObject churn, it's dead easy to identify, track down, and fix!
- Category: Site
Well, it's not really, but this is as much as much time and effort as I can bring myself to spend wrestling with Joomla. I'm sure there are better CMS around these days but this has been going a long time and I don't fancy the thought of migrating it just now. Can't say I'm a huge fan of modern web design where everything is acres of dead space and all images with no text, trying to find a new theme that focuses on text articles is a mission these days.
In other news, I didn't manage to make it to DevCom sadly due to Covid, but the online coverage was very good and I got to watch more talks than I would have been able to attend in person, so not all bad. A real shame I wasn't able to catch up with friends in Düsseldorf, but there'll be a next time.
In other news, I have a few draft articles I've scribbled down over the years but never published, so I'm spending a little time editing them and may publish a few. May be useful to some people!
Fun fact : the most popular articles on my side are all about the boids implementation I wrote, it's a popular little programming exercise, I suspect it's a lot of students. I think my implementation is pretty optimal so all good!
My Unreal plugins have been updated to UE 5.0 a while ago, but having dabbled with 5.1 at work recently, I'm pretty sure I'm going to need to update them all in the next few weeks.
- Category: Site
Apologies for the vanilla template, I've been needing to get the back-end updated for months and finally got round to it recently. The process went fairly smoothly, except for the template I was using isn't playing ball with the new Joomla version.
It's probably about time I went with a 'modern' bootstrap style like all the cool kids anyhow. Sadly I've had my butt kicked sideways by Covid for the past week, and am only just dredging up the stamina to get to Germany for DevCom next week. I will however, get back to prettying the site up again in the coming weeks once I'm fully recovered.
Page 1 of 22