美文网首页
Unity中,将指定物件显示在黑色遮罩前

Unity中,将指定物件显示在黑色遮罩前

作者: 全新的饭 | 来源:发表于2023-08-07 18:20 被阅读0次

用途

如需要提示玩家点击目标内容时

做法

  1. 黑色遮罩所属的Canvas的RenderMode应设置为ScreenSpace—Camera
  2. UICamera的制作
    ClearFlags:Depth only
    CullingMask:UI
    Depth:大于MainCamera的
  3. 新增一个层:Top
  4. SetToTopSys的实现
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// 将目标物设置到最前(通常是设置到黑色遮罩之前)
/// </summary>
public class SetToTopSys
{
    private static SetToTopSys _instance;
    public static SetToTopSys Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new SetToTopSys();
            }
            return _instance;
        }
    }

    private Camera _cam;
    private const string TargetLayerMaskName = "Top";

    private readonly int UiCanvasOrderInLayer;

    private SetToTopSys()
    {
        InitCam();
        // 初始化UICanvas的Order(要比其他所有的都大)
        int value = -1;
        var allCanvas = GameObject.FindObjectsOfType<Canvas>();
        foreach (var c in allCanvas)
        {
            if (value < c.sortingOrder)
            {
                value = c.sortingOrder;
            }
        }
        value++;
        UiCanvasOrderInLayer = value;

        void InitCam()
        {
            // 新创建的Cam的Depth应是所有Depth中最大的!
            var cams = GameObject.FindObjectsOfType<Camera>();
            float depth = -1;
            foreach (var cam in cams)
            {
                if (depth < cam.depth)
                {
                    depth = cam.depth;
                }
            }
            depth++;

            _cam = new GameObject("TopCam").AddComponent<Camera>();
            _cam.clearFlags = CameraClearFlags.Depth;
            _cam.cullingMask = 1 << LayerMask.NameToLayer(TargetLayerMaskName);
            _cam.orthographic = Camera.main.orthographic;
            _cam.orthographicSize = Camera.main.orthographicSize;
            _cam.depth = depth;

            _cam.transform.SetParent(Camera.main.transform);
            _cam.transform.localPosition = Vector3.zero;
            _cam.transform.localRotation = Quaternion.identity;
            _cam.transform.localScale = Vector3.one;
        }
    }

    public void MyDestroy()
    {
        DestroyCam();

        void DestroyCam()
        {
            if (_cam != null)
            {
                GameObject.Destroy(_cam.gameObject);
                _cam = null;
            }
        }
    }

    public void SetUiGoToTop(GameObject uiGo)
    {
        if (uiGo.GetComponent<Canvas>() == null)
        {
            var canvas = uiGo.AddComponent<Canvas>();
            canvas.overrideSorting = true;
            canvas.sortingOrder = UiCanvasOrderInLayer;
            uiGo.AddComponent<GraphicRaycaster>();
        }
    }

    public void ResetUiGo(GameObject uiGo)
    {
        Object.Destroy(uiGo.GetComponent<GraphicRaycaster>());
        Object.Destroy(uiGo.GetComponent<Canvas>());
    }

    public void SetSceneGoToTop(GameObject go)
    {
        SetLayer(go, LayerMask.NameToLayer(TargetLayerMaskName));
    }


    public void ResetSceneGo(GameObject go, int originalLayer)
    {
        SetLayer(go, originalLayer);
    }

    // 设置自己及所有子孙节点的Layer
    private void SetLayer(GameObject go, int layer)
    {
        var transforms = go.GetComponentsInChildren<Transform>(true);
        foreach (var trans in transforms)
        {
            trans.gameObject.layer = layer;
        }
    }

    public void EnableCam()
    {
        _cam.gameObject.SetActive(true);
    }

    public void DisableCam()
    {
        _cam.gameObject.SetActive(false);
    }
}
  1. 调用示意
    SetToTopTest
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SetToTopTest : MonoBehaviour
{
    [SerializeField]
    private GameObject[] _uiGos;
    [SerializeField]
    private GameObject[] _sceneGos;

    [SerializeField]
    private string _originalLayerName;

    private void Start()
    {
        Init();
    }

    private void Update()
    {
        MyUpdate();
    }

    private void OnDestroy()
    {
        MyDestroy();
    }

    private void Init()
    {

    }

    private void MyUpdate()
    {
        // 目标UI显示到最前
        if (Input.GetKeyDown(KeyCode.A))
        {
            foreach (var go in _uiGos)
            {
                SetToTopSys.Instance.SetUiGoToTop(go);
            }
        }
        // 目标UI不显示到最前
        else if (Input.GetKeyDown(KeyCode.B))
        {
            foreach (var go in _uiGos)
            {
                SetToTopSys.Instance.ResetUiGo(go);
            }
        }
        // 目标物件显示到最前
        else if (Input.GetKeyDown(KeyCode.C))
        {
            foreach (var go in _sceneGos)
            {
                SetToTopSys.Instance.SetSceneGoToTop(go);
            }
        }
        // 目标物件不显示到最前
        else if (Input.GetKeyDown(KeyCode.D))
        {
            foreach (var go in _sceneGos)
            {
                SetToTopSys.Instance.ResetSceneGo(go, LayerMask.NameToLayer(_originalLayerName));
            }
        }
    }

    private void MyDestroy()
    {

    }
}

相关文章

  • 三十一、综合案例—土豆网鼠标经过显示遮罩

    案例:土豆网鼠标经过显示遮罩 练习元素的显示与隐藏 练习元素的定位核心原理:原先半透明的黑色遮罩看不见,鼠标经过大...

  • 视图遮罩的实现

    ios遮罩就是将原始图片或者视图通过遮罩的方式修改原有的显示,比如最简单的将方形图片显示成圆角图片,很多人会通过l...

  • CorelDRAW 位图颜色遮罩的运用

    CorelDRAW中的位图颜色遮罩命令可以将选择的颜色隐藏或显示,一般可用来抠图,这个颜色遮罩功能可以帮助您只改变...

  • opacity通道和智能材质,sp

    ctrl alt+右键点击切换图层,alt+q隔离显示。 编辑快速遮罩y,几何体填充全部黑色,要画遮罩的填充白色 ...

  • SerializeField和Serializable

    Serialize功能 Unity3D 中提供了非常方便的功能可以帮助用户将 成员变量 在Inspector中显示...

  • Unity中 视频的采集与播放 BMS

    一.实验目的: 了解视频资源在Unity中的使用方式以及在Unity中实时显示视频的方法 二.实验内容: (1) ...

  • unity如何设置遮罩

    在flash时期我们曾用过一个叫做遮罩的东西 在现在的unity时期我们应该如何来用呢? 幸好在unity的201...

  • 会声会影X7“遮罩帧的使用”

    会声会影遮罩帧就是在制作视频编辑里由黑白两种颜色组成的BMP图像,在编辑软件里将遮罩帧添加到视频或图像素材时,黑色...

  • 三(二)物件常量

    物件常量 有40个图形物件可以在价格表中创建和显示。 所有用于处理物件的常量分为9组: 物件类型-图形物件的标识符...

  • 前端制作遮罩与蒙版

    遮罩: 有色则显示,无色抠取,半透明则半透明 蒙版: 黑色则抠除,白色显示,灰色则半透明 概念上两者非常容易混淆,...

网友评论

      本文标题:Unity中,将指定物件显示在黑色遮罩前

      本文链接:https://www.haomeiwen.com/subject/rlbgpdtx.html