人物的名称与血条的绘制方法很简单,但是我们需要解决的问题是如何在3D世界中寻找合适的坐标。因为3D世界中的人物是会移动的,它是在3D世界中移动,并不是在2D平面中移动,但是我们需要将3D的人物坐标换算成2D平面中的坐标,继而找到人物头顶在屏幕中的2D坐标最后使用GUI将名称与血条绘制出来。
首先学习本文的重点内容,如何将游戏世界中任意3D坐标转换成屏幕中的2D坐标。根据这个方法计算出的2D坐标屏幕左下角的点为0.0 ,屏幕右上角的坐标为1.1 所以真实的2D坐标还得通过Screen.height 与Screen.width计算一下才行。
1
Vector2 position = camera.WorldToScreenPoint (worldPosition);
在unity工程导入角色控制器组件,不知道角色控制器的朋友请阅读我之前的文章哈。创建一个Plane做为游戏的地面,然后利用角色控制器组件创建两个模型,一个做为主角,一个作为NPC,主角可以通过控制来移动从四周来观察NPC对象。由于地面的面积比较小移动主角时为了避免主角越界掉下去,我们做一个边界的物理层。物理层其实很简单,就是给平面四周放置四个平面在四周将平面包围着,给四周的四个平面绑定上Box
Collider组件,这样主角就不会越界掉下去啦。因为没有给贴图所以效果上看不到这四个对象。 如下图所示,在场景是途中主角被四个平面包围这,即时它拼命的想往外条但是还是跳不出去。
创建脚本NPC.cs 然后把脚本挂在NPC对象身上,在脚本中我们绘制主角的血条以及名称。
-
NPC.cs
-
001
-
using UnityEngine;
-
002
-
using System.Collections;
-
003
-
-
004
-
public class NPC : MonoBehaviour {
-
005
-
-
006
-
//主摄像机对象
-
007
-
private Camera camera;
-
008
-
//NPC名称
-
009
-
private string name = "我是雨松MOMO";
-
010
-
-
011
-
//主角对象
-
012
-
GameObject hero;
-
013
-
//NPC模型高度
-
014
-
float npcHeight;
-
015
-
//红色血条贴图
-
016
-
public Texture2D blood_red;
-
017
-
//黑色血条贴图
-
018
-
public Texture2D blood_black;
-
019
-
//默认NPC血值
-
020
-
private int HP = 100;
-
021
-
-
022
-
void Start ()
-
023
-
{
-
024
-
//根据Tag得到主角对象
-
025
-
hero = GameObject.FindGameObjectWithTag("Player");
-
026
-
//得到摄像机对象
-
027
-
camera = Camera.main;
-
028
-
-
029
-
//注解1
-
030
-
//得到模型原始高度
-
031
-
float size_y = collider.bounds.size.y;
-
032
-
//得到模型缩放比例
-
033
-
float scal_y = transform.localScale.y;
-
034
-
//它们的乘积就是高度
-
035
-
npcHeight = (size_y *scal_y) ;
-
036
-
-
037
-
}
-
038
-
-
039
-
void Update ()
-
040
-
{
-
041
-
//保持NPC一直面朝主角
-
042
-
transform.LookAt(hero.transform);
-
043
-
}
-
044
-
-
045
-
void OnGUI()
-
046
-
{
-
047
-
//得到NPC头顶在3D世界中的坐标
-
048
-
//默认NPC坐标点在脚底下,所以这里加上npcHeight它模型的高度即可
-
049
-
Vector3 worldPosition = new Vector3 (transform.position.x , transform.position.y + npcHeight,transform.position.z);
-
050
-
//根据NPC头顶的3D坐标换算成它在2D屏幕中的坐标
-
051
-
Vector2 position = camera.WorldToScreenPoint (worldPosition);
-
052
-
//得到真实NPC头顶的2D坐标
-
053
-
position = new Vector2 (position.x, Screen.height - position.y);
-
054
-
//注解2
-
055
-
//计算出血条的宽高
-
056
-
Vector2 bloodSize = GUI.skin.label.CalcSize (new GUIContent(blood_red));
-
057
-
-
058
-
//通过血值计算红色血条显示区域
-
059
-
int blood_width = blood_red.width * HP/100;
-
060
-
//先绘制黑色血条
-
061
-
GUI.DrawTexture(new Rect(position.x - (bloodSize.x/2),position.y - bloodSize.y ,bloodSize.x,bloodSize.y),blood_black);
-
062
-
//在绘制红色血条
-
063
-
GUI.DrawTexture(new Rect(position.x - (bloodSize.x/2),position.y - bloodSize.y ,blood_width,bloodSize.y),blood_red);
-
064
-
-
065
-
//注解3
-
066
-
//计算NPC名称的宽高
-
067
-
Vector2 nameSize = GUI.skin.label.CalcSize (new GUIContent(name));
-
068
-
//设置显示颜色为黄色
-
069
-
GUI.color = Color.yellow;
-
070
-
//绘制NPC名称
-
071
-
GUI.Label(new Rect(position.x - (nameSize.x/2),position.y - nameSize.y - bloodSize.y ,nameSize.x,nameSize.y), name);
-
072
-
-
073
-
}
-
074
-
-
075
-
//下面是经典鼠标点击对象的事件,大家看一下就应该知道是什么意思啦。
-
076
-
void OnMouseDrag ()
-
077
-
{
-
078
-
Debug.Log("鼠标拖动该模型区域时");
-
079
-
}
-
080
-
-
081
-
void OnMouseDown()
-
082
-
{
-
083
-
Debug.Log("鼠标按下时");
-
084
-
-
085
-
if(HP >0)
-
086
-
{
-
087
-
HP -=5 ;
-
088
-
}
-
089
-
-
090
-
}
-
091
-
void OnMouseUp()
-
092
-
{
-
093
-
Debug.Log("鼠标抬起时");
-
094
-
}
-
095
-
-
096
-
void OnMouseEnter()
-
097
-
{
-
098
-
Debug.Log("鼠标进入该对象区域时");
-
099
-
}
-
100
-
void OnMouseExit()
-
101
-
{
-
102
-
Debug.Log("鼠标离开该模型区域时");
-
103
-
}
-
104
-
void OnMouseOver()
-
105
-
{
-
106
-
Debug.Log("鼠标停留在该对象区域时");
-
107
-
}
-
108
-
-
109
-
}
复制代码
注解1:通过collider.bounds.size 可以拿到模型对应三个轴向的高度,但是模型是可以缩放的,所以真实的模型高度应当是原始高度乘以缩放系数才行。 transform.localScale可以拿到模型对应三个轴向的缩放系数,因为这里我们需要模型的高度,所以忽略X轴与Z轴。
注解2:在这里我们计算血条的宽度,GUI.skin.label.Calcsize()这个方法是以默认的皮肤对象Label对象去参数对象的宽高。参数是new GUIContent(blood_Red)意思是拿红色血条的贴图的宽高,它将保存在返回的size中。最后以宽高将血条绘制在屏幕中,我们的血条采取两层。背景是黑色的,前面是红色的,当人物费血时红色血条减少。
注解3: 这里通过字符串来获取它整体的宽度与高度,因为NPC的名称是可变的,所以我们需要动态的获取整体的显示区域。同样是以GUI.skin.label对象去调用CalcSize。【狗刨学习网】
如下图所示,当使用鼠标点击NPC对象时,NPC头顶的血条将开始发生减血。这个例子我使用OnGUI绘制当然大家也可以在Hierarchy 视图中的创建GUI Texture 或者GUI Text对象 来实现,不过原理都是这样的 大家可以试试。
Unity3d人物的名称与血条的绘制方法
原文:http://blog.csdn.net/book_longssl/article/details/43907617