Unity 개발에 자주 쓰이는 개념 - cheona-thousand-man/Unity-myBasics-Wiki GitHub Wiki
- static
-
event
-
선언 방식 1
public delegate void TimerStarted();
public static event TimerStarted OnTimerStarted;
-
선언 방식 2
public static event Action OnTimerStarted;
-
이벤트 발생
OnTimerStarted?.Invoke();
-
선언 방식 1
-
delegate(함수 포인터)
함수 포인터에 실행할 로컬 함수를 할당(저장)
= 함수 위치의 목록이 포함된 주소록
= 이벤트 핸들러와 콜백- 이벤트 핸들러(구독)
OnTimerStarted += TimerStartAction();
- 이벤트 콜백
public delegate void Callback();
StartCoroutine(MyCoroutine(OnComplete));
Ienumerator MyCoroutine(Callback callback) {callback();}
void OnComplete();
- 이벤트 핸들러(구독)
-
generic
클래스 선언 시 자료형 유예 & 인스턴스화 할 때 자료형 선언 -
Serialize
오브젝트 인스턴스를 스트림(파일/네트워크)에 전송하기 위해 binary로 변환하는 과정
- prefab
-
Unity event, Action
-
Unity Event 멀티캐스트 델리게이트 역할(다중 구독 가능)
public UnityEvent myEvent;
myEvent.AddListner(MyEventListner);
myEvent.Invoke();
-
Unity Action 단일 델리게이트 방식(다중 구독 불가)
public Action myAction;
myAction = MeyActionMethod;
myAction?.Invoke();
→myEvent.AddListner(myAction);
-
Unity Event 멀티캐스트 델리게이트 역할(다중 구독 가능)
-
ScriptableObject 데이터 컨테이너, 인스턴스(게임 설정/상태/데이터 등)를 에셋으로 저장
- 게임 데이터와 로직 분리(오브젝트X): 데이터 중심 설계
- Inspecter에서 편집 가능
- 재사용 가능
- ScriptableObject 클래스 정의
먼저, ScriptableObject 클래스를 정의합니다.
using UnityEngine;
[CreateAssetMenu(fileName = "NewCharacterData", menuName = "Character Data", order = 51)]
public class CharacterData : ScriptableObject
{
public string characterName;
public int health;
public int attackPower;
}
위 코드에서는 CharacterData라는 ScriptableObject 클래스를 정의했습니다. CreateAssetMenu 속성을 사용하여 에디터에서 쉽게 생성할 수 있도록 했습니다.
- ScriptableObject 인스턴스 생성
이제 에디터에서 CharacterData 인스턴스를 생성할 수 있습니다.- 에디터 상단 메뉴에서 Assets -> Create -> Character Data를 선택합니다.
- 새로운 CharacterData 에셋을 생성하고, 필요한 데이터를 입력합니다.
- ScriptableObject 사용
생성한 CharacterData 인스턴스를 게임에서 사용하려면, 이를 참조하는 스크립트를 작성합니다.
using UnityEngine;
public class Character : MonoBehaviour
{
public CharacterData characterData;
void Start()
{
if (characterData != null)
{
Debug.Log($"Character Name: {characterData.characterName}");
Debug.Log($"Health: {characterData.health}");
Debug.Log($"Attack Power: {characterData.attackPower}");
}
}
}
이 스크립트를 게임 오브젝트에 추가하고, 인스펙터에서 CharacterData 에셋을 드래그하여 characterData 필드에 할당합니다.
-
Coroutine
-
시작과 중지
StartCoroutine(Method());
StopCoroutine(Method());
-
모두 중지
StopAllCoroutines();
-
일시 중지와 재개
yield return new WaitWhile(() => {condition});
yield return new WaitUntil(() => !{condition});
yield return new WaitForSeconds({time:float});
-
다른 코루틴 호출
yield return StartCoroutine(InnerCoroutine());
- 반환 값 처리
-
시작과 중지
public class CoroutineWithReturn : MonoBehaviour
{
void Start()
{
StartCoroutine(MyCoroutine(result => Debug.Log("결과: " + result)));
}
IEnumerator MyCoroutine(Action<int> callback)
{
yield return new WaitForSeconds(2);
int result = 42; // 임의의 계산 결과
callback(result);
}
}
public class CoroutineWithTask : MonoBehaviour
{
async void Start()
{
int result = await MyCoroutine();
Debug.Log("결과: " + result);
}
Task<int> MyCoroutine()
{
var tcs = new TaskCompletionSource<int>();
StartCoroutine(MyCoroutineRoutine(tcs));
return tcs.Task;
}
IEnumerator MyCoroutineRoutine(TaskCompletionSource<int> tcs)
{
yield return new WaitForSeconds(2);
int result = 42; // 임의의 계산 결과
tcs.SetResult(result);
}
}
public class CoroutineWithUniTask : MonoBehaviour
{
async void Start()
{
int result = await MyCoroutine();
Debug.Log("결과: " + result);
}
async UniTask<int> MyCoroutine()
{
await UniTask.Delay(2000);
int result = 42; // 임의의 계산 결과
return result;
}
}
- Chaining Couroutines
IEnumerator CoroutineChain()
{
yield return StartCoroutine(CoroutineA());
yield return StartCoroutine(CoroutineB());
yield return StartCoroutine(CoroutineC());
}
IEnumerator CoroutineA()
{
Debug.Log("Coroutine A 실행 중...");
yield return new WaitForSeconds(1);
}
IEnumerator CoroutineB()
{
Debug.Log("Coroutine B 실행 중...");
yield return new WaitForSeconds(1);
}
IEnumerator CoroutineC()
{
Debug.Log("Coroutine C 실행 중...");
yield return new WaitForSeconds(1);
}