Audio Source (2D sound, 3D sound)
Audio Listener

SoundManager사운드를 관리하는 매니저 스크립트
사운드를 매니저 스크립트로 관리해서, 씬이 넘어가도 파괴되지 않고 전체적인 소리 관리를 담당한다
-> 필요한 오브젝트에서 사운드를 호출해서 사용하는 방식으로 많이 씀
매니저 스크립트는 주로 싱글톤으로 구현한다
(디자인 패턴 - 자세히)
AudioSource 타입을 담을 수 있는 객체를 생성한다
매니저 스크립트에 Listener 함수를 정의하고, 매개변수로 AudioClip이 들어온다
-> PlayOneShot : 인자로 넣은 오디오 클립을 즉시 한번만 재생하는 메서드 (AudioSource 컴포넌트의 프로퍼티 값이 바뀌는 건 아님)
-> AudioClip : 실제로 재생 할 오디오 파일
Listener함수를 호출하기 위해서는audioSource객체를 사용해야한다
이 객체를 사용하기 위해서는AudioSource컴포넌트를 가져와야함!!!! (GetComponent)

Random.Range()특정 범위 내에서 난수를 생성하는 방법
Random.Range(min, max)min과 max 사이의 정수, 실수를 랜덤으로 반환한다
-> 매개변수의 값에 따라 정수, 실수 가능
-> min이상 max 미만
ex) random = Random.Range(1, 6);
1이상 6미만의 값들 중 랜덤으로 한 값이 random변수에 저장된다
Random.value0과 1 사이의 실수 난수를 반환한다
ex) float random = Random.value;
5초마다 랜덤한 숫자를 Debug로 찍어보기 위해 Update함수에서 연산 식을 짜보았다
Update함수는 매 프레임마다 호출된다
매 프레임마다 연산을 많이 수행하면, 그만큼 CPU가 더 많은 일을 하게 되어 CPU 점유율이 증가
코루틴을 사용한다면 자신이 필요한 순간에만 반복하고 필요하지 않을 때에는 전혀 사용하지 않음으로써 자원관리를 매우 효과적으로 할 수 있다
그러니 Update문에서 모든 연산을 다 정의하고 처리하지 않고, 내가 필요할때만 해당 함수를 호출하여 사용하는 편이 더 효율적이다

코루틴은 비동기적으로 실행할 수 있기 때문에 이 말의 뜻은 이해하고 가자
: 프로그램이 여러 작업을 처리하는 방식의 차이
Synchronous)작업들이 순차적으로 실행되는 방식
한 작업이 끝나야만 다음 작업이 시작되며, 각 작업은 서로 기다리며 실행
Asynchronous)작업들이 동시에 실행될 수 있는 방식
한 작업이 진행되는 동안 다른 작업이 기다리지 않고 독립적으로 실행

특정 작업을 여러 프레임에 걸쳐서 비동기적(동시에)으로 실행할 수 있도록 하는 기능이다
당장 실행되는게 아니라 일정 시간동안 멈춰있다가 그 뒤에 동작하게 하거나, 특정 조건을 부여해서 코드가 실행되는 기능도 할 수 있다
코루틴은 IEnumerator라는 반환형으로 시작해야한다
yield return이 반드시 함수 내부에 존재해야한다
코루틴의 실행은 StartCoroutine() 메서드를 사용해야한다
코루틴의 종료는 StopCoroutine()을 사용해야한다
-> yield break;와 역할은 동일하지만, yield break;는 코루틴 내부에서, StopCoroutine()은 코루틴 외부에서 실행한다
IEnumerator 함수이름()
{
yield return // + 조건
// 함수 내용
}
yield return null; : 다음 프레임에 실행 된다
yield return new WaitForSeconds( float ); : 매개변수로 입력한 숫자에 해당하는 초만 큼 기다렸다가 실행된다
-> 유니티 상에서의 시간을 기준으로 체크
yield return new WaitForSecondsRealtime( flaot ); : 매개변수로 입력한 숫자에 해당하는 초만큼 기다렸다가 실행된다
-> 현실 시간을 기준으로 체크
그외 : yield return + new WaitForFixedUpdate / WaitForEndOfFrame 등...
yield break;
-> 조건을 만족했을때, 코루틴을 종료하는 코드 (코루틴 내에서)
코루틴 내부에 for문이나 while문을 사용하면 업데이트 문 처럼 매 프레임마다 반복되게 사용할 수 있다
-> Update문은 따로 동작 중!
ex) 5초마다 random 변수의 값을 출력하는 Coroutine 사용법

시작 → 실행 → 일시 정지(yield) → 재개 → 종료
yield return)에 따라 실행을 멈췄다가 다시 실행
코루틴은 서브 루틴처럼 작동하여, 주 루틴 내에서 일정 시간이 걸리는 작업을 비동기적으로 실행한다

코루틴은 유니티의 메인 루틴에 의해 호출되며, 코루틴이 실행되는 동안 메인 루틴은 계속 다른 작업을 처리할 수 있다 (비동기적)
메인 루틴이 한 프레임을 처리하는 동안, 코루틴은 yield를 통해 대기하거나 다른 조건이 충족될 때까지 멈출 수 있다

✅ 코루틴은 메인 루틴과 독립적으로 실행된다
-> 메인 루틴과 병렬적(멀티스레드)으로 실행되는 것 처럼 보일 수 있다

using UnityEngine;
using System.Collections;
public class CoroutineExample : MonoBehaviour
{
void Start()
{
Debug.Log("1️⃣ Start() 실행 - 메인 루틴");
StartCoroutine(MyCoroutine());
Debug.Log("2️⃣ Start() 끝 - 메인 루틴");
}
IEnumerator MyCoroutine()
{
Debug.Log("3️⃣ 코루틴 시작");
yield return new WaitForSeconds(2f); // 2초 대기
Debug.Log("4️⃣ 코루틴 다시 실행 (2초 후)");
}
}


-> 코루틴이 별도의 스레드에서 실행되는 것이 아님!! 메인루틴 돌 고 있을때 비동기적으로 실행되는 것이고, 메인 루틴과 병렬로 실행되는 것이 아니라!!! 잠시 정지되었다가 다시 실행되는 느낌