实例化UI按钮切换渲染模式后沿Z轴意外偏移的原因
问题原因及解决方法
为什么Z轴会偏移?
这是因为Screen Space Overlay和Screen Space Camera两种UI渲染模式的坐标逻辑完全不同:
- Overlay模式下,UI直接绘制在屏幕上,Z轴值被忽略,元素深度由Hierarchy顺序决定,所以你设Z=0不会有问题。
- 切换到Screen Space Camera后,UI元素是3D世界空间中的对象,位置会受Canvas的相机设置和父物体坐标空间影响。
你代码里用Instantiate(buttonTemplate, new Vector3(x,y,0), Quaternion.identity, transform)时,传入的new Vector3(x,y,0)是世界空间坐标,Unity会自动把这个世界坐标转换为父物体(Canvas或UI容器)的本地空间坐标。而Screen Space Camera模式下,Canvas的本地Z轴对应到相机的距离(由Canvas的Plane Distance参数控制),如果Canvas本身的世界位置不在Z=0处,世界空间Z=0的点转换为Canvas本地坐标时,就会出现负数Z值,导致元素被相机远裁剪面挡住,无法显示。
解决方法
直接用本地坐标设置按钮位置,避免世界坐标转本地坐标的换算问题,修改实例化代码即可:
for (int i = 0; i < div; i++){ float x = 250 + 250 * Mathf.Cos(radianSteps*i); float y = (h/2) + 250 * Mathf.Sin(radianSteps*i); // 先实例化到父物体下,再设置本地位置 GameObject button = Instantiate(buttonTemplate, transform); button.transform.localPosition = new Vector3(x, y, 0); button.name = "Emotion "+i; TextMeshProUGUI textObject = button.transform.GetChild(0).GetComponent<TextMeshProUGUI>(); textObject.text = emotionPairs[i]; textObject.fontSize = 12; SelectEmotion selectComp = button.GetComponent<SelectEmotion>(); selectComp.emotionIndex = i; selectComp.maxIndex = div-1; selectComp.start = position; selectComp.dest = new Vector3((w-(w/4)),(h/2),0); }
额外补充:Screen Space Camera模式下,要确保Canvas的Plane Distance设置在相机的近裁剪面和远裁剪面之间,这样UI平面本身处于相机可视范围内,子元素设本地Z=0时就能正常显示。
内容的提问来源于stack exchange,提问作者UmbrellaMan
相关产品推荐
相关产品推荐

