• Subcribe to Our RSS Feed

Simple Scrolling Combat Text with Unity3D

Dec 10, 2011   //   by Josh   //   Games, Tutorials, Unity3D  //  1 Comment

I found an interesting discussion on Eric Heimburg’s G+ page about “floaty numbers” in Unity, and offered to share my solution to this problem as seen in HexDev, so here it is! Maybe someone will come looking for Scrolling Combat Text in Unity and this code will help!

So to get things started, here’s a quick screenshot of the implementation in HexDev:

Concept

The basic concept is to display numbers above a unit whenever they take damage.  The number should rise for a certain height at a given speed and then poof away!  Nice and simple right?

So, to do this using my approach, we need a couple things:

  1. A Prefab with a TextMesh component attached.
  2. A Unit object with a MonoBehaviour attached that calls: SendMessage(“DamageTaken”, x);   where x is the number to be displayed.
  3. The ScrollingCombatText behaviour below attached to the GameObject that you want to display SCT numbers.

So, Step 1) In my projects, I have created a prefab called SCTText which looks like this:

Nothing fancy, again just a GameObject that has a TextMesh object on it.  The beauty of it is that you can change this prefab to have a mesh or particles or whatever you want on it.  The number will be updated by the ScrollingCombatText script below.

For step 2, all of my units have a special behaviour attached to them that manages their health.  Whenever they take damage, they simply use the Unity SendMessage API to notify other MonoBehaviour’s attached to the game object that the unit has taken damage.  This will probably need to be tailored to your project.

And for step 3, I just attach the script below to my GameObject, give it the Prefab we defined in step 1, configure some parameters and whenever the unit takes damge, voila!  Scrolling combat text!  Here’s what the configuration of the script looks like on my units (each unit can have their own values or we can use the default values):

Code – ScrollingCombatText

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class ScrollingCombatText : MonoBehaviour
{
	// How fast will the spawned text object rise
    public float RiseRate = 4.0f;
	// How high should the spawned text object rise
    public float RiseHeight = 10.0f;
 
	// Prefab with an attached TextMesh component that will be spawned when damage is taken
    public GameObject TextPrefab = null;
 
    private List floatingTextObjects = new List();
 
	// This will be the starting height of the floating numbers
	private float initialHeight = 0.0f;
 
	// Use this for initialization
	void Start ()
    {
		// If this component is attached to a CharacterController, use the CharacterController's height attribute to set the initial height
		CharacterController charController = gameObject.GetComponent();
		if (charController != null)
			initialHeight = charController.height;
	}
 
	// Requires the GameObject to have a method call to: SendMessage("DamageTaken", int)
    void DamageTaken(int damageAmount)
    {
		// Create a new text object and set the starting height and text
        GameObject textInstance = (GameObject)Instantiate(TextPrefab);
        textInstance.transform.parent = gameObject.transform;
        textInstance.transform.localPosition = new Vector3(0, initialHeight, 0);
 
        TextMesh mesh = textInstance.GetComponent<TextMesh>();
        mesh.text = damageAmount.ToString();
 
		// Add to the list of floating text objects to update every frame
        floatingTextObjects.Add(textInstance);
    }
 
	// Update is called once per frame
    void Update()
    {
		// Cache all text meshes to be deleted and later delete them
        List objectsToDelete = new List();
 
        foreach (GameObject floatingTextObject in floatingTextObjects)
        {
			float riseDelta = Time.deltaTime * RiseRate;
            Vector3 newPosition = new Vector3(floatingTextObject.transform.localPosition.x, floatingTextObject.transform.localPosition.y + riseDelta, floatingTextObject.transform.localPosition.z);
            floatingTextObject.transform.localPosition = newPosition;
            floatingTextObject.transform.LookAt(floatingTextObject.transform.position + Camera.mainCamera.transform.forward);
 
			// Delete this floating text object if it exceeds our RiseHeight property
            if (floatingTextObject.transform.localPosition.y &gt;= initialHeight + RiseHeight)
            {
                objectsToDelete.Add(floatingTextObject);
            }
        }
 
        foreach (GameObject objectToDelete in objectsToDelete)
        {
            floatingTextObjects.Remove(objectToDelete);
            Destroy(objectToDelete);
        }
    }
}

1 Comment

  • That was an interesting read. For my game Traces of Illumination, I originally created just a simple way of showing messages on the bottom of the screen for all kinds of game messages and tutorials. As I needed the same feature for other games I made it more general purpose and it eventually became ScoreFlash – Scrolling Combat Text on Steroids. This meanwhile has become a package I’m selling through the Unity Asset Store (full source code is included, so you might be interested in having a look ;-) ).

    Originally, I only used UnityGUI – but it now also has support for NGUI and EZ GUI for rendering, and it has PlayMaker actions. One interesting thing about the NGUI / EZ GUI integration is that the framework I created for this could also be used to “post” images or fully built achievements (i.e. background, several texts etc).

Leave a comment