用过的大家都知道,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差不多了。如图:
然后点击运行,查看效果,改变相机的位置和朝向,截取两张图做对比,如下图:
大家可以看到第一张图是对的,第二张图从另一半看就错了,有了遮挡。
再看一张层次图:
层次图里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();
}
附上一张图:
相机的移动方式很多,我就不多说了。