카테고리 없음

2025.07.03 13주차 목요일

mochoa 2025. 7. 3. 21:10

1. EquipmentManager 리팩토링

    • TryEquip / TryUnequip
      • 이미 장착된 모델이 있으면 자동으로 TryUnequip() 후 교체하도록 처리
      • CategoryWithPrefab 를 통해 ID 기반 매핑 대신, EquipmentItem SOequippedPrefab 을 직접 참조하여 Instantiate
    • PrefabReference 컴포넌트
      • 런타임 및 에디터 환경 구분 없이, 인스턴스화된 모델에 원본 프리팹 정보(originalPrefab)를 저장

변경 전

var accessor = World.GetReadOnlyAccessor<GameObject>(EquipableData.ID);
accessor.TryGetValue(peek.ID, out var prefab);

변경 후

  • EquipmentItem SOequippedPrefab 필드 추가
  • TryEquip 최상단에 기존 장착 제거 로직 추가
  • SO 에서 직접 프리팹을 가져와 Instantiate
protected void TryEquip(ItemStack stack)
{
    // 0) 이미 장착된 모델이 있으면 교체
    if (currentModel != null)
        TryUnequip();

    // 1) ItemStack → EquipmentItem SO 캐스팅
    var equipmentItem = stack.Item as EquipmentItem;
    if (equipmentItem == null)
    {
        Debug.LogError("이 아이템은 장비가 아닙니다!");
        return;
    }

    // 2) SO에 연결된 프리팹 직접 사용
    var prefab = equipmentItem.equippedPrefab;
    if (prefab == null)
    {
        Debug.LogError($"[{equipmentItem.name}]에 프리팹이 할당되지 않았습니다.");
        return;
    }

    currentModel = Instantiate(
        prefab,
        rightHand.position,
        rightHand.rotation,
        rightHand
    );
    currentModel.AddComponent<PrefabReference>()
               .originalPrefab = prefab;

    // 3) 스택 처리
    equippedStack = equippedSlot.Slot.ExtractAll();
    uiSlotComponent.InsertPossible(equippedStack);
}

2. PlayerController와 Input System 통합

  • InputActionsEquip(R), Unequip(Q) 액션 추가
  • PlayerController 에서
    • playerActions.Equip.started += OnEquipInputStarted
    • playerActions.Unequip.started += OnUnequipInputStarted
  • 콜백에서 equipmentManager.IssueCommand(new EquipCommand(...)) / new UnequipCommand() 호출하여 장착 로직 위임

변경 전

void Update()
{
    if (Input.GetKeyDown(KeyCode.R)) { /* 장착 */ }
    if (Input.GetKeyDown(KeyCode.Q)) { /* 해제 */ }
}

변경 후

  • InputActionsEquip(R), Unequip(Q) 액션 생성
  • OnEnable/OnDisable 에서 액션 구독 추가
  • 콜백에서 equipmentManager.IssueCommand 호출
private void OnEnable()
{
    playerInputs.Enable();
    playerActions.Equip.started   += OnEquipInputStarted;
    playerActions.Unequip.started += OnUnequipInputStarted;
}

private void OnDisable()
{
    playerInputs.Disable();
    playerActions.Equip.started   -= OnEquipInputStarted;
    playerActions.Unequip.started -= OnUnequipInputStarted;
}

private void OnEquipInputStarted(InputAction.CallbackContext ctx)
{
    var stack = equipmentManager.equippedSlot.Slot.Peek();
    equipmentManager.IssueCommand(new EquipCommand(stack));
}

private void OnUnequipInputStarted(InputAction.CallbackContext ctx)
{
    equipmentManager.IssueCommand(new UnequipCommand());
}

3. GatherInteractable 개선: 도구 제한 기능

  • AllowedToolPrefabs 리스트로 허용 도구 프리팹 에디터에서 드래그·드롭으로 설정
  • BeginInteract()
    1. EquipmentManager.rightHand 자식으로 붙은 현재 모델 획득
    2. PrefabReference 또는 PrefabUtility / 이름 비교를 통해 원본 프리팹 확인
    3. AllowedToolPrefabs.Contains(prefab) 검사 후, 허용 도구가 아니면 채집 로직 return

변경 전

  • 모든 도구 무조건 채집 가능

변경 후

  • AllowedToolPrefabs 리스트로 프리팹 직접 비교
  • PrefabReference 를 통해 원본 프리팹 확인
public List<GameObject> AllowedToolPrefabs;

public override void BeginInteract(GameObject interactor)
{
    var equipMgr = interactor.GetComponent<EquipmentManager>();
    // 현재 손에 붙은 모델 가져오기
    var child = equipMgr.rightHand.childCount > 0
        ? equipMgr.rightHand.GetChild(0).GetComponent<PrefabReference>()?.originalPrefab
        : null;

    if (child == null || !AllowedToolPrefabs.Contains(child))
    {
        Debug.LogWarning("필요한 도구가 장착되어 있지 않습니다.");
        return;
    }

    // 채집 로직...
}