안녕하세요 투니드입니다!
이번 시간에는 씬간의 전환에 부드러운 효과를 적용하는 것을 진행해 보겠습니다!
전편에 마지막에 얘기했던 페이드효과를 만들어볼게요!
우선 Canvas에 새로운 Image오브젝트를 하나 만들어줍니다! 이름은 TintScreenImage 라고 지어줄게요!

만든 오브젝트를 캔버스 크기에 꽉 채워 주시구요! Image 컴포넌트의 Color값을 R : 0 G : 0 B : 0 A : 255 완전 검은색으로 이렇게 맞춰줍니다! 그리고 Raycast Target을 꺼서 이벤트 처리나 인식이 되지 않도록 만들어줄게요!
영상에서 사용하는 건 어쨌든 페이드 효과처럼 테스트가 먼저 진행이 되고 있는데 제가 궁금해서 찾아봤어요
컬러 틴트 효과랑 페이드 효과가 어떻게 다른지요!
여러분들도 궁금하실까봐 접은 글로 남겨놓을게요!
컬러 틴트 효과와 페이드 효과
컬러 틴트 효과와 페이드 효과는 다릅니다. 두 효과는 모두 화면이나 오브젝트의 시각적인 변화를 유도하지만, 그 목적과 방법은 조금 다릅니다.
1. 컬러 틴트 효과 (Color Tint Effect)
컬러 틴트는 색상 필터 또는 색상 변환 효과입니다. 주로 화면이나 오브젝트의 색을 일정 색상으로 변경하는 데 사용됩니다. 이 효과는 화면이나 오브젝트의 색을 특정 색으로 덧칠하거나 변경하여 분위기나 특정 효과를 강조합니다.
- 예시: 게임에서 밤에 화면을 어둡게 하기 위해 어두운 파란색이나 보라색으로 화면을 틴트할 수 있습니다. 반대로, 게임에서 경고 메시지가 있을 때 빨간색으로 화면을 틴트할 수도 있습니다.
- 특징: 특정 색상으로 변하는 효과, 색상이 일정하게 유지될 수 있습니다.
2. 페이드 효과 (Fade Effect)
페이드 효과는 투명도 (알파 값) 를 변화시키는 효과로, 화면이나 오브젝트의 가시성을 서서히 변경합니다. 보통은 페이드 인(fade-in) 또는 페이드 아웃(fade-out) 이라는 형태로 사용됩니다. 즉, 화면이나 오브젝트가 서서히 나타나거나 사라지는 효과입니다.
- 예시: 화면이 서서히 어두워지면서 점차적으로 사라지는 효과나, 반대로 서서히 나타나는 페이드 인 효과가 있을 수 있습니다.
- 특징: 투명도 변화로 인해 객체가 서서히 보이거나 사라지는 효과, 완전히 보이지 않거나 보이게 되는 시각적 변화입니다.
주요 차이점
- 컬러 틴트는 색상 자체를 변경하는 것에 중점을 둡니다. 색상의 변화를 통해 특정 분위기나 테마를 표현합니다.
- 페이드는 투명도를 조절하여 화면이나 오브젝트의 보이거나 사라지는 효과를 제공합니다.
예시 비교:
- 컬러 틴트: 화면이 붉은색으로 덮여져 있으면, 화면 자체가 붉은색으로 색이 변경됩니다.
- 페이드: 화면이 서서히 투명해지거나 서서히 나타나는 효과입니다. 페이드 아웃이면 점차 사라지고, 페이드 인이면 점차 나타납니다.
이 두 효과는 함께 사용할 수도 있습니다. 예를 들어, 게임에서 페이드 아웃과 함께 컬러 틴트를 적용하여 빨간색으로 화면이 서서히 변하면서 사라지게 할 수 있습니다.
그렇다고 합니다!
아무튼 만든 이미지 오브젝트에 ScreenTint.cs 파일을 만들어서 붙여줄게요!
원본 영상과 내용이 많이 다릅니다! 혹시 원본 영상을 따라 하고 싶으신 분들은 영상을 참고해 주세요!
먼저 변수 선언부입니다!

