欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

unity UI血条效果

程序员文章站 2022-07-13 14:41:53
...

gihub传送门
https://github.com/ddghost/unity3d_n/tree/%E8%A1%80%E6%9D%A1

这次作业五选一,我选了血条这个来做(感觉比较实在简单)。
先来看下成果,这个是IMGUI做的,黑色是因为没找到什么办法设置颜色。
unity UI血条效果
这个是用UGUI,感觉比较好看点。
unity UI血条效果

这次用的这个人物资源和上次巡逻兵的一样,是在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。
unity UI血条效果

canvas的renderMode改为OverLay那个。
unity UI血条效果

然后Canvas里面加一个slider。
unity UI血条效果

slider下有几个子元素,把那个Handle Slide Area的active的√给点掉,这样slider就没有那个滑块了。
unity UI血条效果

然后设置slider下的Fill Area中的fill的颜色,设为红色,这样slider看上去就是红色的血条了。
unity UI血条效果

再把当前血量改一改。
unity UI血条效果
还要改的就是血条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,性能更好(有种被坑的感觉),那种情况应该是静态的血条最好,例如一些游戏会在下方显示当前血量那种,这里这种动态的血条就不太好使,不过等我想起来这件事的时候已经很晚了,所以前面的作业也就那样了。