Phase-Functioned Neural Networks for Character Control
For most games with animated 3D characters, a lot of time is spent linking the animations with the character’s motion, often using complex state machines that create webs of animation transitions.
This research, by Daniel Holden, Taku Komura, and Jun Saito, instead used a neural network to act as the character controller. The neural network is trained on a large dataset of animations and terrain data, taking gigabytes of data and combining it into a function that runs quickly and uses only a few megabytes of memory.
There’s been some past research in this area, but based on the video of their results their phase-functioned approach is very, very effective.
This is the exact kind of generative tool that can empower artists. It still needs the artistic input (that animation data has to come from somewhere) but it takes care of the very tedious work of combining all of those animations, freeing the artists to produce even more art. (And the technical artist can go improve some other tool.)
And, since the training is offline, rather than while the game is running, the risks of training a neural net can be supervised, so the game can ship with just the resulting locked-in function.
So I’ve finally made some notable progress on this project. After the switch to the new computer nuked my former build, I’ve started from scratch and surpassed that old build in both functionality and future potential, because I’ve finally managed to accomplish one of my basic goals. I’ve created the foundation for a modular controller.
This means that I can now make component scripts that focus on VERY SPECIFIC things, meaning I’ll never have the problem of being unable to parse my own code again. (Note: This was never an issue of “not enough comments”, I just have moments where my attention issues make me functionally illiterate) I now have a basic run and jump controller working and can make any additional tweaks as I need them.
For an idea of what this can mean for the game, picture the controller now as a tree, with each leaf being an action, and the path of branches to that action being the series of triggers and inputs required to make it happen. Each branch is like a “mode” for the controller to be in, and switching between modes can change what literally every button does. Spacebar might be jump while on the ground, but while swimming, it might be “dash”. And it’s not just environmental input like the character being in water than can change modes either. Something as simple as holding shift in this game is a mode shift, as it completely changes what most buttons to. WASD go from running to a defensive sidle, Spacebar changes from jumping, to a dive move. LMB/RMB change from melee and ranged attacks, to shield bashing and grab moves. This opens up so many potential pathways, it’s actually simpler to list what it CAN’T do. Which is literally nothing FYI.
The goal now is to get a basic block terrain system working so I can start testing and refining the movement in a facsimile of the finished game’s terrain, so I can have everything working properly ASAP. That way, I can switch focus to making things look good afterwards. Ideally, the alpha build will include some simple Perlin noise terrain to provide a proof of concept during the testing phase, though the final game will have a pre-built map. Though I also intend to include a procedural sandbox mode for the replay-ability.
I’ve decided to declare the deadline for this game’s first public alpha to be the end of this summer. This means I need to finish basic terrain generation, and a simple set of controls by September. At which point I’ll post a link to where you can pick up the eventual released alpha.
So I’m almost done with the character controller, finally. The only thing left to do is add the wall jump functionality which will in turn become the basis for most of the advanced movement. Aside from that and code cleanup, like compressing the player state taxonomy into a single check-tree, the controller is complete.
Next on the list is starting on the map builder. I’ve mentioned it before, but maybe not here, that my game’s terrain *won’t* be procedural. Instead, the entire map will be pre-built using an image translator that will take the color vectors of an image, and translate them into position data, biome assignment, and so on. It’s a relatively simple concept. Meanwhile, features ON that topology will be procedurally populated based on the pre-assigned biome layout, and pre-determined town locations. Everything will be saved to a map file, chunk by chunk, with entities included. Everything persistent and reliable.
The initial hurdle to get over is finding a good size for the object pool the game will draw from. All tiles will be based off a single prefab that changes stats, textures and effects based on the ID it’s given by the map builder. The chunks are 32x32x32 in the current plan, though this may be reduced later, so the highest possible number of blocks each chunk can have instantiated at a time is about 3/4 of the entire chunk. This is A LOT of objects, and that’s not good optimization, but for the time being I don’t know a better way. Such is the nature of developing when you have literally no experience in game development.
For the time being, I’m simply going to make the system build a platform that I can test placement and removal of blocks, without bothering to manage chunks or the object pool. This should be pretty easy and only take about a week, unless I fall asleep at the wheel again like I did a while ago.
I should have more screenshots to post soon, and eventually I’ll have ones with better graphics. Everything is placeholder at the moment.
It’s been quite a while since I last posted anything of my own projects. That’s because I’ve been very busy and/or working on non-programming projects (have you heard of my other blog, Whispers of Ink? :P) and trying to figure this out!
Here are some useful links I found while trying to figure out this topic:
Continue reading if you want to learn how I resolved it!
So, main problem when facing a new 2D game programming? The player controller. If you already had a custom one or a borrowed one that works for you, that’s easy to resolve! But when you don’t, that’s where the headaches start.
There are several types of 2D Player Controllers, but let’s summarize them all in two: either you are limited by some easy boundaries (let’s say, the screen itself) or you do have difficult collisions. I did have them. It took me for about two months to finally pull it off, because I couldn’t wrap my head around how to detect them properly.
Most of all, I didn’t want to use rigidbodies. They are very useful but quickly turn bothersome, specially when slopes and edges come into play, and I’m looking for a fine tuned player controller. I don’t need physics (for now).
KEY POINTS
Movement vector: Useful to bring movement accross frames. It will store the player (last) movement direction, both horizontal and vertical.
Jumping: Jumps are actually arcs. You will need the maximum height achivable for a jump (store the jumping point somewhere), the jump speed and the gravity. When the player hits jump, the jumpSpeed (per deltaTime) is stored in your movement vector vertical value (y). This vector is dragged to the next frames, so you will keep substracting gravity to it until the gravity value is met.
Correct the movement: User input is paramount, but what the user wants is not what is happening in the world we are building. Let the user tell you the movement they want (store this in the movement vector), then proceed to check that movement against the virtual world reality. If something doesn’t check out, correct it! Collisions, slopes and jumping are the most usual.
Collision prediction: Once you have your movement vector in place, it’s time to check if proceeding with the movement will result in collisions. Store these collisions.
Ground detection: First, you need to check if you’ll land in an obstacle. Raycast from the player feet down; if it hits a collider that is stored in your future collisions, you know you’ll be landing somewhere. React appropiately (cancel vertical movement, for example). Pro-tip: Have several raycast points in the feet for broader detection, and pick the shortest distance to a collision.
Horizontal collision: You’ll need three raycast points: head, waist / body center, and a fake feet position. Why fake? Well, you’ll need it slightly above your actual feet position to avoid hitting ground. Raycast them in the direction of your movement (left or right). If any one of them hits a collider already predicted, that’s a future collision. React appropiately (cancel vertical movement, for example).
Slopes: This is the trickiest. Using the raycasts for your horizontal collision detection, check if the feet hit anything. Three situations may happen next:
If feet raycast didn’t hit anything, raycast from head and waist points. If there’s hit, just cancel the horizontal movement; you have a obstacle ahead.
If the feet raycast did hit something, but the player is not grounded, cancel movement and that’s it. Slopes don’t matter flying, and the ground detection would have stopped the falling anyway.
If the feet raycast hit something, and the player is grounded, you’ll need to create another slightly higher raycast point. Let’s call it slope detector. Raycast in the same direction from the slope detector, this time with a higher distance detection. It should hit the same collider (if it doesn’t, it’s just a sprite disadjustment or a small step). Get the angle of the vector form by both points (feetHitPoint -> slopeHitPoint) and the ground. If the slope is walkable, your new movement vector is the hit vector normalized, multiplied by the magnitude of your actual movement vector (to keep the movement speed). If it is not a walkable slope, just cancel the movement.
AND THAT’S IT!
It sounds way easier now.
Also, pro-tip (that I have yet to implement): Use more hit detection points for more accurate results! Slope edges will get in between the feet points, and that would qualify as a bug more likely.
Hey all, sorry for letting this dev blog lag. In all honesty, my efforts have been more dedicated to my YouTube tutorials than to game dev lately, though I have been making some progress on a project I can share soon. On the tutorial front, I've been focused on two series: one about character controllers (everything from walking to attacking to vehicles) and one about building meshes through code. If either of those interest you, please check them out (https://m.youtube.com/channel/UCifiUB82IZ6kCkjNXN8dwsQ?). And as always, you can support my tutorials and game dev at patreon.com/boardtobits. Thanks!
Learn to make a fully-featured character controller from scratch for your games in Unity.
I’ve been working on this series for the past couple months, and while it’s still not finished, it’s at least robust enough that you can get a character moving and jumping. There’s still a lot more to come but now’s a great time to jump in.