[Unity] 12. 싱글톤 & 코루틴 캐싱

치치·2025년 3월 5일
0

Unity

목록 보기
14/27
post-thumbnail

코루틴 - 캐싱 기법

  • 코루틴을 사용하는 과정에서 GC(가비지 컬렉터)를 생성하게 된다

→ 최적화 하지 않으면 GC비용이 증가한다 (반복적으로 StartCoroutine()이 호출되거나 WaitForSecondsnew로 할당될때 여러개의 객체가 생성될 수 있다)

  • 코루틴 최적화를 하기 위해서는 YieldInstruction을 최적화 해야한다
  • yield 구문 자체는 가비지 값을 생성하지 않지만, new가 붙는 것들은 가비지가 생성되기 때문에 캐싱해주는 것이 좋다

  • WaitForSeconds 의 원형을 보면, 클래스 타입으로 YieldInstruction 을 상속받고 있다 (return Yield 타입들)
  • 그래서 new WaitForSeconds를 호출할때마다 새로운 객체가 생성된다

while문을 돌려서 자주 호출하면 GC부하 증가 (유니티는 자동으로 GC가 메모리를 정리하긴 함)

  • 즉, WaitForSeconds 참조변수를 미리 생성해두고 재사용하면 불필요한 객체 생성을 막을 수 있다 (클래스는 참조타입)

→ 이것이 캐싱


  • 미리 WaitForSeconds 타입의 참조변수를 생성하고, new로 동적할당

waitForSeconds 를 재사용할 수 있다

→ 캐싱을 사용하지 않으면, new WaitForSeconds를 호출할 때마다, 힙에 새로운 객체가 생성되는 것 (비효율적)

참고 : https://velog.io/@livelyjuseok/C-Unity-코루틴-Yield-최적화-하기IEqualityComparer



싱글톤

  • 게임 내에서 단 하나의 객체만 존재하도록 보장하는 디자인 패턴이다
  • 유니티에서 게임 매니저, 오디오 매니저, 데이터 관리 매니저 등 전역적으로 하나만 존재해야 하는 객체를 만들 때 사용된다

싱글톤의 특징

  • 전역 접근 가능
    • 어디서든 Singleton.Instance로 접근 가능
    • → static으로 선언했기 때문 (전역)
  • 객체 중복 방지
    • 게임 매니저, 사운드 매니저 등 한 개만 유지해야 하는 객체 관리 가능
  • 데이터 공유
    • 씬이 변경되어도 데이터 유지 가능 (DontDestroyOnLoad() 사용)
  • 퍼포먼스 최적화
    • 불필요한 객체 생성 방지 → 이미 객체가 하나 있다면 생성하지 않음

오디오 매니저를 싱글톤으로 만들어보자!

  • AudioManager 타입의 참조변수 instancestatic으로 생성한다

