Mark Gilbert's Blog

Science and technology, served light and fluffy.

Giving the game a voice – TextBoxDribble

One day on a car trip, CJ and I were brainstorming about the algebra game, and my two daughters got into the act.  The three girls started working out a storyline for the game, and how there should be a guide of some sort that leads you through the levels.  The girls did some sketches, and I quickly threw one in to see what it would look like.

10

A lot of the game is (we think) intuitive, or is explained to you in the tutorials.  However, there are a handful of messages that can appear during gameplay, mostly around telling you when you tried to do something invalid (like applying an operation to only one side of the equation).  I thought it would be cool to have this wizardly-looking mentor fellow “speak” those feedback messages to the user.  To make that look a little more convincing, I wanted the message to “dribble” in, one word at a time, instead of having the full message appear over the image, to mimic someone speaking them.

TextBoxDribble

To do that, I wrote a script called TextBoxDribble.  As the name implies, this script will make the message you assign to a textbox appear to dribble in.  Here is the script, in its entirety:

using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof(Text))]
public class TextBoxDribble : MonoBehaviour
{

[Tooltip(“Must be greater than 0; defaults to 1”)]
public int FramesBetweenEachWord = 1;

private string _PreviousValue;
private string _NewValue;
private string[] _Words;
private bool _ShouldWatchForChanges;
private bool _ShouldDribbleTheWordsIn;
private int _WordIndex;

private void Start()
{

this._ShouldWatchForChanges = true;
this._ShouldDribbleTheWordsIn = false;
this._WordIndex = 0;
this._PreviousValue = this.GetComponent<Text>().text;

        // Make sure FramesBetweenEachWord is always something valid;
if (FramesBetweenEachWord <= 0) { FramesBetweenEachWord = 1; }

}

void Update ()
{

if(this._ShouldWatchForChanges && !this._PreviousValue.Equals(this.GetComponent<Text>().text))
{

this._ShouldWatchForChanges = false;
this._NewValue = this.GetComponent<Text>().text;
this.GetComponent<Text>().text = “”;
this._Words = this._NewValue.Split(‘ ‘);
this._WordIndex = 0;
this._ShouldDribbleTheWordsIn = true;

}

if(this._ShouldDribbleTheWordsIn)
{

if (this._WordIndex < this._Words.Length)
{

if(Time.frameCount % FramesBetweenEachWord == 0)
{

this.GetComponent<Text>().text = string.Format(“{0} {1}”, this.GetComponent<Text>().text, this._Words[this._WordIndex]);
this._WordIndex++;

}

}
else
{

this._PreviousValue = this.GetComponent<Text>().text;
this._NewValue = “”;
this._ShouldDribbleTheWordsIn = false;
this._ShouldWatchForChanges = true;

}

}

}

}

}

The script’s Update() method has two main pieces.  The first conditional looks for changes to the textbox .text property.  When the textbox is assigned a new value, the script pulls it out, breaks it into an array of words, clears the textbox, and sets _ShouldDribbleTheWordsIn to true.

That signals the second block to go into action.  This block begins to reconstruct the new message, one word at a time.  Once the entire original value has been assigned, it goes back to watching for new changes.

The user can control how quickly the words appear through the public FramesBetweenEachWord property, which gets exposed in the Unity editor.  The name, hopefully, explains how it will work – the higher the value, the more time passes between each word getting appended, and the slower the overall phrase will come in.

Advertisements

October 9, 2017 Posted by | Game - Algebra, Unity | Comments Off on Giving the game a voice – TextBoxDribble