在游戏的战斗中经常需要使用到一个能够跟随人物位置变化而变化的血条,由于项目用到,就动手写了一个,作为巩固一下里面需要用到的坐标变换的知识。
我们项目中ui层使用的照相机跟场景中的照相机是独立的,所以这个例子中需要两个照相机,一个用来显示血条,另外一个用来显示角色,当然,需要保证角色的屏幕坐标跟血条的屏幕坐标要保持一致。惯例先来上最终效果图:
上面三幅图中,不管球体怎么移动,血条在屏幕上的坐标始终是跟它的屏幕坐标是一致的。下面来讲解一下制作过程。
1,创建两个照相机,分别为camera1,camera2,其中camera1对准的是球体,camera2则是画布的照相机。
2,创建画布,将画布的renderCamera设置为camera2,画布上添加一个血条。
3,给血条添加一个脚本,脚本代码如下:
using UnityEngine;
using System.Collections;
public class BloodBar : MonoBehaviour
{
public Transform m_tagTrans;//传进来跟随的物体,这里就是一个球体,游戏中可以为角色
public Camera m_cam;<span style="white-space:pre"> </span>//画布的renderCamera
public UnityEngine.Canvas m_canvas;//画布
public UnityEngine.UI.Image img;
private float m_curBlood = 0.0f;
private float m_tagBlood = 0.5f;
// Use this for initialization
void Start ()
{
}
//传进来的血量必须是百分比
void UpdateBlood(float blood)
{
if (0 <= blood && 1 >= blood)
m_tagBlood = blood;
else
Debug.Log("传入错误血量值!!!");
}
//随着目标点变动更新位置
void UpdatePosition()
{
//目标世界坐标转画布坐标
Vector3 worldToScreenPoint = Camera.main.WorldToScreenPoint(m_tagTrans.position);
//在画布上对应的点
worldToScreenPoint = new Vector3(worldToScreenPoint.x, worldToScreenPoint.y, m_canvas.planeDistance);
Vector3 screenToWorldPoint = m_cam.ScreenToWorldPoint(worldToScreenPoint);
//得到最终画布坐标系中的投影点
Vector3 projPoint = m_canvas.transform.worldToLocalMatrix.MultiplyPoint(screenToWorldPoint);
this.transform.localPosition = projPoint;
}
// Update is called once per frame
void Update ()
{
//血量变动
m_curBlood = Mathf.Lerp(m_curBlood, m_tagBlood, 0.1f);
img.fillAmount = m_curBlood;
UpdatePosition();
}
}
代码中关键部分为UpdatePosition()这个函数,理解了mvp变换很容易就可以看出来这几句代码做了什么。