→ 전역으로 생성하였기 때문에, 이 클래스를 모든 곳에서 사용할 수 있다 (공유)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AudioManager : MonoBehaviour
{
    [SerializeField] AudioSource audioSource;

    private static AudioManager instance;

    // AudioManger 타입의 정적 참조 변수
    public static AudioManager Instance { get { return instance; } }

    private void Awake()
    {
        audioSource = GetComponent<AudioSource>();
        // 맨 처음 참조변수는 null을 가리킴 (데이터 안넣은 상태)
        // -> null이라면 참조변수가 자기 자신을 가리키게
        if(instance == null)
        {
            instance = this;
            Debug.Log(Instance);
        }
        else // null이 아니라면
        {

        }
    }

    public void Listener(AudioClip audioClip)
    {
        audioSource.PlayOneShot(audioClip);
    }
  • AudioManager 클래스 타입으로 생성된 참조변수 instance는 전역으로 생성되었기 때문에, 메모리의 DATA영역에 생성된다

  • static으로 선언된 변수는 클래스 자체에 속하고, 객체 인스턴스 없이도 접근할 수 있다

  • 스택영역에 있는 다른 객체들이 이 참조 변수를 참조해서 객체에 접근할 수 있는 것

  • 실제 참조변수는 private로 선언하였고, 따로 만든 Instance 참조변수를 통해 해당 instance를 반환하게 작성하였다 (캡슐화)

  • 참조변수를 선언하면 초기값으로 null이 들어있기 때문에, 어떤 객체도 가리키고 있지 않은 상태이다 → 새 객체를 할당해줘야함

  • 현재 AudioManager클래스의 객체를 참조하게 this로 가리킨다 (this는 현재 객체)


외의 싱글톤들

제네릭 싱글톤 : https://deff-dev.tistory.com/124 / 지연 싱글톤 :


믹사모 사용하기

  • 믹사모에서 캐릭터를 가져올때, 각 캐릭터마다 본(뼈)구조를 갖고있다
  • 애니메이션도 해당 캐릭의 본에 맞춰서 가져와진다 → 다른 캐릭터에 이 애니메이션을 적용할 수 없음 (이미 본에 맞는 애니메이션이기 때문)

캐릭터 포멧타입 : FBX for Unity(.fbx)

애니메이션 포멧 타입 : 동일, Without Skin

  • 만약 애니메이션이 기존 위치값이 변하는 애니메이션이라면?

InPlace 체크해서 가져오기 → 위치값이 변하지 않고 제자리에서 움직인다


  • 믹사모에서 모델을 가져오면, 가져온 직후에 텍스쳐가 모델에 입혀지지 않은 상태이다

→ 모델과 다르게 텍스쳐가 따로 포멧되어 저장되어 있는 상태

Extract Textures를 사용하여 텍스쳐를 추출



2D 3D를 동시에 송출하는 방법

2D(UI 화면)와 3D(게임 오브젝트)를 카메라로 함께 송출하는 경우는 주로 캐릭터 선택창이나 상태창에서 사용된다

ex) 예시로 구현한 엘소드 캐릭터 선택창

  • renderTexture 를 사용한다

  • 실시간으로 렌더링 되는 이미지 → raw Image를 생성한다

  • 카메라는 총 2개를 사용한다

→ 2D 화면을 비춰줄 카메라 1개, 3D 게임 오브젝트를 비춰줄 카메라 1개

→ 카메라에는 AudioListener 컴포넌트가 디폴트로 들어가있기 때문에, 하나의 카메라에만 있도록 해주기

  • 카메라가 2개일때 렌더링 되는 순서

Depth에 따라서 렌더링 순서가 달라진다 (카메라 컴포넌트에 붙어있음)

숫자가 더 높을수록 앞에 렌더링되어 보인다 (우선순위 높아짐)

  • 3D 게임오브젝트를 비춰줄 카메라 컴포넌트의 Target Texture에 생성한 Render Texture를 넣어준다

  • 생성한 Raw Image에도 Render Texture 넣어주기

    다 적용하면 아래의 형태로 나온다

raw Image에서 2번째 카메라가 비추는 화면이 송출된다

→ 근데 배경까지 같이 나와버려서 어색하다

  • 3D 게임 오브젝트를 비추는 화면의 Clear FlagsSolid Color로 변경해준다

Clear Flags : 카메라가 씬을 렌더링할 때, 배경을 어떻게 그릴지를 결정하는 프로퍼티

  • Skybox : 기본적인 배경인 하늘상자

  • solid Color : 단색 배경 (투명도를 0으로 하면 투명하게 보인다)

  • Depth Only : 배경을 지우지 않고, 오브젝트의 깊이 정보만 업데이트

  • Don't Clear : 배경을 지우지 않는다 (다중 카메라 설정에 사용)


결과물

  • 만약 캐릭터를 위에서 보고 싶다거나 더 가까이서 보고싶다면

→ 대신 비춰주는 raw Image 의 사이즈를 키우거나, 카메라의 위치값과 회전값을 조정

  • 만약 캐릭터를 더 선명하게 보고싶다면

Render TextureSize를 조정한다 (해상도)

참고 : Render Texture를 사용한 엘소드 캐릭터 선택창

https://youtu.be/BTX5SMji5v4?si=oqAdp5rCb5ybGUWW


애니메이션 이벤트

  • 애니메이션을 실행했을때, 특정 시점에서 내가 이벤트를 호출하고 싶을때 사용된다
  • 애니메이션 클립 → Animation → Events

Add Event로 이벤트 추가하면 키 프레임이 나온다

원하는 시점에 이벤트를 발생시킬 수 있다 → 함수 이름 정확하게 적기

Function 함수에 정의해둔 로직이 애니메이션이 실행되고 설정된 프레임에 실행된다

profile
뉴비 개발자

0개의 댓글