Unity3D研究院之人物头顶名称与血条更新与绘制(二十六)
来源:互联网 发布:搞笑视频制作软件 编辑:程序博客网 时间:2024/04/26 07:09
http://www.xuanyusong.com/archives/1032
人物的名称与血条的绘制方法很简单,但是我们需要解决的问题是如何在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对象 来实现,不过原理都是这样的 大家可以试试 哇咔咔。
最后雨松MOMO希望和大家一起进步,一起学习,哇咔咔~
本章内容下载地址:http://vdisk.weibo.com/s/abYBx
程序有两点需要注意的地方:
1、当Y轴缩放比例过大时,npcHeight会特别大,后面会导致负值,从而血条在NPC的太上方。1以内没什么明显影响。
2、当背对NPC时,也显示血条。相关代码修改如下:
Vector3 position = camera.WorldToScreenPoint (worldPosition);
if position.z>0
这个程序 有点 问题,在
//根据NPC头顶的3D坐标换算成它在2D屏幕中的坐标
Vector2 position = camera.WorldToScreenPoint (worldPosition);
这个方法 返回的是一个三维坐标,屏幕坐标也是三维,
而且这个程序有个bug 如果你脚本付给敌人,使显示敌人的血量,但是 当你背对敌人,敌人血量也会显示;
我的解决方法是 将敌人的坐标转化为屏幕3D 坐标,并判断z轴 是否大于0,如果小于零代表敌人不在你的 视野内 不显示敌人血量
- Unity3D研究院之人物头顶名称与血条更新与绘制(二十六)
- Unity3D研究院之人物头顶名称与血条更新与绘制一(转)
- Unity3D人物头顶名称与血条更新与绘制
- Unity3D之人物头顶名称与血条更新与绘制
- 人物头顶名称与血条更新与绘制
- Unity3d人物的名称与血条的绘制方法
- Unity 绘制人物头顶的血条
- Unity3D技术之名称与血条绘制详解
- Unity3D 人物头顶名称显示
- Unity3D研究院之与根据动态的两个轨迹点绘制面详解(二十)
- Unity3d GUI人物的名称与hp的绘制方法
- unity3d学习笔记(十九)--ngui制作人物头顶的头像和血条
- Unity3D研究院之FBX模型的载入与人物行走动画的播放(十二)
- Unity3D研究院之游戏对象的访问绘制线与绘制面详解(十七)
- Unity3D研究院之游戏对象的访问绘制线与绘制面详解(十七)
- 【基础】Unity3D研究院之游戏对象的访问绘制线与绘制面详解(十七)
- Unity3D研究院之FBX模型的载入与人物行走动画的播放
- Unity3D研究院之IOS Android支持中文与本地文件的读取写入(二十七)
- 微软开放了.NET 4.5.1 的源代码
- 视图转换的几种方法
- ibm system X3250 M4 服务器安装ubuntu server 12.04
- Android开发者应该知道的Android体系架构和开发库
- [转]解决adb not responding you can wait more
- Unity3D研究院之人物头顶名称与血条更新与绘制(二十六)
- 【C++】PAT(advanced level)1065. A+B and C (64bit) (20)
- POJ 2773 Happy 2006 (公式法 or 二分容斥定理)
- JAVASE_08_@面向对象_多态和Object
- mysql 的小经验
- C++笔试经典题目总结
- 黑马程序员 第二篇:关于继承
- POJ-3258 River Hopscotch 二分枚举求上限
- android平台蓝牙编程