Thursday Report: Chitter Chatter
Mostly polishing things up this week with some animations and tweening.
One issue I had run into with the dialogue box is that, although the box spawns in the correct locations according to the NPC’s head, if the player were to move the camera, the box might obscure the NPC or simply look strange.
The fix was surprisingly simple. I set up a signal that gets emitted by the camera whenever the camera is zoomed in or out. It says to the rest of the game ‘camera changed!’ and certain parts of the game can act accordingly. The dialogue box listens for this signal, and it knows that once the camera changes to find the spawn location again (now that it’s moved by the camera moving), and change position.
This worked fine, but looked a bit choppy — the dialogue box would suddenly appear in its new location. A simple tween takes the two points, where the box is and where the box will be, and makes a nice little animation between them.
Godot comes with a number of different mathematical animation options to change the feel of this animation — I went for ‘CIRC’, which once arriving at its destination floats a little bit back of forth. I think this gives the box a better sense of place by making it seem less rigid. Speech bubbles would float around in real life, right?
Don’t we all?
Oh, and boxes now automatically find the name of the NPC and place it’s name atop the box.
Hubert is a fresh addition to the crew, and marks the first ‘villager’ archetype added in the game. I figured, as a round and well proportioned apple, Hubert would be perfect for the ‘default’ villager on which all other villagers are based. In theory, all the work done on Hubert (states, scripts, animations etc) can simply be hot-swapped with new sprites and information and a new villager is ready to go.
Since there will be vastly more villagers than travelers, this makes sense in the face of father time. If at any point this feels homogeneous, I’ll be sure to make adjustments. In theory, however, personality types will be as easy to assign as, well, assigning them. Then the game will know how the villager might act, and what they might say.
Ready to hit the town.
But for now, I’m focusing on getting Hubert right.
Facial animation was another focus this week. It occurred to me that ‘AnimatedSprites’ would be an ideal solution to the problem I had. Previously, as seen in the video footage of Tellstone the Toad, I had the mouth animate open and closed on a tween. It looked repetitive and too bouncy for normal speech. An ‘AnimatedSprite’ node allows me to load in many different sprites and either pick between them or cycle through them. So, with many mouths loaded in, I can select the closed mouth when the character isn’t talking, and spin through all the mouths when they are.
By just pasting in each mouth at a fairly random order, you can quite easily create the illustration of speech.
The fun part is spamming these in a random order.
It looks smoother than my GIF capture lets on.
I think the jitter of the blinking eyes and moving mouth is a nice contrast against the smoothness of the tweens. I think it’s a nice reminder of the story-book like aesthetic the game has.
Nodding in agreement.
And above is a simple example of how some small gestures can really give life to the conversation. I’m hoping that I’ll be able to change character expressions depending on their dialogue, and their actions as well. Perhaps for more casual conversations (not when a character is ‘shocked’, for instance), a series of different animations can play out randomly to make things look more natural.
Nothing too extreme, of course. No one wants two wild hand gestures after another. That would just be silly.
Follow me on Twitter.