![[1인개발 프로젝트] 하늘소 프로젝트 5주차](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1S6cq%2FbtsETWLbjGC%2FKqV1NMByDn5RwSsag2FhxK%2Fimg.png)
저번 주차에 데이터베이스를 구현하고 Isomtric 타일 맵을 쓰기 위해 그에 맞는 테스트 타일을 제작하였다.
그리고 이번 주차는, 정말 맨 땅에 헤딩만 하다가 그 땅이 엄한 땅이었음을 알게 된 주차였다.
정말... 한 것은 많지만 이뤄낸 것은 없는 것 같다는 말이 제일 잘 어울린다.
아무래도 짜다 보니 스파게티 코드가 된 것이 모든 악의 근원인 것 같다.
그래서 미리 말하자면, 이번 주차에 했던 내용은 싹 다 갈아엎어지거나 일부만 유지하고 다시 작업해야 할 것 같다.
아니 그래서 뭘 했는데?
NPC 상호작용 기능 구현
셀 필드 파밍 기능에서는 플레이어가 움직이며 탐험하는 것도 있지만 NPC, 아이템과의 상호작용도 존재한다.
그래서 우선 NPC와의 상호작용을 먼저 구현하기로 하고 개발에 들어갔다.
랜덤 타일맵 선택
전체적인 로직을 설명하자면, 타일 맵을 여러개 만들어놓은 후 (최종 완성 시에는 요일별로 3~4개 쯤 만들 듯) 이것을 랜덤으로 뽑아와 거기에 미리 배치되어있는 NPC와 대화하게 하는 것이다.
int randomInt = Random.Range(0, 범위);
를 사용하면 0부터 범위 - 1 구간 (개구간) 까지에서 랜덤한 정수를 하나 뱉는다. 이때 실수를 출력하고 싶다면 float로 설정하면 되고, 이럴 때는 범위가 포함되어서 랜덤값을 뱉는다.
이것을 사용하여 간단하게 타일맵을 고른 후 고른 타일맵만 보이게 하는 코드를 작성했다.
int rand = Random.Range(0, tilemaps.Length);
for (int i = 0; i < tilemaps.Length; i++)
{
if (i != rand)
{
GameObject targetGrid = tilemaps[i].transform.parent.gameObject;
targetGrid.SetActive(false);
}
}
tilemap = tilemaps[rand];
타일 맵들을 인스펙터에서 배열에 넣어준 후 그것들 중에서 골라 남은 것들을 비활성화 하는 식이다.
이것을 전에 만들었던 플레이어 이동 알고리즘에 적용시켜 랜덤 타일맵에서도 이동하도록 구현했다.
그리고, 이 이후에 NPC와 직접적으로 대화하는 기능을 구현하려고 했다.
NPC와의 대화 - 미완성
전체 로직을 설명하자면, 게임 화면의 중앙 하단 쯤에 버튼을 하나 두어 근처에 상호작용 요소가 없을 때에는 비활성화, 있을 때에는 활성화되어 버튼을 눌러 상호작용을 시작하고, DOTween을 이용한 대사창으로 대화를 이어나가거나 퀘스트를 받는 상호작용을 가능하게 할 예정이었다.
int rand = PathFinder.Instance.rand;
target = NPCTiles[rand];
playerPos = target.WorldToCell(player.transform.position);
up = new Vector3Int(playerPos.x + 1, playerPos.y, 0);
down = new Vector3Int(playerPos.x - 1, playerPos.y, 0);
left = new Vector3Int(playerPos.x, playerPos.y + 1, 0);
right = new Vector3Int(playerPos.x, playerPos.y - 1, 0);
if (target.HasTile(up))
{
button.interactable = true;
text.text = "대화하기";
npcLocation = "up";
}
else if (target.HasTile(down))
{
button.interactable = true;
text.text = "대화하기";
npcLocation = "down";
}
else if (target.HasTile(left))
{
button.interactable = true;
text.text = "대화하기";
npcLocation = "left";
}
else if (target.HasTile(right))
{
button.interactable = true;
text.text = "대화하기";
npcLocation = "right";
}
else
{
button.interactable = false;
text.text = "주변에 아무것도 없습니다.";
npcLocation = "none";
}
이것이 저 계획을 토대로 짠 Update 함수 내부 코드이다. 플레이어의 상하좌우 방향으로 타일처리된 NPC가 있는지 판단하고, 있다면 그에 맞는 좌표로 상호작용을 실행한다.
여기까지는 잘 작동하였다. 그런데, 이 다음부터 문제가 사막에서 석유 찾은것 마냥 펑펑 터졌다.
대화를 진행하는 함수를 짜고 보니 Update -> 대화 관리 함수 -> 대화 함수 -> Update -> ... 의 함수 무한 참조 현상이 발생하였다. 의도한대로 작동하기는 했지만, 이대로 대화 기능을 방치하면 나중에 다른 기능과 충돌의 가능성이 있을 뿐만 아니라 다른 사람에게 욕먹기 딱 좋은 구성이 되어버린다.
그리고, 치명적으로, 잘 작동하던 instance를 사용한 싱글톤 구조와 GetComponent가 작동을 하지 않기 시작했다.
다른 데에서는 instance를 통해 변수를 불러오던, 함수를 불러오던 문제 없이 불러와졌는데, 유독 이번에 짠 스크립트가 바보가 된건지 작동하지 않았다. 해결해보려고 애를 써봤지만 결국 방법은 찾지 못했다.
그리고, Getcomponent는 왜 작동을 하지 않는지 모르겠다... 저건 유니티 내장인데...
이런 문제들과 4~5시간 씨름을 하다가 결국 포기하고 심신의 안정을 위해 이번 주차에는 그만하기로 했다.
사실 게임의 메인 기능이라 이런 문제들이 생길 것이라는 것은 어느정도 예상하고 있었다. 근데 무엇을 언제 하든 의도대로 코드가 작동하지 않으면 작동하지 않는대로 무섭고, 잘 작동하면 작동하는대로 무섭다. 이거 왜 오류가 안나지? 나게 해놨는데
이번 주차를 통해 얻은 필요한 것 / 생각할 것들이 몇가지 있다.
- 셀 필드 파밍 기능에 대한 전반적인 재구성
- NPC와의 대화기능 로직 그림으로 그려서 이해하고 넘어가기
- 랜덤 타일맵 선택 기능 갈아엎기 or 그대로 (갈아엎는다면 타일맵 정보를 json 저장)
- 데이터베이스 간소화 (id로 구분하는 등 객체가 갖는 멤버변수의 간소화)
- 그림은 나아아아중에. 기획은 됐으니 개발이 먼저.
- 이번 주차에 겪었던 문제들 조사 및 해결
이것들이 다음 주차 혹은 그 다음 주차까지 해결해야 할 목표인 것 같다.
이번 주차는 한 것이 없었지만, 매를 먼저 맞았다고 생각하고있다. 학기 중에 개발하다가 이런 문제가 닥쳤으면 그대로 측두엽이 바람좀 쐬고 온다고 했을지도 모른다.
그리고, 슬슬 다른 프로젝트를 진행할 차례이다. 예정된 프로젝트가 두 개 있으니 이 이상 더 일을 벌리지 않는 것이 좋을 것 같다...
버텨라. 네가 선택한 유니티다.
내가 왜 이런 선택을

몸져 누운 나
'1인 개발 > 하늘소 프로젝트' 카테고리의 다른 글
[1인개발 프로젝트] 하늘소 프로젝트 6주차 (0) | 2024.02.25 |
---|---|
[1인개발 프로젝트] 하늘소 프로젝트 4주차 (1) | 2024.02.09 |
[1인개발 프로젝트] 하늘소 프로젝트 3주차 (2) | 2024.02.02 |
[1인개발 프로젝트] 하늘소 프로젝트 2주차 (1) | 2024.01.19 |
[1인개발 프로젝트] 하늘소 프로젝트 1주차 (4) | 2024.01.12 |
안녕하세요! 코드 짜는 농부입니다! 경희대학교 소프트웨어융합학과 23학번 재학중입니다. 문의 : dsblue_jun@khu.ac.kr
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!