在开发项目中,可能会有制作血条的功能,或者制作三维场景中人物头上的状态栏或者信息栏的功能需求。
效果:
其实主要就是UGUI物体跟随三维世界的物体坐标的实现。然后将血条信息或者其他的信息数据赋值。
知识点:
1、就是三维世界与UGUI的坐标转换
Uunity提供了很方便的API:RectTransformUtility(RectTransform的辅助类)
a、这个功能主要用到了ScreenPointToWorldPointInRectangle;
解释:
bool ScreenPointToWorldPointInRectangle(RectTransform rect, Vector2 screenPoint, Camera cam, out Vector3 worldPoint),把屏幕坐标转换成在rect这个实参平面内的世界坐标,这个函数可能会比较难搞懂一些,可以理解为在屏幕坐标ScrrenPoint处发条Z方向的射线,摄像与rect的交点就是返回的世界坐标worldPoin。(这里的rect就传自身的RectTransform,screenPoint就是屏幕坐标,其实就是把screenPoint投射在Canvas平面上得到rect的世界坐标点)
b、还有另外一个接口和它类似:ScreenPointToLocalPointInRectangle
解释:bool ScreenPointToLocalPointInRectangle(RectTransform rect, Vector2 screenPoint, Camera cam, out Vector2 localPoint); 把一个屏幕空间上的点,转换成rect的内部坐标,Canvas 的RenderMode在Camera和World模式下,传入的camera为UI摄像机,在OverLay,camara参数应该传入null。(这里的rect就传你想要赋值的物体的父物体)。
主要思路就是将目标的三维世界坐标先转化为屏幕坐标,然后将得到的屏幕坐标转化为UGUI自身的坐标。
2、可以用UGUI的Slider制作血条,也可以直接用图片Image(用图片的话设置方式见下图);
主要设置ImageType为Filled模式即可,然后改变Fill Amount的值。
代码部分:
public Vector3 Offset = new Vector3(0,1,0);
private void CalPosition()
{
Vector3 vector3 = Vector3.zero;
Vector3 screenPosition = Camera.main.WorldToScreenPoint(TargetTransform.position + Offset);//将目标物体的坐标转化为屏幕坐标
Vector3 uiPosition = Vector3.zero;
//;//将得到的屏幕坐标转化为UGUI坐标
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(transform as RectTransform, screenPosition, null, out uiPosition))
{
transform.position = uiPosition ;
}
}
设置偏移量,方便调整血条的位置,使其位置更和谐。