Unity把UGUI再World模式下显示到相机最前方

Unity把UGUI再World模式下显示到相机最前方

通过脚本修改Shader

再VR里有时候要把3D的UI显示到相机最前方,加个UI相机会坏事,可以通过修改unity_GUIZTestMode来解决。

测试用例

测试用例如下:
在这里插入图片描述
场景包含一个红色的盒子,一个UI里含有这些元素
在这里插入图片描述

在这里插入图片描述
我们在UI根挂上运行脚本WorldSpaceOverlayUI.cs

脚本如下:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

[ExecuteInEditMode] //Disable if you don't care about previewing outside of play mode
public class WorldSpaceOverlayUI : MonoBehaviour
{
    
    
    private const string shaderTestMode = "unity_GUIZTestMode"; //The magic property we need to set
    [SerializeField] UnityEngine.Rendering.CompareFunction desiredUIComparison = UnityEngine.Rendering.CompareFunction.Always; //If you want to try out other effects
    [Tooltip("Set to blank to automatically populate from the child UI elements")]
    [SerializeField] Graphic[] uiGraphicsToApplyTo;
    [Tooltip("Set to blank to automatically populate from the child UI elements")]
    [SerializeField] TextMeshProUGUI[] uiTextsToApplyTo;
    //Allows us to reuse materials
    private Dictionary<Material, Material> materialMappings = new Dictionary<Material, Material>();
    protected virtual void Start()
    {
    
    
        if (uiGraphicsToApplyTo.Length == 0)
        {
    
    
            uiGraphicsToApplyTo = gameObject.GetComponentsInChildren<Graphic>();
        }
        if (uiTextsToApplyTo.Length == 0)
        {
    
    
            uiTextsToApplyTo = gameObject.GetComponentsInChildren<TextMeshProUGUI>();
        }
        foreach (var graphic in uiGraphicsToApplyTo)
        {
    
    
            Material material = graphic.materialForRendering;
            if (material == null)
            {
    
    
                Debug.LogError($"{
      
      nameof(WorldSpaceOverlayUI)}: skipping target without material {
      
      graphic.name}.{
      
      graphic.GetType().Name}");
                continue;
            }
            if (!materialMappings.TryGetValue(material, out Material materialCopy))
            {
    
    
                materialCopy = new Material(material);
                materialMappings.Add(material, materialCopy);
            }
            materialCopy.SetInt(shaderTestMode, (int)desiredUIComparison);
            graphic.material = materialCopy;
        }
        foreach (var text in uiTextsToApplyTo)
        {
    
    
            Material material = text.fontMaterial;
            if (material == null)
            {
    
    
                Debug.LogError($"{
      
      nameof(WorldSpaceOverlayUI)}: skipping target without material {
      
      text.name}.{
      
      text.GetType().Name}");
                continue;
            }
            if (!materialMappings.TryGetValue(material, out Material materialCopy))
            {
    
    
                materialCopy = new Material(material);
                materialMappings.Add(material, materialCopy);
            }
            materialCopy.SetInt(shaderTestMode, (int)desiredUIComparison);
            text.fontMaterial = materialCopy;
        }
    }
}

在这里插入图片描述

引用
https://discussions.unity.com/t/world-space-canvas-on-top-of-everything/128165/14

猜你喜欢

转载自blog.csdn.net/thinbug/article/details/133345518