using UnityEngine;
using System.Collections;
public class DamagePopup : MonoBehaviour {
//目標(biāo)位置
private Vector3 mTarget;
//屏幕坐標(biāo)
private Vector3 mScreen;
//傷害數(shù)值
public int Value;
//文本寬度
public float ContentWidth=100;
//文本高度
public float ContentHeight=50;
//GUI坐標(biāo)
private Vector2 mPoint;
//銷毀時間
public float FreeTime=1.5F;
void Start ()
{
//獲取目標(biāo)位置
mTarget=transform.position;
//獲取屏幕坐標(biāo)
mScreen= Camera.main.WorldToScreenPoint(mTarget);
//將屏幕坐標(biāo)轉(zhuǎn)化為GUI坐標(biāo)
mPoint=new Vector2(mScreen.x,Screen.height-mScreen.y);
//開啟自動銷毀線程
StartCoroutine("Free");
}
void Update()
{
//使文本在垂直方向山產(chǎn)生一個偏移
transform.Translate(Vector3.up * 0.5F * Time.deltaTime);
//重新計算坐標(biāo)
mTarget=transform.position;
//獲取屏幕坐標(biāo)
mScreen= Camera.main.WorldToScreenPoint(mTarget);
//將屏幕坐標(biāo)轉(zhuǎn)化為GUI坐標(biāo)
mPoint=new Vector2(mScreen.x,Screen.height-mScreen.y);
}
void OnGUI()
{
//保證目標(biāo)在攝像機(jī)前方
if(mScreen.z>0)
{
//內(nèi)部使用GUI坐標(biāo)進(jìn)行繪制
GUI.Label(new Rect(mPoint.x,mPoint.y,ContentWidth,ContentHeight),Value.ToString());
}
}
IEnumerator Free()
{
yield return new WaitForSeconds(FreeTime);
Destroy(this.gameObject);
}
}
在上面的代碼中我們需要把握下面幾點(diǎn):
1、根據(jù)Transform組件獲取位置坐標(biāo),將此坐標(biāo)轉(zhuǎn)化為屏幕坐標(biāo)及GUI坐標(biāo)。
2、常見的四種坐標(biāo)系:
a、世界坐標(biāo):場景中物體的坐標(biāo),使用 transform.position獲得。
b、屏幕坐標(biāo):以像素來定義的,以屏幕的左下角為(0,0)點(diǎn),右上角為(Screen.width,Screen.height),Z的位置是以相機(jī)的世界單位來衡量的。如Input.mousePosition即為屏幕坐標(biāo)。
c、視口坐標(biāo):視口坐標(biāo)是標(biāo)準(zhǔn)的和相對于相機(jī)的。相機(jī)的左下角為(0,0)點(diǎn),右上角為(1,1)點(diǎn),Z的位置是以相機(jī)的世界單位來衡量的。
d、GUI坐標(biāo):該坐標(biāo)系以屏幕的左上角為(0,0)點(diǎn),右下角為(Screen.width,Screen.height)。
3、在代碼中我們將世界坐標(biāo)先轉(zhuǎn)化為屏幕坐標(biāo),再轉(zhuǎn)化為GUI坐標(biāo)
好了,下面我們將這個腳本綁定在一個空的游戲體上,并制作成預(yù)設(shè),在下面的示例中,我們將使用這個預(yù)設(shè)。
如圖,我們希望實(shí)現(xiàn)當(dāng)角色攻擊紅色的膠囊體時,在游戲場景中顯示玩家對膠囊體造成的傷害值。具體怎么做呢?我們可以先給模型和膠囊體加上碰撞器,并勾選IsTrigger使其成為一個觸發(fā)器。我們分別將他們的tag設(shè)為Player和Enemy。接下來,為Enemy編寫一個腳本:[csharp] view plaincopyprint?using UnityEngine;? using System.Collections;? ? public class Enemy : MonoBehaviour {? ? ? ? public GameObject PopupDamage;? ? ? ? void OnTriggerEnter(Collider mCollider)? ? ? {? ? ? ? ? if(mCollider.gameObject.tag=="Player")? ? ? ? ? {? ? ? ? ? ? ? //克隆傷害彈出組件? ? ? ? ? ? ? GameObject mObject=(GameObject)Instantiate(PopupDamage,transform.position,Quaternion.identity);? ? ? ? ? ? ? mObject.GetComponent().Value=Random.Range(20,40);
}
}
}
這里我們設(shè)定玩家對敵人造成的傷害值為20到40,運(yùn)行程序,我們會得到下面的結(jié)果:
由于這里使用的是非精確碰撞,所以導(dǎo)致程序一開始角色就和膠囊體發(fā)生了碰撞,而OnTrigger()方法由于只能在碰撞開始的時候捕捉碰撞,所以這里只顯示了一次傷害值。理論上只有當(dāng)玩家攻擊膠囊體,才會觸發(fā)傷害值的顯示,不過這個問題再這里我們可以先不追究,因?yàn)槲覀冴P(guān)注的是傷害數(shù)值的顯示。到目前為止,這個問題已經(jīng)圓滿的解決了。
有朋友可能會問:為什么人家的游戲里顯示的傷害效果看起來那么眩目,而你的程序卻只能顯示普普通通的文字呢?對于這個問題,我們這里給出兩種思路,留給大家自己去探究啊。第一種方法是在項目中創(chuàng)建一個GUISkin,然后在DamagePopup腳本中添加一個GUIStyle類型的成員變量mStyle,通過該變量我們可以引用到在項目中創(chuàng)建的GUISkin。這樣,我們就可以定義整體的GUI樣式。此時,我們將OnGUI中的方法修改為:
GUI.Label(new Rect(mPoint.x,mPoint.y,ContentWidth,ContentHeight),Value.ToString(),mStyle);
這樣我們就可以實(shí)現(xiàn)自定義的文字效果了。第二種方法是使用貼圖,即首先準(zhǔn)備0-9的數(shù)字圖片,然后我們將Value各個數(shù)位上的數(shù)字分別截取出來,根據(jù)截取的結(jié)果來繪制貼圖,這樣同樣可以實(shí)現(xiàn)自定義的效果。好了,今天的內(nèi)容就是這樣了.