gihub传送门
https://github.com/ddghost/unity3d_n/tree/%E8%A1%80%E6%9D%A1
这次作业五选一,我选了血条这个来做(感觉比较实在简单)。
先来看下成果,这个是IMGUI做的,黑色是因为没找到什么办法设置颜色。
这个是用UGUI,感觉比较好看点。
这次用的这个人物资源和上次巡逻兵的一样,是在unity的商店找的,资源如下
https://www.assetstore.unity3d.com/cn/?stay#!/content/73611
人物控制移动的代码与上次相比稍有改动。
IMGUI实现血条
先来讲下IMGUI,这个其实就是用OnGUI函数来实现的,通过GUI的box,label,HorizontalScrollbar等等来实现菜单什么的ui,这里做的血条就用到了HorizontalScrollbar。但这个东西实现血条感觉我做的还不太好,比方说人物走远了,血条大小还是不变,并且感觉上会越来越高等等,这些都是挺麻烦的事情,要通过摄像机和人物的距离来进行调整,时间有限,这里只是粗略地实现血条。
以下就是IMGUI实现血条的代码,写好后直接挂到人物上面就好了,根据人物高矮和分辨率来调一下barUpLength。
public class IMGUI : MonoBehaviour {
private Rect bloodBar;
private float barUpLength = 70f;
void Start()
{
bloodBar = new Rect (0, 0, 60, 20);
}
void OnGUI()
{
Vector2 player2DPosition = Camera.main.WorldToScreenPoint (transform.position);
player2DPosition.y = Screen.height - player2DPosition.y - barUpLength;
bloodBar.center = player2DPosition + new Vector2(0 , 0);
if ( player2DPosition.x > Screen.width || player2DPosition.y > Screen.height
|| player2DPosition.x < 0 || player2DPosition.y < 0) {
} else {
GUI.HorizontalScrollbar(bloodBar, 0.0f, 1.0f, 0.0f, 1.0f);
}
}
}
UGUI实现血条
然后就是UGUI,首先给人物添加一个Canvas。
canvas的renderMode改为OverLay那个。
然后Canvas里面加一个slider。
slider下有几个子元素,把那个Handle Slide Area的active的√给点掉,这样slider就没有那个滑块了。
然后设置slider下的Fill Area中的fill的颜色,设为红色,这样slider看上去就是红色的血条了。
再把当前血量改一改。
还要改的就是血条slider的大小,在scale那里改改就好了,就不贴出来了。
接下来就UGUI的代码,这部分代码和IMGUI很像,都是将人物的坐标转换到摄像机的坐标,然后把血条放到人物在摄像机坐标的上方,不过UGUI中,Slider是实在的一个GameObject,挂在了人物上,因此感觉比较实在。
public class UGUI : MonoBehaviour {
private float barUpLength = 3f;
public Slider healthSlider ;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
Vector3 worldPos = new Vector3(transform.position.x, transform.position.y + barUpLength , transform.position.z);
Vector3 screenPos = Camera.main.WorldToScreenPoint(worldPos);
healthSlider.transform.position = new Vector3(screenPos.x, screenPos.y, screenPos.z);
}
}
总结
总的来说,IMGUI是个挺难弄的东西,因为它已经挺过时了,UGUI的话就比较好,是实在的一个GameObject,不运行也可以看到,方便调试。这次作业中我用的这两种方法都没有实现血条的近大远小,因为感觉也有点麻烦,感觉应该是通过摄像机到人的距离来调整血条大小还有相对的高低,但是推导相应的公式感觉比较头疼。
补充
事实上在UGUI中,把canvas的rendermode设置成worldspace,然后再用代码使得slider一直面朝摄像机,就可以实现近大远小的功能,但是老师说能用overlay就用overlay,性能更好(有种被坑的感觉),那种情况应该是静态的血条最好,例如一些游戏会在下方显示当前血量那种,这里这种动态的血条就不太好使,不过等我想起来这件事的时候已经很晚了,所以前面的作业也就那样了。