일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 스프링부트
- 프리티어
- 위키북스
- 자바개발자
- 인디게임
- 오블완
- 인프라
- 백엔드개발자
- 도커
- CICD
- 라피신
- 게임개발동아리
- 생활코딩
- 체크인미팅
- UNIDEV
- 온라인테스트
- 배포
- 백엔드
- EC2
- 개발공부
- 스프링
- Developer
- RDS
- 티스토리챌린지
- 전국대학생게임개발동아리연합회
- UNICON2023
- AWS
- UNICON
- 프로그래밍
- 42서울
- Today
- Total
Hyun's Wonderwall
유니티 페이드 인&페이드 아웃 효과 주기 - Panel의 불투명도를 조절 본문
유니티 2D 게임의 씬 전환 등에서 페이드 인/페이드 아웃 효과를 주고자 한다. 체크박스 on/off를 통해 페이드인과 페이드아웃 효과를 모두 줄 수 있는 스크립트를 원해서 공부하며 만들어 보았다. 덕분에 Coroutine을 조금 더 잘 이해하게 된 것 같다.
FadeController.cs
효과를 줄 오브젝트(GameObject panel)와 페이드인여부(bool isFadeIn)를 인스펙터에서 지정하면, 페이드인과 페이드아웃 중 하나를 적용할 수 있는 스크립트이다.
(1) 효과를 주고자 하는 씬에서 UI > Panel 오브젝트를 하나 만들어 Image 색을 검정으로 지정했다.
(2) 작성한 FadeController.cs를 Canvas에 붙였다.
- IsFadeIn을 체크하면 페이드인, 체크를 하지 않으면 페이드아웃.
- Panel에는 위의 오브젝트 FadePanel을 넣었다. Panel에 직접 붙이지 않은 이유는 Panel을 활성화/비활성화하는 코드가 있기 때문이다. (-> Panel을 통해 전환 효과 중에 클릭을 막기 위해)
isFadeIn이 true이면 해당 씬을 플레이하는 즉시 페이드인이 된다.
isFadeIn이 false이면 다른 외부 스크립트에서 FadeOut()을 호출하면 페이드아웃이 된다.
(3) 콜백을 고려하기: 외부 스크립트에서 페이드 효과를 호출하는데 그 이후에 다른 동작을 해야 하는 경우가 있다.
(예: 씬을 전환하는 외부 스크립트에서 FadeOut()을 호출하는 경우, 씬 전환 동작이 페이드아웃 효과가 종료된 이후에 일어나야 함)
외부 스크립트에서 씬에 FadeController가 있는지 찾고, 있는 경우 FadeController의 RegisterCallback 메소드를 호출해 다음 동작을 저장한 후에 페이드 효과 메소드를 호출하도록 한다. (->효과를 끝마친 후 액션을 필드에서 확인하고 invoke됨)
(외부 스크립트 코드는 생략)
*참고한 블로그들: https://blog.naver.com/bestmic/221335432969, https://makerejoicegames.tistory.com/87
(4) FadeController 스크립트 코드
using System;
using System.Collections;
using UnityEngine;
public class FadeController : MonoBehaviour // Panel 불투명도 조절해 페이드인 or 페이드아웃
{
public bool isFadeIn; // true=FadeIn, false=FadeOut
public GameObject panel; // 불투명도를 조절할 Panel 오브젝트
private Action onCompleteCallback; // FadeIn 또는 FadeOut 다음에 진행할 함수
void Start()
{
if (!panel)
{
Debug.LogError("Panel 오브젝트를 찾을 수 없습니다.");
throw new MissingComponentException();
}
if (isFadeIn) // Fade In Mode -> 바로 코루틴 시작
{
panel.SetActive(true); // Panel 활성화
StartCoroutine(CoFadeIn());
}
else
{
panel.SetActive(false); // Panel 비활성화
}
}
public void FadeOut()
{
panel.SetActive(true); // Panel 활성화
Debug.Log("FadeCanvasController_ Fade Out 시작");
StartCoroutine(CoFadeOut());
Debug.Log("FadeCanvasController_ Fade Out 끝");
}
IEnumerator CoFadeIn()
{
float elapsedTime = 0f; // 누적 경과 시간
float fadedTime = 0.5f; // 총 소요 시간
while (elapsedTime <= fadedTime)
{
panel.GetComponent<CanvasRenderer>().SetAlpha(Mathf.Lerp(1f, 0f, elapsedTime / fadedTime));
elapsedTime += Time.deltaTime;
Debug.Log("Fade In 중...");
yield return null;
}
Debug.Log("Fade In 끝");
panel.SetActive(false); // Panel을 비활성화
onCompleteCallback?.Invoke(); // 이후에 해야 하는 다른 액션이 있는 경우(null이 아님) 진행한다
yield break;
}
IEnumerator CoFadeOut()
{
float elapsedTime = 0f; // 누적 경과 시간
float fadedTime = 0.5f; // 총 소요 시간
while (elapsedTime <= fadedTime)
{
panel.GetComponent<CanvasRenderer>().SetAlpha(Mathf.Lerp(0f, 1f, elapsedTime / fadedTime));
elapsedTime += Time.deltaTime;
Debug.Log("Fade Out 중...");
yield return null;
}
Debug.Log("Fade Out 끝");
onCompleteCallback?.Invoke(); // 이후에 해야 하는 다른 액션이 있는 경우(null이 아님) 진행한다
yield break;
}
public void RegisterCallback(Action callback) // 다른 스크립트에서 콜백 액션 등록하기 위해 사용
{
onCompleteCallback = callback;
}
}
위의 코드가 가장 깔끔한 페이드인&아웃 방법이고
아래는 시행착오 코드들이다.
(1) 이 코드는 Canvas에 Canvas Group 컴포넌트를 추가해 하위 UI들의 투명도를 조절 가능하는 코드이다.
Canvas 하위 Sprite Render 오브젝트들의 투명도가 조절 안되어.. 동작은 하지만 원하는 것은 이루지 못했다.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FadeController : MonoBehaviour
{
public bool isFadeIn; // true=FadeIn, false=FadeOut
public CanvasGroup canvasGroup;
private float elapsedTime = 0f; // 경과 시간
private float fadedTime = 1f; // 총 소요 시간
private Action onCompleteCallback; // FadeIn 또는 FadeOut 다음에 진행할 함수
void Start()
{
canvasGroup = GetComponent<CanvasGroup>();
if (!canvasGroup)
{
Debug.LogError("canvasGroup 컴포넌트를 찾을 수 없습니다.");
throw new MissingComponentException();
}
// Fade In Mode
if (isFadeIn)
{
canvasGroup.alpha = 0f;
StartCoroutine(CoFadeIn());
}
// Fade Out Mode
else
{
canvasGroup.alpha = 1f;
// FadeOut 함수 호출 시 코루틴 시작
}
}
public void RegisterCallback(Action callback) // 다른 스크립트에서 콜백 액션 등록하기 위해 사용
{
onCompleteCallback = callback;
}
public void FadeOut()
{
StartCoroutine(CoFadeOut());
}
IEnumerator CoFadeIn()
{
while (elapsedTime <= fadedTime)
{
canvasGroup.alpha = Mathf.Lerp(0f, 1f, elapsedTime / fadedTime);
elapsedTime += Time.deltaTime;
yield return null;
}
}
IEnumerator CoFadeOut()
{
while (elapsedTime <= fadedTime)
{
canvasGroup.alpha = Mathf.Lerp(1f, 0f, elapsedTime / fadedTime);
elapsedTime += Time.deltaTime;
yield return null;
}
if (onCompleteCallback != null)
{
onCompleteCallback();
}
}
}
(2) 이 코드는 (1) 코드에서 Canvas 자식들 오브젝트들의 Sprite Render 불투명도를 조절하는 코드이다.
이와 같이 하면 겹쳐있는 스프라이트들이 비쳐보이게 되어 실패... 그러나 나중에 쓸 일이 있을 수도 있을 것 같아 기록해둔다.
using System;
using System.Collections;
using UnityEngine;
public class FadeCanvasController : MonoBehaviour // 캔버스 전체를 페이드인 or 페이드아웃
{
public bool isFadeIn; // true=FadeIn, false=FadeOut
private Action onCompleteCallback; // FadeIn 또는 FadeOut 다음에 진행할 함수
void Start()
{
canvasGroup = gameObject.GetComponent<CanvasGroup>();
if (!canvasGroup)
{
Debug.LogError("CanvasGroup 컴포넌트를 찾을 수 없습니다.");
throw new MissingComponentException();
}
if (isFadeIn) // Fade In Mode -> 바로 코루틴 시작
{
canvasGroup.alpha = 0f;
StartCoroutine(CoFadeIn());
}
else // Fade Out Mode -> FadeOut 함수 호출 시 코루틴 시작
{
canvasGroup.alpha = 1f;
}
}
public void FadeOut()
{
Debug.Log("FadeCanvasController_ Fade Out 시작");
StartCoroutine(CoFadeOut());
Debug.Log("FadeCanvasController_ Fade Out 끝");
}
IEnumerator CoFadeIn()
{
float elapsedTime = 0f; // 누적 경과 시간
float fadedTime = 0.5f; // 총 소요 시간
while (elapsedTime <= fadedTime)
{
canvasGroup.alpha = Mathf.Lerp(0f, 1f, elapsedTime / fadedTime); // Canvas가 투명 -> 불투명
SetChildRenderersAlpha(Mathf.Lerp(0f, 1f, elapsedTime / fadedTime));
elapsedTime += Time.deltaTime;
Debug.Log("Fade In 중...");
yield return null;
}
Debug.Log("Fade In 끝");
onCompleteCallback?.Invoke(); // 이후에 해야 하는 다른 액션이 있는 경우(null이 아님) 진행한다
yield break;
}
IEnumerator CoFadeOut()
{
float elapsedTime = 0f; // 누적 경과 시간
float fadedTime = 0.5f; // 총 소요 시간
while (elapsedTime <= fadedTime)
{
canvasGroup.alpha = Mathf.Lerp(1f, 0f, elapsedTime / fadedTime); // Canvas가 불투명 -> 투명
SetChildRenderersAlpha(Mathf.Lerp(1f, 0f, elapsedTime / fadedTime));
elapsedTime += Time.deltaTime;
Debug.Log("Fade Out 중...");
yield return null;
}
Debug.Log("Fade Out 끝");
onCompleteCallback?.Invoke(); // 이후에 해야 하는 다른 액션이 있는 경우(null이 아님) 진행한다
yield break;
}
void SetChildRenderersAlpha(float alpha)
{
// Canvas 하위의 모든 Renderer를 찾아서 투명도를 조절
Renderer[] renderers = gameObject.GetComponentsInChildren<Renderer>(true);
foreach (Renderer renderer in renderers)
{
renderer.material.color = new Color(renderer.material.color.r, renderer.material.color.g, renderer.material.color.b, alpha);
}
}
public void RegisterCallback(Action callback) // 다른 스크립트에서 콜백 액션 등록하기 위해 사용
{
onCompleteCallback = callback;
}
}
'Study > Unity, C#' 카테고리의 다른 글
[가상현실] 유니티 AR 카메라로 사진 촬영 (1) | 2024.05.11 |
---|---|
유니티 - 버튼 텍스트, TextMeshPro 가로세로 폭 맞추기 (0) | 2024.01.22 |
유니티 에러 - [Collab] Collab service is deprecated and has been replaced with PlasticSCM (0) | 2024.01.01 |
[유니티 공부] 랜덤 확률 버튼 미니게임 (0) | 2024.01.01 |
유니티 공부 - (1) 유니티 준비, 인터페이스 둘러보기 (2) | 2023.12.28 |