LINQ는 SQL(Structured Query Language)처럼 간결한방식으로 컬렉션(배열, 리스트 등)이나 데이터 소스에 대해 데이터를 조회, 필터링, 정렬, 변형할 수 있게 해주는 기능이고, 쿼리(Query)를 C# 언어에 통합한 데이터 질의 기능이다. (LINQ에 관해서는 C# 시리즈에 따로 내용을 정리할 것이다.) LINQ를 사용할 때 쿼리 구문 방식과 메서드 구문 방식이 있다.
OrderBy()는 데이터를 오름차순으로 정렬하는 LINQ의 메서드로 메서드 구문 방식이다.
⚔ 카드 무작위 섞기
// 배열 크기는 초기화할 때 정해진다
int[] arr = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7 };
// Linq를 사용한 셔플
// x => Random.Range(0f, 7f) : 배열을 순회하면서 x 값 자체는 전혀 사용되지 않고,
// x 하나당 랜덤 숫자 하나를 만들어서 랜덤 숫자를 기준으로 오름차순 정렬하는 것이다.
// ToArray(): OrderBy를 쓰면 IEnumerable<T>를 반환하기 때문에 사용
arr = arr.OrderBy(x => Random.Range(0f, 7f)).ToArray();
IEnumerable<T>란?"하나씩 차례대로 꺼낼 수 있는 객체(컬렉션)"를 의미하는 인터페이스로 List<T>, Array, Queue<T>, HashSet<T> 같은 대부분의 컬렉션은 내부적으로 IEnumerable<T>를 구현하기 때문에 이런 컬렉션들은 foreach 반복이 가능하다.
런타임에 에셋을 로딩할 때 사용하는 폴더로 Resources.Load<T>("Path") 메소드를 활용해서 에셋을 동적으로 불러올 수 있다. Resource 폴더는 어디 위치해도 Unity가 자동으로 인식하고, 여러 개가 존재해도 상관 없다. (빌드 시 하나의 큰 디렉토리에 묶어서 빌드에 포함시킨다.)
⚔ Enemy prefab을 Resources 폴더에서 Load 후 생성
GameObject obj = Resources.Load<GameObject>("Prefabs/Enemy");
Instantiate(obj);
Resource 폴더 사용을 하면 간단하게 에셋을 불러올 수 있지만 에셋들이 게임 시작 시 메모리에 로드될 준비가 되기 때문에 런타임 메모리 사용량 증가 문제가 생길 수 있다는 말과 아래 유니티 공식 매뉴얼을 보면 메모리 관리에 불리한 것 같습니다.
유니티 매뉴얼
https://docs.unity3d.com/kr/2023.2/Manual/BestPracticeUnderstandingPerformanceInUnity6.htmlResources 폴더는 Unity 프로젝트에서 많은 문제를 유발하는 일반적인 원인입니다. Resources 폴더를 잘못 사용할 경우 프로젝트의 빌드 크기가 커지고 통제 불가능할 정도로 메모리를 과도하게 사용하게 되어 애플리케이션 시작 시간이 크게 늘어날 수 있습니다.
이 폴더의 문제점으로 인해 프로덕션 애플리케이션에는 덜 적합하지만, 빠른 프로토타이핑에는 유용할 수 있습니다.새 프로젝트의 전체 프로덕션을 위해서는 일반적으로 에셋 구성에 Addressables 패키지를 사용해야 합니다.
때문에 프로토타이핑에는 Resources 폴더를 이용해도 괜찮지만 상용 서비스를 하려면 Addressables 패키지 사용은 선택이 아닌 필수인 것 같다.