attack damage scrolling

I’m trying to create basic combat text and the way I was thinking of doing it is spawning a new guiText object everytime you take damage. I’m just unsure about how to spawn multiple instances of the same guitext for each different ammount of damage you take and then scroll for a while upwards before deleting the object completly.

I did it with GUIText. That’s the sequence:

1- Create a GUIText and select its properties (font, size etc.)

2- Create the script below and add it to the GUIText:

public var color: Color = Color(0.8,0.8,0,1.0);
public var scroll: float = 0.05;  // scrolling velocity
public var duration: float = 1.5; // time to die
public var alpha: float;

function Start(){
	guiText.material.color = color; // set text color
	alpha = 1;
}

function Update(){
	if (alpha>0){
		transform.position.y += scroll*Time.deltaTime; 
		alpha -= Time.deltaTime/duration; 
		guiText.material.color.a = alpha;		
	} else {
		Destroy(gameObject); // text vanished - destroy itself
	}
}

3- Drag the GUIText from Hierarchy to Project view to make it a prefab

4- Add these lines to the script where the effect will be fired:

var ptsPrefab: Transform; // drag the prefab to this variable in Inspector

function SpawnPts(points: float, x: float, y: float){
    x = Mathf.Clamp(x,0.05,0.95); // clamp position to screen to ensure
    y = Mathf.Clamp(y,0.05,0.9);  // the string will be visible
    var gui: Transform = Instantiate(ptsPrefab,Vector3(x,y,0),Quaternion.identity);
    gui.guiText.text = points.ToString();
}

5- Drag the prefab you’ve made to the ptsPrefab var in the Inspector

Done! If you fire the effect calling something like this:

SpawnPts(150,0.3,0.4);

you will see a yellow 150 appearing at the GUI position 0.3,0.4 and going up while vanishing to death.

EDITED: If you want it to appear at the position the object is picked, use this in the object’s OnTriggerEnter function:

var v:Vector3 = Camera.main.WorldToViewportPoint(transform.position);
SpawnPts(100, v.x, v.y); // 100 points picked

If it’s a damage value, you can create the scrolling points in the ApplyDamage (or equivalent) function, using the hit point as the origin (called hitPoint here):

var v:Vector3 = Camera.main.WorldToViewportPoint(hitPoint);
SpawnPts(damage, v.x, v.y);

I’ve done that with GUITexts, and it does work OK. A few ways to do it (I currently use an array and ONGui to make them all for the entire sceeen.)

Make a GUIText prefab with a script on it. When you get hit, Instantiate the GUItext prefab and fill in the value. Don’t worry about position or rotation, since the script will be setting those. Rough idea:

// Whenever we do damage:
// spawn floating damage text, position/rotation won't matter:
Transform damageText = Instantiate(dmgPrefab, Vector3.zero, Quaternion.identity);
// set text:
damageText.GUIText.Text = "-4";
// set color if we added a GUIstyle:
damageText.GetComponent<dmgPrefabScript>().GStyle.color = Color.red;
// set target to thing we hit:
damageText.GetComponent<dmgPrefabScript>().target = orcThatgotHit;


// the GUIText script:

Transform target; // the guy I am on. Filled in by the guy who Instantiates me
float rise=0; // 0 to 0.5 -- what % of the screen I am up

void Update() {
  // Find spot to draw it on the sceen:
  // GUITexts are in screen coords: 0-1 L/R, 0-1 U/D
  // this converts the orc's (x,y,z) into the screen spot:
  transform.position = Camera.WorldToScreen(target);
  // -z means it is behind us (I think)
  if(transformtarget.z<0) transform.position = Vector3.up*100; // off screen
  // it is now ON the orc, move it up:
  transform.position += rise * Vector3.up;

  // rise up a little for next frame:
  rise += 0.02f; // this a percent of the screen, per frame, so small

  // Could die after 2 secs, but dieing after going up 50% is easier:
  //fading out would be cooler, but more work:
  if(rise>0.5f) Destroy(gameObject);
}

