컨베이어 벨트가 설비와 연결될 때, 단순히 모든 아이템을 주고받는 것이 아니라 선택한 입출력 포트의 아이템만 이동하도록 수정했다.
기존에는 컨베이어 벨트를 설비 옆에 설치하면 설비의 OutputBuffer에 들어 있는 아이템이 구분 없이 벨트로 이동했다. 예를 들어 설비의 출력이 청동판과 석탄 가루 두 가지라면, 사용자가 석탄 가루만 빼내고 싶어도 컨베이어 벨트에는 모든 output 아이템이 섞여 나오는 문제가 있었다.
컨베이어 벨트 설치 후 열리는 연결 위젯에서 사용자가 특정 input 또는 output 슬롯을 선택하고, 벨트가 그 선택 정보를 기준으로 아이템을 이동하도록 구조를 정리했다.
컨베이어 벨트 연결 위젯의 역할 정리
컨베이어 벨트 연결 위젯은 벨트를 설비의 어느 포트에 연결할지 선택하는 UI다.
설비의 레시피가 다음과 같다고 하면,
Input : 청동, 석탄
Output : 청동판, 석탄 가루
벨트가 설비에 아이템을 넣는 방향이면 Input 슬롯이 표시되고, 설비에서 아이템을 빼내는 방향이면 Output 슬롯이 표시된다.
즉, 사용자는 벨트를 설치한 뒤 다음과 같은 선택을 할 수 있다.
Input 1 : 청동
Input 2 : 석탄
또는
Output 1 : 청동판
Output 2 : 석탄 가루
이때 선택하는 것은 설비의 특정 포트 슬롯이다.
const FKOFactoryPortSlot PortSlot(Kind, Index, ItemHint);
여기서 Kind는 Input 또는 Output이고, Index는 포트 번호, ItemHint는 해당 포트에 표시되는 아이템 정보다.
선택한 포트 정보를 벨트에 저장
슬롯을 클릭하면 위젯에서는 선택한 포트 정보를 컨베이어 벨트에 넘긴다.
Belt->BindToMachinePort(Building, ClickedSlot);
이후 벨트는 선택한 포트 정보를 내부에 저장한다.
BoundMachine = Machine;
BoundKind = Slot.Kind;
BoundPortIndex = Slot.PortIndex;
BoundItemId = Slot.ItemId;
bHasSelectedPort = true;
여기서 중요한 값은 BoundItemId와 bHasSelectedPort다.
BoundItemId는 이 벨트가 어떤 아이템 포트에 연결되었는지를 의미한다. 예를 들어 석탄 가루 output 슬롯을 선택했다면 BoundItemId에는 석탄 가루 아이템 ID가 저장된다.
bHasSelectedPort는 사용자가 실제로 슬롯을 선택했는지 여부를 나타낸다. 이 값이 false라면 아직 포트 선택이 완료되지 않은 상태이므로, 벨트가 설비에서 아이템을 꺼내면 안 된다.
Output 포트 선택 전에는 아이템을 꺼내지 않도록 처리
가장 큰 문제는 위젯에서 슬롯을 선택하기 전에 벨트가 먼저 동작하면서 설비의 모든 output 아이템을 가져오는 것이었다.
이를 막기 위해 벨트가 설비의 Output 포트와 연결될 예정인 상태라면, 포트 선택이 끝나기 전에는 아이템을 꺼내지 않도록 했다.
if (!bHasSelectedPort || BoundItemId.IsNone())
{
return;
}
즉, Output 바인딩 상태인데 아직 슬롯을 선택하지 않았거나 선택한 아이템 정보가 없다면, 벨트는 설비에서 아무 아이템도 가져오지 않는다.
선택한 Output 아이템만 꺼내도록 수정
기존 로직에서는 설비에서 아이템을 가져올 때 일반적인 PopOutputItem()을 사용했다.
Src->PopOutputItem(Pulled)
이 방식은 특정 아이템을 지정하지 않고 output 버퍼에서 꺼낼 수 있는 아이템을 가져오는 구조다. 그래서 석탄 가루 슬롯을 선택해도 청동판까지 함께 벨트로 나오는 문제가 생겼다.
수정 후에는 Output 포트에 바인딩된 벨트라면 BoundItemId 기준으로만 아이템을 꺼내도록 했다.
if (Proc->TryExtractItem(BoundItemId, 1) == 1)
{
Slots[0] = FKOConveyorItem(BoundItemId);
}
이제 석탄 가루 output 슬롯을 선택하면, 해당 벨트는 석탄 가루만 꺼낸다. 청동판은 같은 설비의 output에 존재하더라도 이 벨트로 이동하지 않는다.
Output 바인딩 후 일반 Pull 로직으로 내려가지 않도록 수정
수정 과정에서 중요한 부분은 Output 바인딩 처리 후 일반 Pull 로직으로 이어지지 않게 하는 것이다.
Output 포트에 바인딩된 벨트는 선택된 아이템만 꺼내야 한다. 그런데 해당 분기 이후에 다시 일반 PopOutputItem() 로직이 실행되면, 결국 모든 output 아이템이 다시 섞여 나올 수 있다.
그래서 Output 바인딩 분기에서는 처리가 끝난 뒤 바로 빠져나오도록 했다.
if (BoundKind == EKOPortKind::Output && BoundMachine.IsValid())
{
if (!bHasSelectedPort || BoundItemId.IsNone())
{
return;
}
if (UKOFactoryProcessorComponent* Proc =
BoundMachine->FindComponentByClass<UKOFactoryProcessorComponent>())
{
if (Proc->TryExtractItem(BoundItemId, 1) == 1)
{
Slots[0] = FKOConveyorItem(BoundItemId);
}
}
return;
}
이렇게 하면 Output 포트에 연결된 벨트는 항상 선택한 아이템만 처리하고, 일반 Source Pull 로직으로 넘어가지 않는다.
Input 포트 선택 시 동작
Input 포트를 선택한 경우에는 벨트가 설비에 아이템을 넣는 역할을 한다.
예를 들어 Input 슬롯에서 청동을 선택하면, 이 벨트는 설비의 청동 입력 포트에 연결된다.
이 경우 벨트 끝에 도착한 아이템이 청동일 때만 설비에 넣어야 한다. 따라서 Input 바인딩에서도 BoundItemId를 검사하는 구조가 필요하다.
const bool bCanPushToBoundInput =
bHasSelectedPort &&
!BoundItemId.IsNone() &&
Slots[TailIdx].ItemId == BoundItemId;
이 조건을 통해 청동 Input 포트에 연결된 벨트는 청동만 설비에 투입하고, 다른 아이템은 해당 포트로 들어가지 않게 만들 수 있다.
ESC로 위젯을 닫았을 때 처리
포트 선택 위젯에서 ESC를 눌러 닫는 경우도 고려했다.
ESC를 눌렀을 때는 설비와 닿아 있다는 정보는 유지하되, 선택한 포트 정보만 비우는 방식으로 처리하는 것이 적절하다고 판단했다.
BoundPortIndex = INDEX_NONE;
BoundItemId = NAME_None;
bHasSelectedPort = false;
이렇게 하면 벨트는 여전히 해당 설비의 Output 방향에 닿아 있는 상태로 남아 있고, bHasSelectedPort가 false이기 때문에 아이템을 꺼내지 않는다.
즉, ESC로 닫은 상태는 다음과 같이 해석된다.
벨트는 설치되어 있음
설비와 닿아 있음
하지만 포트는 선택되지 않음
따라서 설비에서 아이템을 꺼내지 않음
최종 동작 흐름
컨베이어 벨트와 설비의 연결 흐름은 다음과 같다.
벨트 설치
→ 설비와 닿아 있으면 연결 위젯 열림
→ 벨트는 포트 선택 대기 상태가 됨
→ 선택 전에는 설비에서 아이템을 꺼내지 않음
→ 사용자가 Output 슬롯 선택
→ BoundItemId에 선택 아이템 저장
→ 이후 해당 아이템만 벨트로 이동
예를 들어 설비의 output이 다음과 같을 때,
Output : 청동판, 석탄 가루
사용자가 석탄 가루를 선택하면:
BoundItemId = 석탄 가루
이후 컨베이어 벨트는 석탄 가루만 설비에서 꺼낸다.
반대로 ESC로 위젯을 닫으면:
bHasSelectedPort = false
BoundItemId = None
상태가 되며, 벨트는 설비에서 아무 아이템도 꺼내지 않는다.
정리
이번 작업을 통해 컨베이어 벨트가 단순히 설비의 output을 모두 가져오는 구조에서 벗어나, 사용자가 선택한 input/output 포트 기준으로 동작하도록 개선했다.
특히 BoundItemId와 bHasSelectedPort를 기준으로 벨트의 이동 로직을 제어하면서, 포트 선택 전에는 아이템이 흐르지 않고, 선택 후에는 해당 아이템만 이동하도록 만들었다.
이로써 컨베이어 벨트와 설비 간의 연결이 더 명확해졌고, 여러 output을 가진 설비에서도 원하는 아이템만 분리해서 운송할 수 있게 하였다.
'Unreal 최종 팀프로젝트' 카테고리의 다른 글
| [TIL] 튜토리얼 퀘스트 시스템 | 최종 팀프로젝트 (0) | 2026.07.08 |
|---|---|
| [TIL] 세이브 로드 시스템 | 최종 팀프로젝트 (0) | 2026.07.06 |
| [TIL] 컨베이어 벨트 고스트 프리뷰 방향 표시 | 최종 팀프로젝트 (0) | 2026.06.23 |
| [TIL] 그리드 표시 | 최종 팀프로젝트 (0) | 2026.06.22 |
| [TIL] UI 구조 개선 | 최종 팀프로젝트 (0) | 2026.06.19 |