//구글콘솔 광고 추가가
728x90
반응형

유니티가 업데이트되면서 main Camera의 stack에 새로운 카메라를 쌓을 수 있게 되었다.

여러 카메라의 출력을 레이어링하여 하나의 결합된 출력을 만들 수 있는 기능이다.

이걸 사용하면 하나의 씬에서 여러 개의 카메라를 관리해 줄 수 있으니 사용해 보자.

나의 경우는 하나의 씬에서 프리팹화 시켜둔 미니 게임 여러 개를 불러오게 하려고 시작했다.

 

< 스택 설정 방법 >
Base Camera 설정 :
- 메인 카메라의 Render Type을 "Base"로 설정.
- Stack 섹션에서 오버레이 카메라들을 추가 가능.
Overlay Camera 설정 :
- 새 카메라 생성 후 Render Type을 "Overlay"로 변경.
- Culling Mask를 통해 렌더링 할 레이어 지정.

 

위에서 정리해 둔 것처럼 설정해 보자.

 

1. 우선 기본 main Camera의 Render Type을 Base로 바꿔 준다.

 

 

2. 추가해주고 싶은 Camera의 Render Type을 Overlay로 바꿔 준다.

++ 여기서 잊지 말아야 할 부분, 추가하는 Camera의 Tag을 MainCamera로 남겨두지 말자.

++ Audio Listener도 꺼주거나 지워주자.

 

 

3. 코드에서 카메라 등록 해주고 싶은 부분에 써야 할 부분.

베이스 카메라의 스택에 오버레이 카메라 추가.

 

 

4. 코드에서 카메라 제거 해주고 싶은 부분에 써야 할 부분.

추가해줬던 카메라 제거.

 

 

예외처리 해서 최종 작업한 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering.Universal;

public class CameraManager : MonoBehaviour
{
    private Camera baseCamera;
    private Dictionary<string, Camera> cameras = new Dictionary<string, Camera>();

    private void Awake()
    {
        baseCamera = Camera.main;
    }

    public void RegisterCamera(string miniGameId, Camera overlayCamera)
    {
        if (!cameras.ContainsKey(miniGameId))
        {
            cameras.Add(miniGameId, overlayCamera);
            var cameraData = baseCamera.GetUniversalAdditionalCameraData();
            cameraData.cameraStack.Add(overlayCamera);
        }
    }

    public void UnregisterCamera(string miniGameId)
    {
        // miniGameId가 null이거나 비어있는지 체크
        if (string.IsNullOrEmpty(miniGameId))
        {
            Debug.LogWarning("MiniGame ID is null or empty");
            return;
        }
        
        // 카메라 딕셔너리에서 해당 ID의 카메라를 찾음
        if (cameras.TryGetValue(miniGameId, out Camera camera))
        {
            // 베이스 카메라가 존재하고 카메라가 유효한지 확인
            if (baseCamera != null && camera != null && camera.gameObject != null)
            {
                try
                {
                    var cameraData = baseCamera.GetUniversalAdditionalCameraData();
                    if (cameraData != null && cameraData.cameraStack.Contains(camera))
                    {
                        cameraData.cameraStack.Remove(camera);
                    }
                }
                catch (MissingReferenceException e)
                {
                    Debug.LogWarning($"Camera reference was already destroyed: {e.Message}");
                }
            }
            
            // 딕셔너리에서 카메라 제거
            cameras.Remove(miniGameId);
        }
    }
    
    private void OnDestroy()
    {
        // 카메라 스택 정리
        if (cameras != null)
        {
            foreach(var camera in cameras.Values)
            {
                if (camera != null && baseCamera != null)
                {
                    var cameraData = baseCamera.GetUniversalAdditionalCameraData();
                    if (cameraData != null)
                    {
                        cameraData.cameraStack.Remove(camera);
                    }
                }
            }
            cameras.Clear();
        }
    }
}

 

++ baseCamera 가 null 이 될 수 있는 상황들이 있다면 null 체크도 해줘야 함.

728x90
반응형

+ Recent posts