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

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로 접근 가능DontDestroyOnLoad() 사용)AudioManager 타입의 참조변수 instance를 static으로 생성한다→ 전역으로 생성하였기 때문에, 이 클래스를 모든 곳에서 사용할 수 있다 (공유)
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(UI 화면)와 3D(게임 오브젝트)를 카메라로 함께 송출하는 경우는 주로 캐릭터 선택창이나 상태창에서 사용된다
ex) 예시로 구현한 엘소드 캐릭터 선택창

renderTexture 를 사용한다
raw Image를 생성한다
→ 2D 화면을 비춰줄 카메라 1개, 3D 게임 오브젝트를 비춰줄 카메라 1개
→ 카메라에는 AudioListener 컴포넌트가 디폴트로 들어가있기 때문에, 하나의 카메라에만 있도록 해주기
→ Depth에 따라서 렌더링 순서가 달라진다 (카메라 컴포넌트에 붙어있음)
숫자가 더 높을수록 앞에 렌더링되어 보인다 (우선순위 높아짐)

Target Texture에 생성한 Render Texture를 넣어준다
생성한 Raw Image에도 Render Texture 넣어주기
다 적용하면 아래의 형태로 나온다
→ raw Image에서 2번째 카메라가 비추는 화면이 송출된다
→ 근데 배경까지 같이 나와버려서 어색하다

Clear Flags를 Solid Color로 변경해준다
Skybox : 기본적인 배경인 하늘상자
solid Color : 단색 배경 (투명도를 0으로 하면 투명하게 보인다)
Depth Only : 배경을 지우지 않고, 오브젝트의 깊이 정보만 업데이트
Don't Clear : 배경을 지우지 않는다 (다중 카메라 설정에 사용)
→ 대신 비춰주는 raw Image 의 사이즈를 키우거나, 카메라의 위치값과 회전값을 조정
→ Render Texture의 Size를 조정한다 (해상도)


참고 : Render Texture를 사용한 엘소드 캐릭터 선택창
https://youtu.be/BTX5SMji5v4?si=oqAdp5rCb5ybGUWW
Animation → Events
Add Event로 이벤트 추가하면 키 프레임이 나온다
원하는 시점에 이벤트를 발생시킬 수 있다 → 함수 이름 정확하게 적기

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