66.내일배움캠프 58일차 TIL <Unity Unity 2D 팀프로젝트- MartialGod:Reborn - 7일차> 07/01

정광훈(Unity_9기)·2025년 7월 1일

TIL (Today I Learned)

목록 보기
67/110
post-thumbnail

화면 밝기 조절 기능 구현

<구현 방법>

사진처럼 Global Volume을 만들고 Add Component위에 Add Override를 누르면
Color Adujustments가 있고 Post Exposure는 화면 밝기를 조절하는데 용이하다.
0이 기본값이고 올라가면 밝아지고 내려가면 어두워진다.

여기서 문제가 생기는데 코드와 슬라이더를 연결하고 실행해본 결과
씬 뷰에서는 슬라이더를 조절하면 어두워지고 밝아지고 하는데
게임 뷰에서는 변화가 없는 것이었다. (화면 전체가 설정 UI인 상태)

그래서 슬라이더로 어둡게 하고 UI를 꺼봤더니 배경은 어두워졌고 UI만 변화가 없는 것이었다.

<Screen Space - Overlay 특징>

항상 화면 위에 표시:
어떤 3D/2D 오브젝트보다 항상 앞에 그려집니다.
씬의 오브젝트에 의해 가려지는 일이 없습니다.

카메라 후처리(Post-processing) 영향 없음:
씬을 렌더링하는 카메라에 적용되는 Post-processing 효과
(블룸, 색상 보정, 밝기 조절 등)의 영향을 받지 않습니다.

UI는 독립적인 색상과 밝기를 유지합니다.
(이것이 사용자님이 겪고 계신 문제의 원인입니다.)

Depth (깊이) 개념 없음:
씬의 오브젝트들과 같은 깊이 공간에 존재하지 않습니다.

가장 일반적인 UI:
인게임 HUD, 메뉴, 팝업 등 대부분의 게임 UI에 사용됩니다.

라고 한다.

GPT에게 물어본 결과 2가지 방법을 알려줬는데
1. 셰이더를 만들어서 설정하고 모든 UI오브젝트의 material에 할당해야하는 번거로운 방법
2. 캔버스에서 아래 사진처럼 설정하는 방법
이 있었다.

쉬운 방법은 2번이지만 성능 최적화로 가면 Screen Space - Overlay가
좋다고 한다.

그래서 리더 개발자님과 얘기를 해본 후에 2번 방법으로 가도 될 것 같다 하셔서
2번으로 진행했다. 잘 작동하는 것도 확인했다.


Screen Space - Camera로 설정했을 때

Screen Space - Overlay로 설정하면 씬 뷰에서는 어두워지는데
게임 뷰에서는 변화가 없는 것을 볼 수 있다.


<코드>

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.UI;

public class BrightnessOption : MonoBehaviour
{
    private ColorAdjustments colorAdjustments;
    private Slider brightnessSlider; // 화면 밝기 슬라이드 
    
    [Header("글로벌 볼륨 오브젝트")]
    [SerializeField] private Volume globalVolume; // 글로벌 볼륨 - 화면 밝기 제어 오브젝트

    [Header("밝기 수치 조절")]
    [SerializeField] private float minExposure = -4f; // 밝기 최소값
    [SerializeField] private float maxExposure = 0f; // 밝기 최대값
    
    private float prevBrightnessValue; // 이전에 설정한 화면 밝기
    
    private void Awake()
    {
        brightnessSlider = this.TryGetComponent<Slider>();
    }
    
    private void Start()
    {
        InitBrightnessSlider();
    }

    // GraphicOption에서 화면 밝기 슬라이더의 현재 값을 가져갈 수 있도록 반환
    public float GetBrightnessSliderValue()
    {
        return brightnessSlider.value;
    }

    // GraphicOption에서 화면 밝기 슬라이더의 값을 설정할 수 있도록 함
    public void SetBrightnessSliderValue(float value)
    {
        brightnessSlider.value = value;
        
        SetBrightness(value);
    }

    // GraphicOption에서 화면 밝기 슬라이더의 값을 설정할 수 있도록 함
    public void SetBrightnessDefaultValue()
    {
        SetBrightnessSliderValue(brightnessSlider.maxValue);
    }

    // GraphicOption에서 화면 밝기 슬라이더의 값을 설정할 수 있도록 함
    public void BackUpBrightnessValue()
    {
        prevBrightnessValue = brightnessSlider.value;
    }
    
    private void InitBrightnessSlider() // 초기 슬라이더 설정
    {
        if (globalVolume == null)
        {
            LogHelper.LogError("글로벌 볼륨이 할당되지 않음", this);
            return;
        }

        // Volume Profile: 여러 가지 포스트 프로세싱 효과나 렌더링 설정의 기본값 또는 템플릿을 담고 있음
        // Volume Profile에서 ColorAdjustments 오버라이드를 가져옴
        // globalVolumeprofile에서 ColorAdjustments를 찾으면 colorAdjustments에 할당
        if (!globalVolume.profile.TryGet<ColorAdjustments>(out colorAdjustments)) return;

        // Color Adjustments 오버라이드와 Post-exposure 파라미터를 활성화
        colorAdjustments.active = true;
        colorAdjustments.postExposure.overrideState = true;

        brightnessSlider.minValue = minExposure; // 슬라이더 최소값 = Exposure의 최소값
        brightnessSlider.maxValue = maxExposure; // 슬라이더 최대값 = Exposure의 최대값

        brightnessSlider.value = colorAdjustments.postExposure.value;
    }

    public void SetBrightness(float sliderValue) // 화면 밝기 조절
    {
        colorAdjustments.postExposure.value = sliderValue;
    }
}

<GraphicOption.cs>에서 구현했다가 설정마다 다 분리시켜 구현 중이다.
이유는 코드의 결합성을 줄이기 위해서.
결합성이 높으면 다른 쪽에서 문제가 생기면 이 코드가 정상 작동하지 않기 때문이다.

0개의 댓글