添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

unity实现头顶血条

勿忘初心 2018-09-29 10:06

本文来自网易云社区

作者:汪毅军

在游戏中,头顶血条的是一个非常常见的功能,其中血条可分为2D血条和3D血条。2D血条不会随着模型远近而变化,始终保持着相同的大小;但3D血条会随着模型远近移动而产生透视,会显得比较真实。在大多数情况下,我们应该都会选择2D血条,当然也有一些特殊的地方3D血条会更加合适,今天就来看看这两种实现方案。

2D血条的实现思路

  • 首先需要确定模型头顶的坐标,该坐标可以直接在模型上预设好也可以直接通过计算 Collider 来获取。
  • 我们拿到头顶的世界坐标后,通过3D相机把这个点转换到屏幕坐标,然后这个坐标就是血条的位置。
  • 剩下的就是根据位置调整显示血条即可。
  • 2D血条的实现

  • 实现2D血条的话,需要将 Canvas RenderMode 调整为 ScreenSpace-Overlay 。这个 Canvas 是所有的UI组件共用的。具体结构如下:
  • 然后通过Slider制作血条

  • 接下来按照实现思路来实现相关代码。由于2D血条没有透视问题,所以只需实时更新血条位置即可。
  • public class CHpBar : MonoBehaviour
        private Slider hpSlider;
        private RectTransform rectTrans;
        public Transform target;
        public Vector3 offsetPos; //头顶偏移量
        private void Start()
            hpSlider = GetComponent<Slider>();
            rectTrans = GetComponent<RectTransform>();
            //更新血量
            //hpSlider.value
        private void Update()
            if(target==null) return;
            //通过Collider来获取头顶坐标
            var col = target.GetComponent<Collider>();
            var topAhcor = new Vector3(col.bounds.center.x, col.bounds.max.y, col.bounds.center.z);   
            //加上头顶偏移量
            Vector3 tarPos = topAhcor;
            var viewPos = Camera.main.WorldToViewportPoint(tarPos); //得到视窗坐标
            Vector2 screenPos;
            if (viewPos.z > 0f && viewPos.x > 0f && viewPos.x < 1f && viewPos.y > 0f && viewPos.y < 1f)
                //获取屏幕坐标
                screenPos =  Camera.main.WorldToScreenPoint(tarPos+offsetPos); //加上头顶偏移量
                //不在可视窗口的模型,把名字移动到视线外
                screenPos = Vector3.up * 3000f;
            //转化为屏幕坐标
            rectTrans.position = screenPos;
    

    可以发现,不论模型怎么移动,2D血条始终都会朝向保持着原始大小。

    3D血条的实现思路

  • 3D的话就得把血条固定在模型头上面
  • 每一帧都得根据模型的旋转来调整血条,使血条始终朝着摄像机,这样才不会导致血条旋转、缩放等问题
  • 3D血条的实现

  • 3D血条需要将CanvasRenderMode调整为World Space。并且将Canvas作为模型的Child。具体结构如下:
  • 代码的实现比较简单,直接矫正画布使其一直朝着摄像机

    public class CHpCanvas : MonoBehaviour
        private void Update()
            transform.rotation = Camera.main.transform.rotation;
    

    可以发现,3D血条会跟随模型产生透视效果

    两个血条方案各有自己的适用场景。3D血条更加真实,但是由于一个对象一个Canvas,所以性能方面没有2D血条好。2D血条的话在显示效果上没有3D的好,但是性能方面比3D的好。此外在于一些特殊情况下(比如摄像机绘制RenderTexture),使用3D血条的去处理要比2D血条要简便很多。

    参考文章: https://www.jianshu.com/p/a9fd13594f18

    网易云免费体验馆,0成本体验20+款云产品!