Unity3D/C#: NPC Text Boxes

image

Essentially we’re aiming for the above. First, head over to my code snippets and grab the “Border Text Box” method. I’m storing that in a public static class called “Interface”, so you’ll see, “Interface.BorderTextBox” and you will also need ‘CheckWithinDistance’. In this project I’ve stuck it inside of a public static class called “Scene”, so you will see, “Scene.CheckWithinDistance”.

We’re using a typical Unity C# script. I’ve called it ‘TalkTo.cs’.

    public GUISkin Skin;
    public string[] Body;
    public int[] LinesDisp;
    public CharacterController Player;
    public GameObject NPC;
    public float Dist = 5f;
    public float TextX = 0f;
   public float TextY = -70f;
    public float Width = 200f;
    public float Height = 20f;

To break it down. Skin of course, is the GUI skin we’re going to attach. Body is an array, so in the editor we’d define how many bodies of text we want to go through.

LinesDisp[] is telling Unity how many lines we’ve got displayed by that string. In your GUI skin, make sure you’ve got the Label “word wrap” turned on.  The reason we’re telling Unity this is because it’s a simple way of resizing the text box. There’s probably a way of coding it so the box resizes itself by checking how many lines there are, but this method is simple.

Player & NPC are basically the 2 object we want to check so the text box displays. The player is talking to the NPC after all. Dist is the distance we want to check.

TextX & TextY are the positions and Width & Height are for the text box size. Height will be the height of each line as our box will resize based on the number of lines.

Now, for our Private Declarations:

    private int para = 0;
    private bool touching = false;
   private bool onTouch = false;
    private bool talking = false;

Para is for checking which body of text is currently being used. Touching is to say whether or not the NPC & Player are within conversation distance. onTouch is for creating a method for when they’ve just come into contact. Talking is for checking whether or not they’re talking at the moment.

 

Now, use this for you void OnGUI() MonoBehaviour

void OnGUI()
    {
        GUI.skin = Skin;
        if (Scene.CheckWithinDist(Dist, Player, NPC))
        {
           if (talking == true)
            {
           GUI.Box(new Rect(Screen.width/2 + TextX – Width/2 – 5f, Screen.height + TextY-5f, Width + 5f, 5+ Height*LinesDisp[para]), “”);

           Interface.BorderTextBox(Body[pata].ToString(), Screen.width/2 + TextX – Width/2, Screen.height + TextY, Width, Height*LinesDisp[para], Color.white);
            touching = true;
            }
        }
    }

 

So, first it applies the GUI Skin. Then asks if Player & NPC are within ‘x’ number of units in distance (I put 5 units as default). They asks if they’re talking, if they are then show a GUI Box to make the text window to the specifications we need for a box, the height is multiplied by the number of lines we’ve got. And there’s offsets of 5 units each way so there’s space between the edges of the text and the edge of the box. Then display the actual text with the same measures but without the offset. Then tell Unity that the NPC & Player are touching.

And now for the void Update() method

void Update ()
    {

          if (Input.GetButtonUp(“Action”))
            {
               if (talking == true)
                    para++;
               if (talking == false)
                    talking = true;
                if (para == Body.Length)
                {
                    onTouch = false;
                    talking = false;
                }
            }
                     
       if (touching == true)
        {
           if (onTouch == false)
            {
                onTouch = true;
                line = 0;
            }               
        }       
       if (!Scene.CheckWithinDist(Dist, Player, NPC))
        {
            onTouch = false;
            talking = false;
        }
  }
  

 

You’ll notice “Action” is used for Input, the default name for this control is “Fire1”, which you can change within the project settings.

To walk through.

Ask if the player has hit the ‘Action’ button.

If he has, are they currently talking? Then go to the next paragraph. If not, then tell unity that they are.  Ask if the current paragraph is the last paragraph in the Body array (Body.Length will return its highest array) , if it is the last paragraph, then they’ll stop talking and the ‘OnTouch’ variable will return to its default as ‘false’.

When they are touching, check to see if they’ve already touched (onTouch), if it’s false, then tell Unity that they’ve touched and reset the paragraph back to 0.

If the player is NOT within the desired distance for talking, reset the OnTouch variable and tell Unity that they’re no longer talking.

 

The result in the editor looks like this:

image

Bear in mind this is directly out of my game, so there’s a couple of variables added (Command, Menu & Argument), there’s also a naming convention (LineText for Body). This is because I corrected my naming conventions in my tutorial “LineText” is a little misleading.

Body & LineDisp need to have the same array size as they each match the same paragraph. So notice, element 3 is the screenshot above and element 3 in the LinesDisp array says “2”, meaning it has 2 lines, which is what you can see in the shot. (Posted again below).

image

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s