您当前的位置: 首页 >  Jave.Lin unity

Unity URP - 搬砖日志 - Base Camera 的 Stack 不显示 Overlay Camera

Jave.Lin 发布时间:2021-10-30 16:55:33 ,浏览量:4

文章目录
  • 环境
  • 问题
  • 如何解决
  • References

环境

Unity : 2019.4.30f1 URP : 7.7.1

问题

RT

如下图显示先有一个 Base Camera,注意 是在 DontDestroyOnLoad 分类场景下的 在这里插入图片描述

再如下图显示,另有 uicamera 也是 DontDestroyOnLoad 下的相机,RenderType 是 Overlay的 在这里插入图片描述

再如下图显示,另有 cameraWeapon 也是 SurvivalModeMap 场景下的相机,RenderType 是 Overlay的 在这里插入图片描述

按文档来说,只要是 Overlay 类型的相机,都可以设置到 Base 相机下的 Stack 来达到 叠加 或叫 累加 渲染的效果

从之前的情况得知,我们现在有两个 Overlay 的相机,分别为:uicamera, cameraWeapon

但是下图,可以发现,Base 相机下,却没有显示 cameraWeapon 的 在这里插入图片描述

原因:在Unity GUI 编辑器下来编辑的话,Base 相机的 Stack 相加列表项必须只能在同属于 Base 场景中的 Overlay 相机

如何解决

如果 Base 相机的 Stack 想要跨 场景设置 Stack,那么可以通过代码的方式,拿到其他场景的 Overlay 相机,然后调用如下代码:

var yourOverlayCam = GameObject.Find("xxx").GetComponent();
// 通过脚本的方式,只要能找到 camera 不轮是否跨 base 相机的场景,都可以 Add 进 Stack
_cam.GetComponent().cameraStack.Add(yourOverlayCam);

详细的 DEMO 代码(已验证过可行)

// jave.lin 2021/10/30
// 测试 脚本控制 URP Camera Stack

using UnityEngine;
using UnityEngine.Rendering.Universal;

public class TestURPCameraStack : MonoBehaviour
{
    public Camera mainCam;
    public Camera pCam;

    public Camera weaponCam;
    public Camera uiCam;

    private UniversalAdditionalCameraData mainCam_uacd;
    private UniversalAdditionalCameraData pCam_uacd;
    private UniversalAdditionalCameraData weaponCam_uacd;
    private UniversalAdditionalCameraData uiCam_uacd;

    private void Start()
    {
        GameObject.DontDestroyOnLoad(this.gameObject);
    }

    private void GetCam(string name, ref Camera cam)
    {
        if (cam == null)
        {
            var go = GameObject.Find(name);
            cam = go != null ? go.GetComponent() : null;
        }
    }

    private UniversalAdditionalCameraData GetCamAdditionalData(Camera cam)
    {
        return cam != null ? cam.GetComponent() : null;
    }

    private void SetOverlayCamData(UniversalAdditionalCameraData data)
    {
        if (data != null)
        {
            data.renderType = CameraRenderType.Overlay;
            data.renderShadows = false;
            data.dithering = false;
            data.renderPostProcessing = false;
            data.volumeLayerMask = 0;
            data.volumeTrigger = null;
        }
    }

    private void AddCameraStack(UniversalAdditionalCameraData data, Camera cam)
    {
        if (!data.cameraStack.Contains(cam))
        {
            data.cameraStack.Add(cam);
        }
    }

    private void RemoveCameraStack(UniversalAdditionalCameraData data, Camera cam)
    {
        data.cameraStack.Remove(cam);
    }

    private void InputHandle()
    {
        if (pCam_uacd != null)
        {
            if (Input.GetKeyDown(KeyCode.T))
            {
                // p camera add
                AddCameraStack(pCam_uacd, weaponCam);
                AddCameraStack(pCam_uacd, uiCam);
            }
            if (Input.GetKeyDown(KeyCode.Y))
            {
                // p camera remove
                RemoveCameraStack(pCam_uacd, weaponCam);
                RemoveCameraStack(pCam_uacd, uiCam);
            }
        }

        if (mainCam_uacd != null)
        {
            if (Input.GetKeyDown(KeyCode.G))
            {
                // main camera add
                AddCameraStack(mainCam_uacd, weaponCam);
                AddCameraStack(mainCam_uacd, uiCam);
            }
            if (Input.GetKeyDown(KeyCode.H))
            {
                // main camera remove
                RemoveCameraStack(mainCam_uacd, weaponCam);
                RemoveCameraStack(mainCam_uacd, uiCam);
            }
        }
    }

    private void Update()
    {
        // jave.lin : getting cameras
        GetCam("MainCamera",                ref mainCam);
        GetCam("ParachutingAirshipCamera",  ref pCam);
        GetCam("cameraWeapon",              ref weaponCam);
        GetCam("uicamera",                  ref uiCam);

        // jave.lin : getting camera additional data
        mainCam_uacd        = GetCamAdditionalData(mainCam);
        pCam_uacd           = GetCamAdditionalData(pCam);
        weaponCam_uacd      = GetCamAdditionalData(weaponCam);
        uiCam_uacd          = GetCamAdditionalData(uiCam);

        // jave.lin : setting overlay camera additional data
        SetOverlayCamData(weaponCam_uacd);
        SetOverlayCamData(uiCam_uacd);

        // jave.lin : inputing handle
        InputHandle();
    }
}

如果你的项目中,同一时刻有且仅有一个场景,不会使用 Additive 的方式来加载场景的话,可以不用考虑上面的问题

另外说明一下,通常都是 Base Camera 是渲染 3D 内容, Overlay Camera 都渲染 UI ,但根据项目、需求情况也不一定 Overlay Camera 只是渲染UI的,可以看到 URP 官方的 DEMO 中, Overlay 相机可以是非UI,起到分渲染层级的效果,这个得按你自己的项目需要考量是适合此中方式来制作

References
  • Camera Stacking - 2021/11/1 发现的 github 上的 camera stacking 文档
    • Clearing, rendering order and overdraw - 延伸阅读一下,还有 camera 的 clearing 操作
关注
打赏
1688896170
查看更多评论

Jave.Lin

暂无认证

  • 4浏览

    0关注

    546博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0787s