Thank for aldonaletto’s answer. I reference his code and make some changes for C# and Unity5. Additional, I add another display mode via using TextMesh. Here is my code (it’s tested, should be work. BTW, I use it in a 2D game.):

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class FlyingText : MonoBehaviour {
	// attributes
	public float speed = 0.0f;
	public float duration = 20f;
	public float alpha = 1f;
	public bool bTextMesh = false;

	// this will create a UI text game object in the passed canvas transform
	// parameters: pos - it should be a world space position value
	//             parentTransform - it should be a canvas game object's transform
	public static FlyingText getInstance(string text, Vector3 pos, int fontSize, Color color, float speed, float duration, Transform parentTransform) {
		// create game object
		GameObject obj = new GameObject ("Flying Text");
		obj.transform.parent = parentTransform;
		obj.transform.position = Camera.main.WorldToScreenPoint (pos);
		obj.transform.localScale = new Vector3 (1, 1, 1);

		// add text component
		Text t = obj.AddComponent<Text> ();
		t.text = text;
		t.alignment = TextAnchor.MiddleCenter;
		t.font = Font.CreateDynamicFontFromOSFont ("Arial", 20);
		//t.font = Resources.Load ("Fonts/slkscr") as Font; // use custom font
		t.fontSize = fontSize;
		t.color = color;

		// change rect transform value
		RectTransform rt = obj.GetComponent<RectTransform> ();
		rt.sizeDelta = new Vector2 (200, 40);
		
		// add script component
		FlyingText ft = obj.AddComponent<FlyingText> ();
		ft.bTextMesh = false;
		ft.speed = speed;
		ft.duration = duration;

		return ft;
	}

	// this will create a TextMesh game object in the passed parent transform
	public static FlyingText getInstanceWithTextMesh(string text, Vector3 pos, int fontSize, Color color, float speed, float duration, Transform parentTransform) {
		pos.z = parentTransform.position.z;

		// create game object
		GameObject obj = new GameObject ("Flying Text");
		obj.transform.parent = parentTransform;
		obj.transform.position = pos;
		obj.transform.localScale = new Vector3 (1, 1, 1);
		
		// add text component
		TextMesh t = obj.AddComponent<TextMesh> ();
		t.text = text;
		t.alignment = TextAlignment.Left;
		t.font = Font.CreateDynamicFontFromOSFont ("Arial", 20);
//		t.font = Resources.Load ("Fonts/slkscr") as Font;
		t.fontSize = fontSize;
		t.color = color;
		t.characterSize = 0.1f;

		// assign renderer material
		Renderer r = obj.GetComponent<Renderer> ();
		r.sharedMaterial = t.font.material;

	// set position, make the passed pos parameter as center
	pos.x -= r.bounds.size.x / 2;
	obj.transform.position = pos;
		
		// add script component
		FlyingText ft = obj.AddComponent<FlyingText> ();
		ft.bTextMesh = true;
		ft.speed = speed;
		ft.duration = duration;
		
		return ft;
	}
	
	// Update is called once per frame
	void Update () {
		if (alpha > 0) {
			// change the y position
			Vector3 pos = transform.position;
			pos.y += speed * Time.deltaTime;
			transform.position = pos;

			// change alpha value
			alpha -= Time.deltaTime/duration;

			if( bTextMesh ) {
				TextMesh t = GetComponent<TextMesh> ();
				Color color = t.color;
				color.a = alpha;
				t.color = color;
			} else {
				Text t = GetComponent<Text> ();
				Color color = t.color;
				color.a = alpha;
				t.color = color;
			}
		} else {
			// destroy the game object if it's invisible
			Destroy(gameObject);
		}
	}
}

Usage:

// create a flying text via UI Text
string text = "12345";
Vector2 pos = transform.position;
float speed = 20f;
float duration = 5f;
GameObject canvas = GameObject.Find ("UICanvas");
FlyingText.getInstance (text, pos, 20, Color.red, speed, duration, canvas.transform);

// create a flying text via TextMesh
speed = 0.3f;
Transform parentTransform = GameObject.Find ("Someone").transform;
FlyingText.getInstanceWithTextMesh(text, pos, 24, Color.red, speed, duration, parentTransform);

That’s it. The following is the screenshot of testing result.
57901-flying-text.png

Hello, this post and the aldonaletto answer is a little old, but i think it is very helpful, so I updated it a little for C# bellow:
Like he said, create the GUIText and use this script bellow inside this GUIText’s public class monoBehaviour :

	public Color color = new Color(0.8f,0.8f,0,1.0f);
	public float scroll = 0.02f;  // scrolling velocity
	public float duration = 4.5f; // time to die
	public float alpha;
	
	void  Start (){
		GetComponent<GUIText>().material.color = color; // set text color
		alpha = 1;
	}
	
	void  Update (){
		if (alpha>0){
			Vector3 temp = transform.position; 
			temp.y += scroll*Time.deltaTime;
			transform.position = temp;
			alpha -= Time.deltaTime/duration; 
			Color tempC=GetComponent<GUIText>().material.color;
			tempC.a=alpha;
			GetComponent<GUIText>().material.color=tempC;       
		} else {
			Destroy(gameObject); // text vanished - destroy itself
		}
	}

So do what he said, transform it in a prefab dragging to project view. And inside the code where you want to fire it use this code bellow:

public Transform ptsPrefab;

void  SpawnPts ( float points ,   float x ,   float y  ){
		x = Mathf.Clamp(x,0.05f,0.95f); // clamp position to screen to ensure
		y = Mathf.Clamp(y,0.05f,0.9f);  // the string will be visible
		Transform gui = Instantiate(ptsPrefab,new Vector3(x,y,0),Quaternion.identity) as Transform;
		gui.GetComponent<GUIText>().text = points.ToString();
	}

Drag the prefab to the inspector inside the public ptsPrefab and you can fire it with:

Vector3 v= Camera.main.WorldToViewportPoint(transform.position);
SpawnPts(150,v.x,v.y);

This is untested code, but give this a try:

private var damageList:String[];
private var scrollPosition:Vector2 = Vector2.zero;

function addNewDamage(d:String):void
{
    damageList.push(d);
    yield WaitForSeconds (5);
    if(damageList.Length > 0)
       damageList.Shift();
}

function OnGUI()
{
     scrollPosition = GUILayout.BeginScrollView (scrollPosition ,500,300);
     for(var i:int = damageList.Length-1; i >= 0; i--)
     {
        GUILayout.Label(GUIContent (damageList*));*

}
GUILayout.EndScrollView();
}

// this goes in the function where you get damaged
addNewDamage(“Gun shot -15”);