Unity_본캠프

[내일배움캠프 39일차] 뚝딱딱 뚝딱 제작대 만들기

티백고래 2025. 6. 2. 01:24

1. 오늘의 할 일

작업 철야라고 읽는다

제작대를 만들 겁니다.

만들고 싶은 구조는 다음과 같은데, 잘 되려나....

 

2. 작업 개시🛠️

일단 테스트용 제작 레시피를 만들어둔다.

돌 2개면 border-corner-round를 만들 수 있다.

작업을 시작하기 전에, 각 아이템들에게 Icon이 잘 달려있는지 확인해주자.

 

이제 역할을 정하자

CraftingSystem = 제작 시스템 전반. Recipe의 정보를 받아와서 실제로 아이템을 캐릭터의 인벤토리나 건축 시스템에 할당하는 역할을 한다.

CraftSlot = 레시피 슬롯. 현재 제작 가능한 아이템의 개수를 표시하고, 레시피를 선택하는 역할을 한다. (제작 불가인 경우 alpha값을 0.4로 만든다.)

ResourceSlot = 재료 슬롯, 필요한 재료를 표시한다. (가능하다면, 재료가 부족할 경우 아이콘의 Alpha값을 줄이고 표기를 붉은 색으로 하기)

 

그럼 각 슬롯을 할당해줄 UI를 미리 만들어준다. (나중에 만들어도 되겠지만, 나는 UI 깔아두고 보면서 하는 쪽이 편하다...)

 

 

UI를 주르륵 만들고, 스크립트를 짜기 시작했다.

CraftingSystem은 CraftingUI에 할당, CraftSlot과 ResourceSlot은 각각의 슬롯의 프리펩에 할당했다.

핵심은 CraftingSystem으로, UI에 반영되는 모든 요소와 제작에 사용되는 모든 로직을 품고있다.

그리고 가장 문제도 많았다....

 

무슨 문제가 생겼나요?

같은 레시피가 무한히 증식하기도 하고(슬롯을 파괴하는 로직을 넣지 않아 생긴 일이다. 아직 넣기 전이었으니, 작동하지 않는 게 당연하다.)

우측에 있는 재료칸에는 재료의 이미지가 전부 할당되지 않았다.
특히 재료칸이 업데이트 되지 않는 게 가장 큰 문제였는데, 수정하는 과정에서 다음과 같은 모양새를 보았다.

 

 

1. 중복호출되어 슬롯이 2개 생성, 시간차를 두고 사라짐

 

2. 계속 빈 슬롯 하나만 나오는 현상(기존에도 문제가 되던 현상)

 

3. 누를 때마다 증식하는 슬롯

(슬롯 파괴 로직을 제거한 후 나타난 현상. 처음 생성된 슬롯 외의 슬롯에는 할당되지 않는 모습.)

 

처음엔 2번의 현상의 문제 때문에 튜터님께 여쭤봤는데, 문제 초반 Debug.LogWarning을 찍자 다음과 같은 형태를 보였다.

 

 

저장해뒀던 사진을 잃어버려 튜터님이 찍어주신 오류로그....

한 번 눌렀는데도 같은 오류가 4번 반복된다.

즉=>중복호출이 된다. 그것도 4번이나.

 

출력된 위치를 확인한 결과, 서로 다른 두 곳에서 2번씩 번갈아 호출되었다.

특히 이 함수가 4번 호출.

(본래는 가장  상단에 슬롯들을 전부 부수는 로직이 적혀있다.)

 

튜터님: 한 프레임에 슬롯이 파괴와 생성이 반복되니까 문제가 생기는 것 같다. 그래서 보통 파괴로직과 생성로직을 함께 쓰진 않는다.

=> 그래서 코루틴으로 파괴로직을 지연시켰더니 1.과 같은 현상이 발생했다.


4번이나 중복된 이유

1. 구조상 버튼을 누르면 CraftingSystem의 SetRecipe를 부르고 UpdateRecipeUI를 부르게 되어있는데, SetRecipe에서도 UpdateRecipe를 부르고 있었다. =즉, UpdateRecipe가 한 번의 클릭에 각자 다른 위치에서 2번 호출되었다.

=> OnClickButton에 있는 UpdateRecipeUI 부분을 지우자 4회의 반복이 2번으로 줄었다.

하지만 그럼에도 계속 한 번 클릭할 때마다 호출이 두 번 되었다. 하지만 그 외의 UpdateRecipeUI를 부르는 부분은 없었다.

 

2.  CraftSlot.cs 에는 다음과 같은 로직이 있다.  

    private void Awake()
    {
        button.onClick.AddListener(OnClickButton);
    }

즉, 게임을 시작할 때 onClickAddLisener를 해당 버튼에 할당하고, 해당 슬롯을 누르면 OnClickButton 함수를 호출하는 것이다.

그런데, 내가 Inspecter창에서도 버튼을 할당해버린 것이다.

=>코드상으로는 중복이 없지만 시스템 상으로 중복이 있었다.

 

위의 두 개의 문제를 해결하자, 레시피를 눌렀을 때 아이콘이 정상적으로 할당되었다!

…고 하고 싶지만, 문제는 여전히 남아있었다.

 

 

같은 레시피를 다시 한 번 더 클릭하면, 슬롯이 사라지는 것이다.

이는 마치 호출을 두 번 한 것과 같은 효과로, 실제 호출은 한 번인데도 발생하는 일이다.

무엇이 문제인가 코드를 살펴보다가, 문제의 코드가 아래의 코드임을 확인했다.

 

 

 

코드를 보면 ResourceSlot을 GetChild(i)로 받아오고있다.

여기서 i는 반복문에 사용되는 것으로, 해당 코드는 for문을 통해 해당 레시피의 0번 재료부터 n번째 재료까지 불러오는 기능을 수행하고 있다.

하지만, GetChild로 불러낸 slot은 이미 파괴된 후이므로, 기존 slot에 할당하지 못하게 된다.

새로 만들어진 n+i번째 슬롯은 빈칸이 되는 것이다.

 

그럼 어떻게 해결할까?

=>GameObject로 slot을 선언해서, 그곳에 직접 Instantiate를 실행하도록 하자!

 

그렇게 수정한 내용 코드

:

이렇게 하면 새 재료가 할당될 때마다, 해당 반복회차에 생성된 slot에 itemData와 필요한 재료 개수를 할당하게 된다.

완성된 기능의 모습은 다음과 같다.

 

 

 

3. 완성

코드가 점점 길어질 수록, 서로 기능을 넘겨받을 수록 점차 헷갈리고 어디서 문제가 발생했는지 알아차리기 어려워진다는 것을 느꼈다.

GetChild는 그다지 안쓰는 게 좋다는 말을 들었지만, 괜히 써보고 난 뒤 정말 왜 쓰면 안되는지 알게 되는 시점이었다. (...)