Dangeresque: The Roomisode Triungulate
I was asked by the Brothers Chaps to do additional programming for their Dangeresque project. Namely, I was asked to create custom textboxes that worked inside of Adventure Creator, a plugin for Unity.
They wanted to be able to have textboxes positioned properly that respected character locations and screen boundaries, the ability to have text boxes use alternate graphics to show “thinking,” and the ability to toggle animations off for specific lines.
Technical Breakdown
Once I’d gotten an understanding of the general functionality that Matt and Mike wanted, the first step was to add boolean variables to the editor for No Animation and Thinking Box. I did this by editing the ActionSpeech.cs file in Adventure Creator.
This allowed me to add bools to the Speech action drawer in-editor, meaning that the designers could edit these parameters on a per-line basis. The default was to animate and use the speech box.
The talkbox itself is built in two parts — the talkbox itself and the manager. The manager is a singleton that can persist across scenes, and the talkbox is a simple prefab that just shows the actual text. Below is the code for the talkbox itself.
The TalkboxManager.cs is much more complex, as it has to hook into the Adventure Creator API. It starts by subscribing a function in a delegate in Adventure Creator’s EventManager. There are several coroutines used due to how Adventure Creator does initialization, needing to wait until the talkbox is properly initialized before actually using it.
On top of this, Unity takes a full frame to dynamically position UI elements, so every instance of a custom talkbox showing text has to be delayed a frame in order to compensate.
FormatTalkboxAsync() is the bulk of the functionality. It starts by validating the line being passed in, then finding the position of the speaker to determine the direction the speech carat should be placed.
Then there’s a simple check to determine if we use the “thinking” graphics or “speech” graphics. We wait 2 frames to allow all positions and events to settle; things simply don’t work properly if this step is ignored, because the text dynamically shifts the textbox’s size with some Unity trickery.
Now, we get the half-width and half-height of the box. We find the rect of the speaker on-screen, then find their relative position on the screen for where to place the box. We then determine if this box falls inside the screen (including padding), and finally determine its placement.
Once we show the textbox, we need to show the carat, or the little tag on the bottom of the speech bubble that points to the character’s mouth.
This all ended up working, but naturally was a bit of a pain to figure out all of the math, and required a lot of debug work. In order to make this easier on myself, I created a few Debug utils in order to draw rects on the screen. This let me know visually if my underlying math was correct, and I could then determine if the issue was with the math or I was using its results incorrectly.
The end result was well-placed textboxes with dynamically-placed carats, complete with natively-implemented tools specific to the project’s needs.