人物的名稱與血條的繪制方法很簡單,但是我們需要解決的問題是如何在3D世界中尋找合適的坐標(biāo)。因為3D世界中的人物是會移動的,它是在3D世界中移動,并不是在2D平面中移動
首先學(xué)習(xí)本文的重點內(nèi)容,如何將游戲世界中任意3D坐標(biāo)轉(zhuǎn)換成屏幕中的2D坐標(biāo)。根據(jù)這個方法計算出的2D坐標(biāo)屏幕左下角的點為0.0 ,屏幕右上角的坐標(biāo)為1.1 所以真實的2D坐標(biāo)還得通過Screen.height 與Screen.width計算一下才行。
[代碼]c#/cpp/oc代碼:
1 |
Vector2 position = camera.WorldToScreenPoint (worldPosition); |
在Unity工程導(dǎo)入角色控制器組件,不知道角色控制器的朋友請閱讀我之前的文章哈。創(chuàng)建一個Plane做為游戲的地面,然后利用角色控制器組件創(chuàng)建兩個模型,一個做為主角,一個作為NPC,主角可以通過控制來移動從四周來觀察NPC對象。由于地面的面積比較小移動主角時為了避免主角越界掉下去,我們做一個邊界的物理層。物理層其實很簡單,就是給平面四周放置四個平面在四周將平面包圍著,給四周的四個平面綁定上Box Collider組件,這樣主角就不會越界掉下去啦。因為沒有給貼圖所以效果上看不到這四個對象。哇咔咔~ 如下圖所示,在場景是途中主角被四個平面包圍這,即時它拼命的想往外條但是還是跳不出去,哈哈。

創(chuàng)建腳本NPC.cs 然后把腳本掛在NPC對象身上,在腳本中我們繪制主角的血條以及名稱。
NPC.cs
[代碼]c#/cpp/oc代碼:
002 |
using System.Collections; |
004 |
public class NPC : MonoBehaviour { |
007 |
private Camera camera; |
009 |
private string name = "我是雨松MOMO"; |
016 |
public Texture2D blood_red; |
018 |
public Texture2D blood_black; |
020 |
private int HP = 100; |
025 |
hero = GameObject.FindGameObjectWithTag("Player"); |
027 |
camera = Camera.main; |
031 |
float size_y = collider.bounds.size.y; |
033 |
float scal_y = transform.localScale.y; |
035 |
npcHeight = (size_y *scal_y) ; |
042 |
transform.LookAt(hero.transform); |
047 |
//得到NPC頭頂在3D世界中的坐標(biāo) |
048 |
//默認NPC坐標(biāo)點在腳底下,所以這里加上npcHeight它模型的高度即可 |
049 |
Vector3 worldPosition = new Vector3 (transform.position.x , transform.position.y + npcHeight,transform.position.z); |
050 |
//根據(jù)NPC頭頂?shù)?D坐標(biāo)換算成它在2D屏幕中的坐標(biāo) |
051 |
Vector2 position = camera.WorldToScreenPoint (worldPosition); |
052 |
//得到真實NPC頭頂?shù)?D坐標(biāo) |
053 |
position = new Vector2 (position.x, Screen.height - position.y); |
056 |
Vector2 bloodSize = GUI.skin.label.CalcSize (new GUIContent(blood_red)); |
059 |
int blood_width = blood_red.width * HP/100; |
061 |
GUI.DrawTexture(new Rect(position.x - (bloodSize.x/2),position.y - bloodSize.y ,bloodSize.x,bloodSize.y),blood_black); |
063 |
GUI.DrawTexture(new Rect(position.x - (bloodSize.x/2),position.y - bloodSize.y ,blood_width,bloodSize.y),blood_red); |
067 |
Vector2 nameSize = GUI.skin.label.CalcSize (new GUIContent(name)); |
069 |
GUI.color = Color.yellow; |
071 |
GUI.Label(new Rect(position.x - (nameSize.x/2),position.y - nameSize.y - bloodSize.y ,nameSize.x,nameSize.y), name); |
075 |
//下面是經(jīng)典鼠標(biāo)點擊對象的事件,大家看一下就應(yīng)該知道是什么意思啦。 |
078 |
Debug.Log("鼠標(biāo)拖動該模型區(qū)域時"); |
083 |
Debug.Log("鼠標(biāo)按下時"); |
093 |
Debug.Log("鼠標(biāo)抬起時"); |
098 |
Debug.Log("鼠標(biāo)進入該對象區(qū)域時"); |
102 |
Debug.Log("鼠標(biāo)離開該模型區(qū)域時"); |
106 |
Debug.Log("鼠標(biāo)停留在該對象區(qū)域時"); |
注解1:通過collider.bounds.size 可以拿到模型對應(yīng)三個軸向的高度,但是模型是可以縮放的,所以真實的模型高度應(yīng)當(dāng)是原始高度乘以縮放系數(shù)才行。 transform.localScale可以拿到模型對應(yīng)三個軸向的縮放系數(shù),因為這里我們需要模型的高度,所以忽略X軸與Z軸。
注解2:在這里我們計算血條的寬度,GUI.skin.label.Calcsize()這個方法是以默認的皮膚對象Label對象去參數(shù)對象的寬高。參數(shù)是new GUIContent(blood_Red)意思是拿紅色血條的貼圖的寬高,它將保存在返回的size中。最后以寬高將血條繪制在屏幕中,我們的血條采取兩層。背景是黑色的,前面是紅色的,當(dāng)人物費血時紅色血條減少。
注解3: 這里通過字符串來獲取它整體的寬度與高度,因為NPC的名稱是可變的,所以我們需要動態(tài)的獲取整體的顯示區(qū)域。同樣是以GUI.skin.label對象去調(diào)用CalcSize。
如下圖所示,當(dāng)使用鼠標(biāo)點擊NPC對象時,NPC頭頂?shù)难獥l將開始發(fā)生減血。這個例子我使用OnGUI繪制當(dāng)然大家也可以在Hierarchy 視圖中的創(chuàng)建GUI Texture 或者GUI Text對象 來實現(xiàn),不過原理都是這樣的 大家可以試試 哇咔咔。