결국 지금 컬러틴트 효과를 사용할 것이기 때문에(페이드효과처럼) 기본 색상값과 바뀔 색상값이 필요하구요!
그리고 코루틴을 사용할 것이기 때문에 코루틴 변수를 같이 선언해 줬습니다!

가장 중요한 부분입니다! 이걸로 틴트 효과를 구현해 낼 거예요!
먼저 코루틴을 사용할 것이기 때문에 IEumerator를 반환하는 메서드로 만들어주고, 매개변수로 bool값을 받습니다
그리고 화면이 어두워지는 효과와 밝아지는 효과 총 2가지가 있는데, 0이면 밝게 1이면 어둡게 (알파값 조절) 해줄 것이기 때문에 매개변수로 받은 부울변수로 구분해서 목표가 밝아지는 건지 어두워지는 건지 방향성을 정해줍니다!
Mathf.Approximately 라는 내부함수가 쓰였는데, 이게 뭐냐면
두 실수 값이 거의 같은지 확인하는 함수입니다. 이 함수는 부동소수점 숫자의 비교에서 발생할 수 있는 오차를 무시하고 두 값이 충분히 가까운지 체크할 때 사용됩니다. 예를 들어볼까요?
예시 1
// 사람의 눈에는 같지만, 실제로는 부동소수점 연산에서 다르게 처리되는 예시
float value1 = 0.1f + 0.1f + 0.1f; // 0.3f로 예상
float value2 = 0.3f; // 정확히 0.3f로 설정
if (value1 == value2)
{
Debug.Log("같습니다!"); // 이 조건은 "같습니다!"를 출력하지 않습니다.
}
else
{
Debug.Log("다릅니다!"); // 실제로 "다릅니다!"가 출력됩니다.
}
좀 딥한 얘기 기는 한데 저희가 보기에는 0.3f랑 똑같은데 출력을 보면 결과값이 다르다고 나옵니다!
- 사람은 value1과 value2가 같다고 생각할 수 있지만, 컴퓨터에서는 value1이 조금 더 큰 값이나 조금 더 작은 값으로 처리될 수 있습니다.
- 실제로 부동소수점 값은 정확하게 0.1을 저장할 수 없기 때문에, 0.1 + 0.1 + 0.1을 더했을 때 부동소수점 오차로 인해 **value1과 value2**가 정확히 같은 값이 되지 않습니다.
이런 문제를 겪지 않게 하고자 있는 함수가 Mathf.Approximately입니다! 그러니까 1과 0에 엄청 가까운 값이 될 때까지 while문을 돌려주기 위해서 사용했습니다!
값은 Clamp를 통해서 항상 0~1로 떨어지게끔 만들어줬구요! 시간과 설정속도와 방향성(0으로갈지 1로 갈지)을 같이 설정해 줬습니다! 컬러의 보간을 통해서 점차 어두워지거나 밝아지는 효과를 구현해 냈습니다!
그리고 또 중요한 얘긴데 모든 작업이 끝나면 코루틴을 담았던 변수를 초기화해 줄 겁니다! 이 얘기는 조금 있다가 더 하도록 하죠!

실질적으로 코루틴을 실행시킬 구문입니다! 트랜지션에 있는 트리거에 플레이어가 들어가면 씬 전환을 시켜줬었잖아요?
근데 씬 전환이 일어나는 중간에 계속해서 트리거를 밟는다면 여러 가지 문제가 발생될 수 있습니다! 같은 코드를 여러 번 반복호출하고 그로 인해서 에러가 장난이 아니게 많이 뜰 수 있죠!
그래서 코루틴이 끝나는 곳에 코루틴 변수를 null로 직접 지정을 해줬던 겁니다! 마찬가지로 중복적으로 트리거를 왔다 갔다 한다거나 그런 상황을 대비해서 가드절을 하나 더 추가해 놨습니다!
이렇게 설정을 해두고 Tint와 UnTint를 호출하면 각 상황에 맞는 코루틴을 실행하게 됐습니다!

그러면 이제 각 상황에 호출을 하러 가보겠습니다! GameSceneManager.cs 파일로 갑니다!

