손님 AI에서, 손님이 랜덤한 자리로 가서 음식을 기다리는 행동을 만들고 있다.
랜덤한 자리로 가되, 다른 손님이 없는 자리로 가야한다.
List<bool> _isCustomerSitting 와
List<Transform> _destinations 를 만들어 모든 자리의 Transform값을 인스펙터에서 받아
Random.Range 함수로 _destinations중 하나의 Transform값을 정해 손님 AI 의 목적지를 지정해주고,
_isCustomerSitting[index] = true를 해주는 방식으로 구현했다.
빠르고 간단하게 구현한다면 다른 손님이 없는 자리가 나올 때까지 while문과 Random.Range함수를 돌려 목적지를 지정해주는 방법이 있겠지만, 가챠도 아니고.. 그렇게 구현하고 싶지 않았다.
아래 코드는 손님이 없는 자리들의 List를 새로 만들어 그 중에서 랜덤하게 자리를 지정해주는 코드다.
IEnumerator CreateCustomerCoroutine()
{
while (_currentCustomerNum < _maxCustomerNum)
{
//TODO: Object Pool?
List<(Transform destination, int index)> availableDestinations = _destinations
.Select((d, index) => (d, index))
.Where(tuple => !_isCustomerSitting[tuple.index])
.ToList();
if (availableDestinations.Count <= 0)
yield break;
int customerTypeNum = Random.Range(0, _customerPrefabs.Count);
GameObject customerObject = Instantiate(_customerPrefabs[customerTypeNum], _createCustomerPos);
int seatNum = UnityEngine.Random.Range(0, availableDestinations.Count);
Transform selectedDestination = availableDestinations[seatNum].destination;
customerObject.GetComponent<NpcController>().DecideDestination(selectedDestination);
_isCustomerSitting[availableDestinations[seatNum].index] = true;
++_currentCustomerNum;
yield return new WaitForSeconds(1f);
}
}
아직 익숙하지 않지만 LINQ를 사용해봤다.
List<(Transform destination, int index)> availableDestinations = _destinations
.Select((d, i) => (d, i))
.Where(tuple => !_isCustomerSitting[tuple.i])
.ToList();
Select((d, i) => (d, i))로 _destinations의 각 원소와 그의 index값이 들어있는 valueTuple를 만들고
Where문으로 tuple의 index에 해당하는 자리를 검사해 다른 손님이 앉지 않은 자리면
해당 자리의 Transform과 index를 availableDestinations에 넣어줬다.
Linq를 사용해보기 전 썼던 코드
List<Transform> tempList = new List<Transform>();
for (int i = 0; i < _destinations.Count; ++i)
{
if (!_isCustomerSitting[i])
{
tempList.Add(_destinations[i]);
}
}
위 로직을 Linq를 사용해 나타낸 코드
List<Transform> availableDestinations = _destinations.Where((d, index) => !_isCustomerSitting[index]).ToList();
참고
Tuple, ValueTuple은 두 개 이상의 타입을 묶어 사용할 때 클래스나 구조체를 정의하지 않고 사용할 수 있게 해준다.
Tuple과 ValueTuple의 차이점 (더보기)
Tuple: 가변, 값 변경 가능
new Tuple<T1, T2>(value1, value2) 와 같이 선언 가능
각 요소에 이름 명시할 수 없음 Item1, Item2 등으로 접근
ValueTuple: 불변, 값 변경 불가능
(value1, value2) 와 같이 선언가능
각 요소에 이름 명시 가능
(int num, Transform d)와 같이 이름 명시가능
새로운 List를 만든 후, AI의 목적지로 랜덤 자리를 지정해줬다.
분명 더 나은 방법이 있겠지만 당장은 이 방법밖에 안떠오른다.
'내일배움캠프(Unity)' 카테고리의 다른 글
TIL - AI agent priority, Food Creater (0) | 2024.01.18 |
---|---|
손님 AI 3 - 음식 매칭, 식당 나가기 (1) | 2024.01.16 |
GameManager 관련 미니 특강 (0) | 2024.01.15 |
TIL - 손님 AI 1 (1) | 2024.01.12 |
최종프로젝트 시작 특강 (0) | 2024.01.10 |