UGUI气泡的遮挡问题研究与解决

来源:互联网 发布:阿里云 域名 发票 编辑:程序博客网 时间:2024/06/04 19:55
在Unity中做血条或者悬浮气泡会有一个小问题是我们需要解决的,这就是遮挡顺序的问题。


用过的大家都知道,UI的顺序是以在面板中的层次顺序来排列的。下面举个例子。


在unity中搭建一个场景,如下图所示:


 



 



建三个小球,分别配上三个不同颜色的材质,建三个image分别给三个颜色,一一对应。


然后写一个跟随的脚本,让三个UI分别悬浮到三个小球上方,为了快速,用最简单的方式来写

如下:

using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;using UnityEngine.EventSystems; public class abc : MonoBehaviour {     public Transform aa;    public Transform bb;    public Transform cc;     public RectTransform aaa;    public RectTransform bbb;    public RectTransform ccc;     // Use this for initialization    void Start () {                         }                 // Update is called once per frame        void Update () {        aaa.transform.position = new Vector3(aa.position.x, aa.position.y + 5.0f, aa.position.z);        bbb.transform.position = new Vector3(bb.position.x, bb.position.y + 5.0f, bb.position.z);        ccc.transform.position = new Vector3(cc.position.x, cc.position.y + 5.0f, cc.position.z);    }}
然后把该脚本绑到相机上,把对应的三个小球和三个UI拖入到对应位置,如下图:
 



到这一步后还不够,还得接着来修改一些东西:
1)修改如图的canvas
 



2)把三个UI image的大小(高和宽)改小一点,不然就太大了,改成15差不多了。如图:
 



然后点击运行,查看效果,改变相机的位置和朝向,截取两张图做对比,如下图:
 VS  



大家可以看到第一张图是对的,第二张图从另一半看就错了,有了遮挡。


再看一张层次图:
 



层次图里aaaa\bbbb\cccc的顺序是不会变的。


然而我们要做的事就是通过一定判断改变它的顺序,按照我们想要的顺序来改变。

接着上篇来写,如何改变面板中的层次结构是一个问题,根据什么来判断层次的先后顺序是一个问题,只要解决这两点就OK啦


很简单,unity中其实有一个方法可以通过脚本来改变层次结构,该方法就是SetSiblingIndex;然后根据什么来判断这点,当然是根据物体与摄像机的距离来判断。


我们可以把所需要的物体与摄像机之间的距离计算出来,然后通过距离的大小改变UI的层次索引。
当然,这个方法要放到Update里或者相机有位置改变的时候执行,这样不论相机怎么移动,都会看到距离相机近的物体的UI在最前面,符合实际情况。

Camera cam;    float[] deviceToCam = new float[3];    Dictionary<float, RectTransform> floatToUI = new Dictionary<float, RectTransform>();    void test()    {        cam = Camera.main;        deviceToCam[0] = Vector3.Distance(cam.transform.position, aa.position);        floatToUI.Add(deviceToCam[0], aaa);        deviceToCam[1] = Vector3.Distance(cam.transform.position, bb.position);        floatToUI.Add(deviceToCam[1], bbb);        deviceToCam[2] = Vector3.Distance(cam.transform.position, cc.position);        floatToUI.Add(deviceToCam[2], ccc);         Array.Sort(deviceToCam);        Array.Reverse(deviceToCam);         for (int j = 0; j < 3; j++)        {            floatToUI[j].SetSiblingIndex(j);        }    }

上述代码有字典键值的问题,但是意思正确。具体项目中可以用列表、字典等来存放。


另外可以通过两帧之间的差值判断相机的移动,如下:


#region 通过两帧差值判断相机移动        newPos = cam.transform.position;        if (oldPos == Vector3.zero)        {                     }        else        {            cha = newPos - oldPos;        }        oldPos = newPos;        #endregion         //cha.magnitude        if(cha.magnitude > 0.00001f)        {            test();        }

附上一张图:
 



相机的移动方式很多,我就不多说了。



原创粉丝点击