利用网格去绘制血条
血条肯定是一个矩形,网格是由一个一个三角形组成的,
矩形可以分成两个三角形。
创建一个空物体,添加以下脚本组件
1 [RequireComponent(typeof(MeshFilter),typeof(MeshRenderer))]
2 public class MeshAndUV : MonoBehaviour
3 {
4
5 private Mesh mh;
6 private Renderer rd;
7 private float size = 1;
8 private Material mat;
9 void Awake()
10 {
11 mh = GetComponent<MeshFilter>().mesh;
12 rd = GetComponent<MeshRenderer>();
13 }
14
15 void Start()
16 {
17
18 //顶点数组
19 Vector3[] vertes = new Vector3[]
20 {
21 new Vector3(-size, -size, 0),//第一个点
22 new Vector3(-size, size, 0), //第二个
23 new Vector3(size, size, 0), //第三个
24 new Vector3(size, -size, 0), //第四个
25 };
26
27 mh.vertices = vertes;
28
29 //顶点组成的三角形
30 mh.triangles = new[]
31 {
32 0, 1, 2,
33 0, 2, 3
34 };
35 mh.RecalculateNormals();
36 }
37 }
38
运行下,就发现绘制出一个粉红色的矩形,为啥是粉红色,因为没材质啊
在scene视图下把ShadingMode改为Wireframe模式就可以看到两个三角形
轴点在中心,边长为2的矩形
然后在脚本上设置UV映射,加上贴图材质。
在设置三角形下面添加
1 //UV贴图的四个点,和顶点一一对应,左下角为(0,0),右上角为(1,1)
2 //如果顶点顺序没有跟UV对应,贴图就会出现问题
3 Vector2[] uvs = new Vector2[]
4 {
5 new Vector2(0,0),//第一个点
6 new Vector2(0,1),//2
7 new Vector2(1,1),//3
8 new Vector2(1,0), //4
9 };
10
11 mh.uv = uvs;
12 rd.material = mat;
就可以把这张图绘制出来的
效果如下
这张图包含了HP,MP,我们就要把它们区分开来。
封装成一个函数 void CreateBar(int barIndex)
修改UV映射
血条索引从下往上数,每个间隔0.25f
1 Vector2[] uvs = new Vector2[]
2 {
3 new Vector2(0, 0.25f * barIndex),//第一个点
4 new Vector2(0, 0.25f * (barIndex+1)),//2
5 new Vector2(1, 0.25f * (barIndex+1)),//3
6 new Vector2(1, 0.25f * barIndex), //4
7 };
8
在Start方法调用 CreateBar(0)
效果如下
由于满血状态是全红的,所以在UV的x映射也要做下改变
Vector2[] uvs = new Vector2[]
{
new Vector2(0, 0.25f * barIndex),//第一个点
new Vector2(0, 0.25f * (barIndex+1)),//2
new Vector2(0.5f, 0.25f * (barIndex+1)),//3
new Vector2(0.5f, 0.25f * barIndex), //4
};
是不是有点像啦。只要改变下长宽比就好看啦。
函数添加多一个参数
void CreateBar(Vector2 size, int barIndex)
修改下顶点数组
Vector3[] vertes = new Vector3[]
{
new Vector3(-size.x, -size.y, 0),//第一个点
new Vector3(-size.x, size.y, 0), //第二个
new Vector3(size.x, size.y, 0), //第三个
new Vector3(size.x, -size.y, 0), //第四个
};
调用下函数
void Start()
{
CreateBar(new Vector2(1,0.25f),0 );
}
效果如下
改变血条的值有点个办法,
第一个是改变Material的mainTextureOffset值
mat.mainTextureOffset = new Vector2(0.2f,0);
但是这样会令到所以使用者材质的物体贴图都会改变
第二个办法就是修改UV映射
void SetBarRate(float value)
{
value *= 0.5f;
Vector2[] uvs = new Vector2[]
{
new Vector2(value, 0.25f * barIndex),//第一个点
new Vector2(value, 0.25f * (barIndex+1)),//2
new Vector2(0.5f + value , 0.25f * (barIndex+1)),//3
new Vector2(0.5f + value, 0.25f * barIndex), //4
};
mh.uv = uvs;
}
//因为这张图一半是亮的,一半是暗的,暗的那部分代表失去的血量,所以value要乘以0.5;
void Start()
{
CreateBar(new Vector2(1,0.25f),0 );
SetBarRate(0.9f);
}
效果如下
做到这里就差不多完成了,利用网格去绘制血条。
最终代码
1 using UnityEngine;
2 using System.Collections;
3
4 [RequireComponent(typeof(MeshFilter),typeof(MeshRenderer))]
5 public class MeshAndUV : MonoBehaviour
6 {
7
8 private Mesh mh;
9 private Renderer rd;
10
11 private float rate = 0.5f;
12 public Material mat;
13
14 private int barIndex = 0;
15 void Awake()
16 {
17 mh = GetComponent<MeshFilter>().mesh;
18 rd = GetComponent<MeshRenderer>();
19
20 }
21
22 void Start()
23 {
24 CreateBar(new Vector2(1,0.25f),0 );
25 SetBarRate(0.9f);
26 }
27
28 /// <summary>
29 /// 利用网格创建血条
30 /// </summary>
31 /// <param name="size">三角形大小</param>
32 /// <param name="barIndex">血条索引</param>
33 void CreateBar(Vector2 size, int barIndex)
34 {
35 this.barIndex = barIndex;
36
37 //顶点数组
38 Vector3[] vertes = new Vector3[]
39 {
40 new Vector3(-size.x, -size.y, 0),//第一个点
41 new Vector3(-size.x, size.y, 0), //第二个
42 new Vector3(size.x, size.y, 0), //第三个
43 new Vector3(size.x, -size.y, 0), //第四个
44 };
45
46 //给网格的顶点赋值
47 mh.vertices = vertes;
48
49 //顶点组成的三角形
50 mh.triangles = new[]
51 {
52 0, 1, 2,
53 0, 2, 3
54 };
55
56 //UV贴图的四个点,和顶点一一对应,左下角为(0,0),右上角为(1,1)
57 //如果顶点顺序没有跟UV对应,贴图就会出现问题
58 Vector2[] uvs = new Vector2[]
59 {
60 new Vector2(0, 0.25f * barIndex),//第一个点
61 new Vector2(0, 0.25f * (barIndex+1)),//2
62 new Vector2(0.5f , 0.25f * (barIndex+1)),//3
63 new Vector2(0.5f , 0.25f * barIndex), //4
64 };
65
66 mh.uv = uvs;
67
68 //材质
69 rd.material = mat;
70
71 //法线重新计算
72 mh.RecalculateNormals();
73
74 }
75
76 /// <summary>
77 /// 设置血条比例
78 /// </summary>
79 /// <param name="value">血量失去的百分比</param>
80 void SetBarRate(float value)
81 {
82 value *= 0.5f;
83 Vector2[] uvs = new Vector2[]
84 {
85 new Vector2(value, 0.25f * barIndex),//第一个点
86 new Vector2(value, 0.25f * (barIndex+1)),//2
87 new Vector2(0.5f + value , 0.25f * (barIndex+1)),//3
88 new Vector2(0.5f + value, 0.25f * barIndex), //4
89 };
90 mh.uv = uvs;
91 }
92
93
94 }