刚好今天有朋友问我,比较典型的例子就是游戏里面人物的血条。原理很简单就是把3d点换算成2d的点,但是由于ngui自身是3d所以我们需要先把ngui下的点转成2d点,然后在把他转成3d的点。听起来有点绕,不要紧我直接上代码。对屏幕自适应不明白的看ngui研究之如何自适应屏幕
目前我一直都是用ngui来做人物血条,但是2d血条都会有个限制,就是它不能和模型有遮挡关系。不过血条可以根据人物的位置调节,比如远一点的人物血条会小一些,近一点的人物血条会大一些。
最好让美术做fbx的时候直接内置一个gameobject 的点,因为模型有的高有的低,所以血条的位置高度是不一样的,如果美术内置的话可以让美术来调节模型头顶上的点,这样比较方便。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
usingunityengine;
using system.collections;
publicclassnewbehaviourscript:monobehaviour{
//角色
publictransform cube;
//角色的血条
publictransform ui;
//默认血条缩与摄像机的距离
privatefloatfomat;
//角色头顶的点, 最好让美术把这个点直接做在fbx模型里面。
privatetransform head;
voidstart()
{
//找到角色身上头顶的点
head=cube.find(head);
//计算以下默认血条的距离,也可以写个常量,就是标记一下
fomat =vector3.distance(head.position,camera.main.transform.position);
}
voidupdate()
{
//这里可以判断一下 如果位置没有变化就不要在赋值了
floatnewfomat=fomat/vector3.distance(head.position,camera.main.transform.position);
ui.position =worldtoui(head.position);
//计算出血条的缩放比例
ui.localscale=vector3.one *newfomat;
//测试代码,按下w s键前后移动角色
if(input.getkey(keycode.w))
cube.translate(vector3.forward);
if(input.getkey(keycode.s))
cube.translate(vector3.back);
}
//核心代码在这里把3d点换算成ngui屏幕上的2d点。
publicstaticvector3worldtoui(vector3point)
{
vector3 pt=camera.main.worldtoscreenpoint(point);
//我发现有时候uicamera.currentcamera 有时候currentcamera会取错,取的时候注意一下啊。
vector3 ff= uicamera.currentcamera.screentoworldpoint(pt);
//ui的话z轴 等于0
ff.z=0;
returnff;
}
}
再说一下,一般血条可能都是由多个uisprite组成,那么最好把这些sprite都挂在同一个gameobject下面,这样只需要修正父对象,所以子对象的缩放都会正确。控制角色移动近一点的截图。
控制角色移动远一点的截图,你会发现血条在屏幕上的比例是不会变化的。
祝大家学习愉快,欢迎讨论,嘿嘿嘿嘿