Grabbed a couple of hours in the evening to look at one of those bugs: I was getting a visual pop of the light intensity and colours, as the forest map unloaded. A look at the DayNightController turned up a couple of minor derps; I wasn’t handling all cases where a map could unload, and I should have been using weak pointers, since I was absolutely referencing stuff that could go stale.
But that wasn’t the fix. It turned out to be a bit more subtle.
The code that checks the active post-process volumes, and calculates the blend weight that’s then passed up to the global DayNightController, was pushing itself up as a newly active region, the frame it was being unloaded. Ie: it was calculating a blendweight of 1, just before it died. Why?! After much poking about it started to make sense: when the post-process volume is being unloaded, its EncompassPoint function starts returning -1, which buggered up my math. I never assumed to clamp it, or early out if it was less than zero.
Worse, I think this was a race condition. Sometimes EndPlay was called on the volume check before the -1 appeared, sometimes after. If it was after, it’d be for one frame, which was enough to bugger things up.
For a while I was thinking I’d have to detect the unload, somehow, and early-out of the last Tick, so I’m relieved that the post-process volume did the “correct” thing with its EncompassPoint function, even if it took me a couple of hours to get to the bottom of it.
I’ve had a stall when starting PIE, caused by AI using NavMeshes. An ensure, wrapped around the AIController as it requested a NavMesh filter, was popping. Only happened the first time the map was used, but it was happening in packaged builds as well, so it probably needed fixing.
I’d assumed this was another race condition – the Navmesh was being loaded, or rebuilt, and my AI was trying to use it too early – but this didn’t appear to be the case. Well. Kinda. It was trying to use it before it was loaded, but I discovered the “Is Navigation Being Built Or Locked” node, so I was able to block on that.
In the end, it looks like the default NavMesh_filter was causing it. I removed that, and the problem disappeared, so I moved on. I’m probably not exactly up to speed with Nav Meshes and their internals, at this point…
The rest of the day was spent finishing up the Chicken. The main thing missing was the lack of “flee”. For this I wanted to use the Environment Query System, which most people use in Behaviour Trees. This would be my first attempt at doing so in my UtilAI system, and fortunately, it worked a treat!
If you’re not moving the chicken won’t think you’re a threat, but if you move too quickly, it’ll run away and hide. Nothing too clever. In fact, for the most part it just looks for the point furthest away from the player, but it proves I’ll be able to use EQS down the road, which is the main thing…
Grabbed a couple of hours after class and started rigging/skinning the Rook. Used one of the pre-built Auto Rig Pro armatures, and it ended up working really well.
Knocked up idles, flight loops, landing and take off animations for the Rook. They look a bit ropey if you inspect them up close, but as that’s never going to happen…
Noticed that my AIAction debug info wasn’t getting rendered correctly, so promptly fell down a rabbit hole…
I’d been calling DrawDebugString, which is part of the DrawDebugHelpers class. That, in turn, wraps around some built-in string functions in the Hud. What I wasn’t aware of, was that the stuff in the Hud was designed to receive a load of text and make sure it was printed, automatically, on top of an Actor in the world. That’s pretty handy, and I promptly changed my Logging class to use that directly…
One other thing it does, is remove all the debug text as soon as it receives a string of zero length, and that was my bug. AIActions that have zero score send a string of zero length through the chain, and when it hits the Hud it stops printing. Easy to fix, and I now check for zero length strings and pad them out to a single space in my logging class. I can’t see any instance when I’ll want the Hud’s implementation, as my debug is always calculated every frame…
Once that was fixed, I built up a simple NPC Rook, that takes off from a perch when the player gets within range. Eventually I’ll create rooks that’ll circle the player, and even attack them, but for now I just want more life in the world. And it’s a simple test to make sure things can fly.
I need something for my Rooks to spawn from, so I modified the spawn areas I created for fish/butterflies to optionally use a spawn-point, as well as a volume. And added some options so they could be one-time, when the map loads.
With these scattered about the world, I have various perches that the Rooks could be loitering on as you walk through the map. Pretty funky.
I also added some super noddy steering to the flee AIAction, so the bird changes direction, and a timeout so it’ll shrink scale, and kill itself. You can see this happen if you watch the shadow, but I don’t think it really matters.
With a bit of audio, some particle effects, and the spawn rate turned up to max, you get something like this:
Next week I’ll make a start on the baddies for the first dungeon…