먼저 아까 만든 ScreenTint.class를 참조할 변수를 하나 만들어주고요!

바로 할당도 해줍니다! 그리고 이곳에 코루틴을 하나 더 만들어 보겠습니다!

왜 하나를 더 이쪽에 만드느냐면 기본적으로 컬러틴트 효과를 코루틴으로 만들면서 코루틴이 따로 돌고 있잖아요?
근데 GameSceneManager에서 어두워지고 밝아지고 있는데 다른 곳으로 보내거나 하면 안 되겠죠? 그래서 이쪽에도 걸리는 시간만큼 대기를 시켜주기 위해 코루틴을 사용했습니다!
그리고 아까 말한 것처럼 씬 전환이 연속적으로 일어나야 하는 일이 플레이 중에 분명 생길 것 같다고 생각합니다!
(저는 왔다 갔다 많이 하거든요! 저만 그런가요?)
그렇기 때문에 대기하는 시간 또한 컬러틴트와의 시간을 공유해야만 합니다!
컬러틴트는 시간 * 설정 속도 * 방향성 이었잖아요? 기준점은 1과 0이구요! 그 시간을 역으로 계산해 줘야 시간이 맞습니다!
이 부분은 왜 그런지 보시면서 이해하시는 게 좋을 것 같아요!
씬 전환에 들어가서 컬러틴트 효과가 시작되면 tintedTime이 1을 향해 설정된 속도로 갑니다!
그런데 조건문에 screenTint.tintedTime이 0.01보다 크면 이라고 조건문이 되어있죠? 이거는 호출의 상관관계인지 뭔지는 잘 모르겠지만, tintedTime이 초기에 0으로 시작함에도 넘어오는 값을 보면 0.01 언저리로 넘어와요! (디버그로 확인!)
물론 컬러틴트가 진행이 되던 도중에 호출을 하면 다른 값으로 들어오게 만들었구요! 아무튼
결국 하고 싶었던 건, 씬전환이 초기상태에서 일어난 거냐, 아니면 씬전환 중에 전환이 일어난 거냐를 구분하고 싶었던
겁니다! 부울변수를 하나 추가할까도 했는데 변수를 너무 많이 사용하는 것도 조금 그런 것 같아서 그냥 이렇게 해봤어요..!
아무튼! 이렇게 구분을 해주고 계산식에 나누기가 쓰이는 이유는, 예로 설정속도가 0.5라고하면 tintedTime은 2초로 늘어나겠죠? 1.5초 아니야? 라고 생각하실 수 있는데 흘러가는 시간 * 설정속도니까 0.5면 2초가 됩니다!
그렇기 때문에 1초를 기준으로 잡고 계산을 할 때 나누기를 해주는 겁니다! 이렇게 하면 서로가 딱 맞습니다! 어느 정도 오차는 있겠지만요!
그리고 나서 이 코루틴 함수는 private으로, 캡슐화를 해서 사용할 거라서 외부에서 호출해서 사용할 수 있게 InitSwitchScene이라는 메서드를 같이 만들어서 InitSwitchScene()를 호출하면 코루틴을 실행시키게 만들어줬습니다!
그러면 이제 Transition.cs 파일로 가서 이 InitSwitchScene을 호출해 주면 되겠죠?
Transition.cs로 갑니다!

네 이렇게 호출을 해줬구요! 실행해 보면

씬 전환이 잘 됩니다! 여러 번 왔다 갔다 해도 잘되구요!!
다음 편에서 계속하겠습니다!
'StardewValleyLikeGameCloneCoding' 카테고리의 다른 글
Stardew Valley like Game in Unity Episode 18-1 Crafting (0) | 2025.03.24 |
---|---|
Stardew Valley like Game in Unity Episode 17-2 Smooth scene transition (0) | 2025.03.20 |
Stardew Valley like Game in Unity Episode 16-2 Scene Transition (0) | 2025.03.18 |
Stardew Valley like Game in Unity Episode 16-1 Scene Transition (0) | 2025.03.18 |
Stardew Valley like Game in Unity Episode 15-2 Dialogue system (0) | 2025.03.18 |