no image
내일배움캠프 38일차 TIL [3D_Survival_Project]
🗓️ 오늘 하루 일정✅ 오전09:00 ~ 11:30 : 컨디션 로직/UI 분리BaseCondition를 IValueChangable 구현 + Health 전용으로 정리PlayerCondition에 Hunger/Stamina 추가, 이벤트(onHungerChanged/onStaminaChanged) 발행Awake() 초기 동기화(SetHunger/SetStamina)로 UI 첫 표시 안정화11:30 ~ 13:00 : PlayerConditionUI 이미지 바 동작 수정Image Type=Filled, Preserve Aspect OFF 적용폭 기반(RectTransform)도 지원하도록 SetBar() 정리🍽️ 점심시간13:00 ~ 14:00 : 점심✅ 오후14:00 ~ 14:30 : Equipment..
2025.08.21
no image
내일배움캠프 37일차 TIL [3D_Survival_Project]
🗓️ 오늘 하루 일정✅ 오전09:00 ~ 11:30 : Craft UI 연결 & 프리뷰 슬롯 NRE 수정(countText 널 가드, 버튼/아이콘 점검)11:30 ~ 12:00 : NPC 대화 타이핑 마무리 점검(스킵/완료 분기)🍽️ 점심시간13:00 ~ 14:00 : 점심✅ 오후14:00 ~ 16:00 : 브랜치 머지 정리 및 프리팹/인스펙터 재바인딩 확인16:00 ~ 17:30 : 가공 제한사항(wip) 구현 & 단위 테스트17:30 ~ 18:00 : 버그리스트/체크리스트 업데이트🍽️ 저녁시간18:00 ~ 19:00 : 저녁✅ 저녁19:00 ~ 20:00 : 전체 스크립트 검토(전반 구조/의존성 확인)20:00 ~ 21:00 : 팀 회의✅ 오늘 학습 키워드인벤토리 → 가공(Craft) 1:1 변..
2025.08.20
no image
내일배움캠프 36일차 TIL [3D_Survival_Project]
🗓️ 오늘 하루 일정✅ 오전09:00 ~ 12:30 : NPC 대화/상호작용 기획 정리 (Start → Talk x4 → End 노드 플로우, 헌터/방랑자/장인 톤 가이드)🍽️ 점심시간13:00 ~ 14:00 : 점심✅ 오후14:00 ~ 16:00 : 유니티 배치고사16:00 ~ 16:30 : 쉬는 시간16:30 ~ 18:00 : 챌린지반 특강🍽️ 저녁시간18:00 ~ 19:00 : 저녁✅ 저녁19:00 ~ 21:00 : 팀 회의 (과제 리뷰 & 상호작용 시스템 통일안 논의)✅ 오늘 학습 키워드Raycast 기준점 통일(FPS/TPS), Camera.ViewportPointToRay인터랙션 포인트(interactionRayPointTransform) 설계코루틴 재시작/중단 타이밍, StopCorou..
2025.08.19
no image
내일배움캠프 35일차 TIL [3D_Survival_Project]
🗓️ 오늘 하루 일정 (2025-08-18)✅ 오전09:00 ~ 11:30 : DOTween 기반 BaseUI 정리AnimType(None/Fade/Scale/Slide*) 재구성, ease/ignoreTimeScale/slideDistance 옵션 점검Scale 팝 연출 적용(열림: closed→overshoot→1, 닫힘: 1→overshoot→closed)11:30 ~ 13:00 : 인벤토리 UI 점검버튼 바인딩/비활성 초기화(UnActive) 정리, 선택 아이템 표시 플로우 확인🍽️ 점심시간13:00 ~ 14:00 : 점심✅ 오후14:00 ~ 16:30 : InventoryModel/InventoryMediator 최소 구성 맞춤팀원 다이어그램 기준 InventoryModel(List 기반 수..
2025.08.18
no image
내일배움캠프 34일차 TIL [NPC&UI 다이어그램]
🗓️ 오늘 하루 일정🌅 오전09:00 ~ 10:00 개인 시간10:00 ~ 10:30 게임개발 숙련 프로젝트 발제 참석10:30 ~ 팀 회의(역할/범위 정리)🍽 점심13:00 ~ 14:00 점심🌞 오후14:00 ~ 16:00 NPC, UI 다이어그램 작성16:00 ~ 18:00 UI 관련 강의 수강🍽 저녁18:00 ~ 19:00 저녁🌙 저녁 이후19:00 ~ 21:00 팀원들과 와이어프레임 리뷰✅ 오늘 학습 키워드UI 중재자 패턴UI 상태 전환 구조와이어프레임 설계 및 리뷰 프로세스팀 협업 브랜치 관리✅ 오늘 학습 한 내용을 나만의 언어로 정리하기오늘은 프로젝트 UI와 게임 오브젝트(플레이어, 적, NPC)의 데이터 흐름을 정리하기 위해 다이어그램을 직접 작성했다.BaseUI를 상속받는 다양한..
2025.08.14
no image
내일배움캠프 33일차 TIL [델리게이트 & 람다 학습 + 프로젝트 구조 개선]
🗓️ 오늘 하루 일정✅ 오전09:00 ~ 프로젝트 스크립트 구조 점검 및 정리기존 Equip, EquipTool 삭제수정된 코드들(Move_SportCar, JumpPad, ItemObject 등) 깃허브에 업로드README용 프로젝트 설명, 폴더 구조, 블로그용 글 작성 시도🍽️ 점심시간13:00 ~ 14:00 점심시간✅ 오후깃허브 README 형식 개선 작업 시도트러블슈팅 문서 작성 형식 논의델리게이트 / 람다 공부 계획 수립🍽️ 저녁시간18:00 ~ 19:00 저녁시간✅ 저녁19:00 ~ 21:00 프로젝트 구조 심화 복습델리게이트(delegate) 심화 학습 및 람다(lambda) 표현식 정리✅ 오늘 학습 키워드델리게이트 (Delegate)람다식 (Lambda Expressions)Unity..
2025.08.13
no image
Unity - Project_Up
🎮 Project_Up – Unity 3D 서바이벌 시스템 제작기안녕하세요! 오늘은 제가 진행한 Unity 프로젝트 Project_Up을 소개하려고 합니다.이 프로젝트는 3D 환경에서 플레이어가 이동하고, 오브젝트와 상호작용하며, 자원을 채집하고 아이템을 사용하는 기본적인 서바이벌형 시스템을 구현한 예제입니다.최근에는 장비(Equip) 시스템을 완전히 제거하고, 소비형 아이템 중심의 단순한 인벤토리 구조로 리팩토링을 진행했어요.덕분에 전체 구조가 훨씬 가볍고 직관적으로 변했습니다.📌 프로젝트 개요장르 : 3D 서바이벌 / 인터랙션엔진 : Unity 2021.3 LTS개발 언어 : C#주요 목표캐릭터 이동, 점프, 달리기, 카메라 제어상호작용 가능한 오브젝트와의 간단한 인터페이스소비형 아이템 중심의 인..
2025.08.13
no image
내일배움캠프 32일차 TIL [Project_Up]
🗓️ 오늘 하루 일정✅ 오전09:00 ~ 11:00 : 점프 애니메이션 추가 (OnTriggerEnter에 JumpTrigger 트리거 연동, AddForce로 물리 튕김 적용)11:00 ~ 13:00 : 맵 제작 진행 (지형 구성, 오브젝트 배치 일부)🍽️ 점심시간13:00 ~ 14:00 : 점심시간✅ 오후14:00 ~ 16:00 : 맵 배치 마무리 작업16:00 ~ 18:00 : 챌린지반 강의 수강 (주제: 델리게이트)18:00 ~ 19:00 : 자유시간 및 휴식🍽️ 저녁시간19:00 ~ 20:00 : 맵 최종 점검 및 세부 수정20:00 ~ 21:00 : 맵 제작 완성, 마무리 테스트✅ 오늘 학습 키워드Unity OnTriggerEnter 활용Rigidbody 물리 처리 (AddForce, y..
2025.08.12
반응형

🗓️ 오늘 하루 일정

✅ 오전

  • 09:00 ~ 11:30 : 컨디션 로직/UI 분리
    • BaseCondition를 IValueChangable 구현 + Health 전용으로 정리
    • PlayerCondition에 Hunger/Stamina 추가, 이벤트(onHungerChanged/onStaminaChanged) 발행
    • Awake() 초기 동기화(SetHunger/SetStamina)로 UI 첫 표시 안정화
  • 11:30 ~ 13:00 : PlayerConditionUI 이미지 바 동작 수정
    • Image Type=Filled, Preserve Aspect OFF 적용
    • 폭 기반(RectTransform)도 지원하도록 SetBar() 정리

🍽️ 점심시간

  • 13:00 ~ 14:00 : 점심

✅ 오후

  • 14:00 ~ 14:30 : EquipmentController 정리
    • Unequip() 중복 호출/널 처리 정리, Animator 캐시 안정화
  • 14:30 ~ 15:30 : PlayerAttackController 보강
    • 장비 없으면 공격 차단(_equip.HasItem 가드)
    • 카메라 리그 기준 SphereCast(트리거 포함), damageMask 미지정 시 ~0
    • 히트 시 **GetComponentInParent*로 부모까지 탐색(IDamagable/IValueChangable)
  • 15:30 ~ 16:00 : 애니메이션 이벤트 OnHit 제거 & 레이 단일화
  • 16:00 ~ 18:00 : 챌린지반 강의

🍽️ 저녁시간

  • 18:00 ~ 19:00 : 저녁

✅ 저녁

  • 19:00 ~ 20:30 : 팀 회의 & 최종 통합
    • Enemy.Die() protected override로 수정, _isDead 가드
    • FSM DeathState 전환, Animator Death Bool 연동
    • Animator 깨진 전이 정리(고아 Transition 제거)
    • InventoryUI 빌드 버튼 콜백 → 싱글톤 호출 연결
  • 20:30 ~ 21:00 : 스모크 테스트
    • 레이 히트/데미지, Death 애니 재생, 콘솔 NRE/경고 확인
  • 21:00 ~ 21:30 : 정리 & 커밋 (체크리스트 업데이트)

✅ 오늘 학습 키워드

  • Unity Animator / StateMachine / Transition, Animator.StringToHash
  • FSM(Finite State Machine): DeathState 전환, 매직넘버 → enum 계획
  • Override 흐름: BaseCondition.Die() → Enemy.Die() 오버라이드
  • 공격 판정: SphereCast + QueryTriggerInteraction.Collide
  • 콜라이더 탐색: GetComponentInParent<T>()로 자식 콜라이더 히트 대응
  • 장비 가드: _equip.HasItem 없으면 공격 무시
  • UI 게이지: Image Filled, Preserve Aspect OFF, 초기 동기화
  • InventoryUI: Build 버튼 콜백 → 싱글톤 호출
  • Animator NRE: 고아 전이(깨진 Transition) 정리

✅ 오늘 학습 한 내용을 나만의 언어로 정리하기

  • 체력/허기/스태미나 로직을 PlayerCondition으로 몰아넣고, UI는 이벤트만 받아서 바를 갱신하게 하니 디버깅이 훨씬 쉬워졌다.
  • 공격은 장착 여부 가드애니 트리거카메라 기준 SphereCast로 단일화해서, 애니메이션 이벤트 없이도 판정 타이밍이 자연스럽다.
  • Enemy는 BaseCondition.Die()를 override해야만 내 커스텀 죽음 처리(DeathState, 스폰 알림, Animator Death Bool)가 호출된다는 걸 확실히 체득했다.
  • Animator 에러는 대개 “지워진 상태로 향하는 전이”가 원인이었다. Debug Inspector에서 고아 전이를 지우니 해결.

🧩 학습하며 겪었던 문제점 & 에러

1) 적이 체력 0이어도 죽지 않음

  • 문제 정의: 데미지는 들어가는데 Death 애니/상태로 전환되지 않음.
  • 시도: Death Bool만 켜봄, 로그 출력.
  • 해결 방법: Enemy.Die()를 protected override void Die()로 변경, _isDead 가드, _fsm.ChangeTo(3) 호출.
  • 배운 점: 가상 함수는 반드시 override 해야 실제 파생 클래스 로직이 탄다.
  • 다시 만나면: 체력 0 시 호출 스택(부모→자식)과 Animator 파라미터/전이 조건을 먼저 확인.

2) 공격이 맞는데 데미지가 안 들어감

  • 문제 정의: 레이가 맞아도 HP가 그대로.
  • 시도: 레이어/마스크 확인, 로그로 hit.collider 출력.
  • 해결 방법: 히트 후 GetComponentInParent<IDamagable/IValueChangable>()로 부모까지 탐색.
  • 배운 점: 적 콜라이더가 자식에 있는 경우가 많다. 항상 부모 탐색 고려.
  • 다시 만나면: 히트 처리 유틸을 만들어 공통으로 SelfOrParent<T>() 사용.

3) Animator 창 NRE (GenerateConnectionKey)

  • 문제 정의: Animator 창을 열면 NRE가 반복 발생.
  • 시도: 레이아웃 초기화, Unity 재시작.
  • 해결 방법: Animator Controller Debug Inspector에서 m_AnyStateTransitions/m_StateMachineTransitions의 fileID:0 전이(고아 전이) 제거.
  • 배운 점: 상태 삭제 전에 전이부터 지우자.
  • 다시 만나면: 복잡해지면 컨트롤러 복제 후 재구성이 빠르다.

4) 장비 없이도 공격됨

  • 문제 정의: 맨손 상태에도 레이 공격/애니가 발동.
  • 시도: 입력 처리 위치 점검.
  • 해결 방법: OnAttack() 초입에 _equip == null || !_equip.HasItem 가드.
  • 배운 점: 입력 처리엔 사전 조건(상태 가드)을 습관화.
  • 다시 만나면: 상태/권한 체크를 공통 헬퍼로 묶기.

5) UI 게이지가 시작하자마자 가운데로 줄어듦

  • 문제 정의: 플레이 시작 시 바가 중앙으로 수축.
  • 시도: fillAmount 디버그, 레이아웃 재배치.
  • 해결 방법: Image Preserve Aspect OFF, Type=Filled, 초기값 이벤트로 동기화.
  • 배운 점: UI 스프라이트는 Preserve Aspect가 바 크기/정렬에 영향.
  • 다시 만나면: UI 체크리스트에 Preserve Aspect 항목 추가.

6) Build 버튼 콜백 미연결

  • 문제 정의: 버튼은 보이는데 동작 안 함.
  • 시도: OnBuildClicked 이벤트만 연결.
  • 해결 방법: buildButton.onClick.AddListener(ClickBuild) + 선택 슬롯에서 아이템 조회 → 싱글톤 빌드 함수 호출.
  • 배운 점: UI 버튼은 표시/콜백/권한 세 가지를 동시에 점검.
  • 다시 만나면: 버튼 초기화 함수에서 일괄 바인딩 + 널 가드.

📝 메모

  • FSM 전이 인덱스(3)enum으로 치환 필요(가독성/안전성 ↑).
  • Damage 인터페이스 두 계열(IDamagable / IValueChangable) 정리 검토(어댑터 or 통합).
  • 공격 레이 테스트 케이스(근접/비스듬/장애물) 자동화 소규모 스크립트로 만들기.
  • 로그 레벨링: Debug.Log → Logger(Info/Warn/Error)로 정리, 콘솔 스팸 줄이기.
  • DeathState에서 Collider 비활성 + 지연 파괴 루틴 통일.
  • Animator 파라미터는 **해시 상수화(EnemyAnimParam)**로만 접근해 오타 방지.

반응형
반응형

🗓️ 오늘 하루 일정

✅ 오전

  • 09:00 ~ 11:30 : Craft UI 연결 & 프리뷰 슬롯 NRE 수정(countText 널 가드, 버튼/아이콘 점검)
  • 11:30 ~ 12:00 : NPC 대화 타이핑 마무리 점검(스킵/완료 분기)

🍽️ 점심시간

  • 13:00 ~ 14:00 : 점심

✅ 오후

  • 14:00 ~ 16:00 : 브랜치 머지 정리 및 프리팹/인스펙터 재바인딩 확인
  • 16:00 ~ 17:30 : 가공 제한사항(wip) 구현 & 단위 테스트
  • 17:30 ~ 18:00 : 버그리스트/체크리스트 업데이트

🍽️ 저녁시간

  • 18:00 ~ 19:00 : 저녁

✅ 저녁

  • 19:00 ~ 20:00 : 전체 스크립트 검토(전반 구조/의존성 확인)
  • 20:00 ~ 21:00 : 팀 회의

✅ 오늘 학습 키워드

  • 인벤토리 → 가공(Craft) 1:1 변환 플로우
  • Craft UI 미리보기(입력/출력 슬롯)
  • NullReferenceException 대응(널 가드, 인스펙터 바인딩)
  • NPC 대화 타이핑 효과(스킵/완료 분기)
  • 프리팹/인스펙터 재바인딩, 브랜치 머지 전략

✅ 오늘 학습 한 내용을 나만의 언어로 정리하기

  • 가공은 “미리보기 → 확정 → 코루틴” 3단 분리가 안정적이다. UI는 미리보기 전용, Mediator는 흐름 제어, CraftSystem은 실제 처리만 맡긴다.
  • NRE는 대부분 ‘참조 누락’ + ‘가드 없음’ 조합에서 난다. UI 계층은 필수로 널 가드를 두고, 프리팹/인스펙터 바인딩을 체크리스트로 관리해야 한다.
  • 대화 타이핑은 “타이핑 중 스킵 시 전체 출력, 완료 후 다음 액션/선택지 노출”로 UX가 일관된다.
  • 머지 이후에는 프리팹/인스펙터 재바인딩 시간이 반드시 필요하다. 코드는 합쳐도 레퍼런스는 자동으로 합쳐지지 않는다.

🧩 학습하며 겪었던 문제점 & 에러

1. 가공 미리보기에서 NRE 발생

  • 문제정의: CraftUI의 슬롯 프리뷰에서 InventorySlotUI.Bind 호출 시 countText가 없는 프리뷰 슬롯에서 NRE 발생.
  • 시도: 아이콘만 쓰는 프리뷰임에도 기존 슬롯 스크립트를 그대로 사용.
  • 해결 방법: countText와 button에 널 가드 추가.
// InventorySlotUI.cs (핵심만)
public void Bind(InventorySlotData slotData)
{
    icon.sprite = slotData.itemData.icon; // 프리뷰는 보통 count=1
    if (countText)
        countText.text = slotData.count > 1 ? slotData.count.ToString() : "";
    if (button)
    {
        button.onClick.RemoveAllListeners();
        button.onClick.AddListener(() => onClick?.Invoke());
    }
}
  • 새롭게 알게 된 점: 프리뷰 슬롯처럼 ‘부분 UI’만 쓰는 케이스가 존재하므로 공용 슬롯 스크립트는 부분 필드 널 가드가 필수.
  • 다시 만나게 된다면: Bind()를 세분화(BindIconOnly, BindFull)하거나 슬롯 타입(Enum)로 분기해서 UI 의도를 명시한다.

2. Craft UI에서 출력 아이템 미리보기가 안 뜸

  • 문제정의: 가공 UI는 열리지만 우측(결과) 슬롯이 빈 상태.
  • 시도: OpenWith(input, recipe)에서 입력 바인딩만 확인.
  • 해결 방법: outputSlot.SetActive(true/false)를 분기하고, 레시피가 없을 땐 버튼 비활성화.
// CraftUI.cs (핵심만)
public void OpenWith(ItemData input, RecipeData rcp)
{
    inputSlot.gameObject.SetActive(true);
    inputSlot.Bind(new InventorySlotData { itemData = input, count = 1 });

    if (rcp != null)
    {
        var outItem = TestManager.Instance.itemDatabase.GetItemById(rcp.outputItemId);
        outputSlot.gameObject.SetActive(true);
        outputSlot.Bind(new InventorySlotData { itemData = outItem, count = 1 });
        processButton.interactable = true;
    }
    else
    {
        outputSlot.gameObject.SetActive(false);
        processButton.interactable = false;
    }
    Open();
}
  • 새롭게 알게 된 점: **UI 가시성 제어(SetActive)**와 상태 버튼 인터랙션은 동시에 관리해야 사용자가 혼란스럽지 않다.
  • 다시 만나게 된다면: 이름/설명 텍스트까지 함께 갱신하고, 레시피가 없을 때 안내 메시지 표시.

3. 가공 버튼이 바로 코루틴을 실행(가공창 무시)

  • 문제정의: InventoryMediator.HandleCraft()에서 과거 로직이 남아 있어 CraftUI를 건너뛰고 즉시 CraftCoroutine을 실행.
  • 시도: Mediator 내 Handler 정리.
  • 해결 방법: “가공 버튼 → CraftUI.OpenWith → CraftUI.OnProcess → 코루틴” 흐름으로 단일화.
// InventoryMediator.cs (핵심 흐름)
private void HandleCraft()
{
    if (selectedId == null) return;
    var recipe = manager.CraftSystem().GetTransformRecipe(selectedId.Value);
    if (recipe == null) return;

    var itemData = manager.GetItemDataById(selectedId.Value);
    craftUI.OpenWith(itemData, recipe); // 미리보기 먼저
}

private void HandleProcessConfirmed(ItemData input, RecipeData recipe)
{
    StartCoroutine(manager.CraftSystem().CraftCoroutine(recipe));
    craftUI.Close();
}
  • 새롭게 알게 된 점: UI/로직 책임을 분리하면 디버깅이 쉬워지고, UX도 분명해진다.
  • 다시 만나게 된다면: Handler에 “즉시 실행” 코드가 다시 섞이지 않도록 테스트 케이스코드 리뷰 체크리스트에 항목을 추가한다.

📝 메모

오늘은 UI와 로직의 경계를 다시 세우는 하루였다. 생각보다 작은 널 가드 하나가 전체 흐름을 막기도 한다는 걸 또 체감했다. 모르는 걸 부끄러워하지 말자. 천천히, 정확하게. 팀 회의에서 정리한 기준을 내일 커밋에도 유지하자. 끝은 언제나 정돈이다.


반응형
반응형

🗓️ 오늘 하루 일정

✅ 오전

  • 09:00 ~ 12:30 : NPC 대화/상호작용 기획 정리 (Start → Talk x4 → End 노드 플로우, 헌터/방랑자/장인 톤 가이드)

🍽️ 점심시간

  • 13:00 ~ 14:00 : 점심

✅ 오후

  • 14:00 ~ 16:00 : 유니티 배치고사
  • 16:00 ~ 16:30 : 쉬는 시간
  • 16:30 ~ 18:00 : 챌린지반 특강

🍽️ 저녁시간

  • 18:00 ~ 19:00 : 저녁

✅ 저녁

  • 19:00 ~ 21:00 : 팀 회의 (과제 리뷰 & 상호작용 시스템 통일안 논의)

✅ 오늘 학습 키워드

  • Raycast 기준점 통일(FPS/TPS), Camera.ViewportPointToRay
  • 인터랙션 포인트(interactionRayPointTransform) 설계
  • 코루틴 재시작/중단 타이밍, StopCoroutine, Invoke
  • UI 게이지 비율 계산(Image.fillAmount), 정수 나눗셈 주의
  • 피해 인터페이스 설계(IDamageable), 트리거 컬렉션 관리

✅ 오늘 학습 한 내용을 나만의 언어로 정리하기

E) 오늘 커밋 작업 정리 (UI/NPC/인벤토리)

커밋 타임라인 (Aug 19, 2025)

  • [Feat] NPC : Hunter, Vagabond, CraftMan Update, NPC UI Fix
  • [Feat] NPC Dialog UI Update
  • [Feat] Inventory UI 이미지 추가 
  • [Fix] NPC UI 수정 

무엇을 했나

  • NPC 세트 업데이트(Hunter/Vagabond/CraftMan): 대화 노드/초기 멘트 정리, 프리팹화된 NPC UI 연결 구조 점검, 기본 톤(헌터/방랑자/장인) 반영.
  • NPC Dialog UI 개선: 선택지 레이아웃 정렬(가변 길이 대응), 오토 사이즈 및 줄바꿈 규칙 정리, Talk 노드 4개 탭 구조 가독성 향상.
  • Inventory UI 이미지 추가: 아이콘 스프라이트 적용 및 슬라이스 점검, 빈 슬롯/선택 슬롯 상태 색상 대비 조정.
  • NPC UI 버그 픽스: 앵커/피벗 불일치로 발생하던 해상도별 틀어짐, Raycast Target 과다로 클릭 가로채기 이슈 수정.

🧩 학습하며 겪었던 문제점 & 에러


📝 메모

오늘은 시험과 특강, 회의까지 풀 코스였지만, 작은 디테일(좌표계, 정수/실수, 프레임 타이밍)이 전체 체감 품질을 크게 바꾼다는 걸 다시 느꼈다. 급해도 기본을 꼼꼼히 내일은 상호작용 모듈을 팀 기준으로 더 깔끔하게 모듈화하자. 할 수 있다! 💪


반응형
반응형

🗓️ 오늘 하루 일정 (2025-08-18)

✅ 오전

  • 09:00 ~ 11:30 : DOTween 기반 BaseUI 정리
    • AnimType(None/Fade/Scale/Slide*) 재구성, ease/ignoreTimeScale/slideDistance 옵션 점검
    • Scale 팝 연출 적용(열림: closed→overshoot→1, 닫힘: 1→overshoot→closed)
  • 11:30 ~ 13:00 : 인벤토리 UI 점검
    • 버튼 바인딩/비활성 초기화(UnActive) 정리, 선택 아이템 표시 플로우 확인

🍽️ 점심시간

  • 13:00 ~ 14:00 : 점심

✅ 오후

  • 14:00 ~ 16:30 : InventoryModel/InventoryMediator 최소 구성 맞춤
    • 팀원 다이어그램 기준 InventoryModel(List 기반 수량) 정리
    • InventoryMediator로 UI ↔ Model ↔ Player 흐름 단순화(선택/사용/장착/드롭)
  • 16:30 ~ 18:00 : 대화 시스템(간단 버전) 연결
    • DialogueSO(노드/선택지) → DialogueRunner → DialogueViewUI → NPCDialogue 배선
    • 트러블슈팅:
      • Start(DialogueSO) 네이밍 충돌 → **Run(DialogueSO)*로 변경
      • RectTransform 캐스팅 예외 → GetComponent<RectTransform>() + 가드
      • DialogueRunner.view == null → 인스펙터 주입/자동 탐색 추가

🍽️ 저녁시간

  • 18:00 ~ 19:00 : 저녁

✅ 저녁

  • 19:00 ~ 20:00 : TIL 작성
  • 20:00 ~ 21:00 : 팀 회의
    • 논의: 인벤토리 중재자 경량 패턴 유지, Dialogue 간단 파이프라인 확정
    • 액션아이템:
      • [ ] InventoryUI 선택지/리스트 프리팹 정리 & OnItemClicked(id) 연결
      • [ ] PlayerInventory의 CanUse/Equip 규칙 명세화
      • [ ] DialogueSO 샘플 3개 제작(튜토리얼/NPC/상점)

✅ 오늘 학습 키워드

  • DOTween, Ease(OutCubic/OutBack), CanvasGroup, ignoreTimeScale
  • RectTransform, AnchoredPosition, Scale Pop(overshoot)
  • InventoryModel(List<int> 수량), InventoryMediator(경량 중재자)
  • DialogueSO / DialogueRunner / DialogueViewUI / NPCDialogue
  • Unity 라이프사이클 충돌(Start 오버로드 금지), NRE/InvalidCastException 디버깅

✅ 오늘 학습 한 내용을 나만의 언어로 정리하기

  • UI는 BaseUI 하나로 애니/입력 상태를 표준화하고, 각 화면은 표시만 담당하면 유지보수가 편하다.
  • Scale 팝 연출은 closed → overshoot → 1(열림) / 1 → 작은 overshoot → closed(닫힘) 두 단계로 만들면 손맛이 좋다.
  • 인벤토리는 MVP까지 안 가더라도 Mediator 한 개로 UI·Model·Player를 느슨하게 연결하면 충분히 깔끔하다.
  • 대화는 고정 버튼+스크립터블 오브젝트만으로도 빠르게 돌릴 수 있다.
  • Unity 예약 메서드(Start/Update)는 시그니처 바꾸면 안 됨. 같은 이름으로 파라미터 받는 메서드 만들지 말자.

🧩 학습하며 겪었던 문제점 & 에러

1) Start() can not take parameters

  • 문제&에러에 대한 정의: DialogueRunner.Start(DialogueSO)가 Unity의 예약 Start()와 충돌.
  • 내가 한 시도: 함수명만 바꾸지 않고 호출.
  • 해결 방법: 메서드명을 **Run(DialogueSO)*로 변경하고, 모든 호출부를 runner.Run(...)으로 통일.
  • 새롭게 알게 된 점: MonoBehaviour 예약 메서드는 오버로드 불가.
  • 이 문제&에러를 다시 만나게 되었다면: 처음부터 엔트리 메서드는 Start/Update 등 예약어 피하기.

2) InvalidCastException (Transform → RectTransform)

  • 문제&에러에 대한 정의: rect = (RectTransform)transform; 강제 캐스팅 실패.
  • 내가 한 시도: 캐스팅 유지.
  • 해결 방법: GetComponent<RectTransform>()로 가져오고, 없으면 에러 로그 후 임시 추가.
  • 새롭게 알게 된 점: 에디터/런타임 환경에 따라 루트가 UI가 아닐 수 있음.
  • 이 문제&에러를 다시 만나게 되었다면: Canvas 하위 배치 체크 + null 가드를 기본으로 넣기.

3) NullReferenceException (view == null)

  • 문제&에러에 대한 정의: DialogueRunner.Run에서 view.Show() 호출 시 view 미할당.
  • 내가 한 시도: 인스펙터 할당 누락한 채 실행.
  • 해결 방법: 인스펙터 주입 또는 FindObjectOfType<DialogueViewUI>(true)로 자동 탐색 + null 가드.
  • 새롭게 알게 된 점: UI 참조는 런타임 자동 바인딩 루트를 마련하면 실수가 줄어듦.
  • 이 문제&에러를 다시 만나게 되었다면: 공용 컴포넌트에는 진입점에서 참조 검증 코드를 습관화.

📝 메모

  • BaseUI 팝업 기본값: AnimType=Scale, ease=OutCubic, ignoreTimeScale=true, scaleClosed=0.95, overshoot=0.06.
  • 인벤토리: 선택 아이템 강조, 수량 표시는 UI에서만 표현하고 데이터는 List<int>로 단순화 유지.
  • Dialogue: 버튼 3개 기준으로 프리팹 템플릿 확정해두기(라벨/TMP 배열 길이 동일).
  • 공용 체크리스트: 참조(null) → Canvas/RectTransform → Event 바인딩 → 애니 옵션 순으로 검사.

반응형
반응형

🗓️ 오늘 하루 일정

🌅 오전

  • 09:00 ~ 10:00 개인 시간
  • 10:00 ~ 10:30 게임개발 숙련 프로젝트 발제 참석
  • 10:30 ~ 팀 회의(역할/범위 정리)

🍽 점심

  • 13:00 ~ 14:00 점심

🌞 오후

  • 14:00 ~ 16:00 NPC, UI 다이어그램 작성
  • 16:00 ~ 18:00 UI 관련 강의 수강

🍽 저녁

  • 18:00 ~ 19:00 저녁

🌙 저녁 이후

  • 19:00 ~ 21:00 팀원들과 와이어프레임 리뷰

✅ 오늘 학습 키워드

  • UI 중재자 패턴
  • UI 상태 전환 구조
  • 와이어프레임 설계 및 리뷰 프로세스
  • 팀 협업 브랜치 관리

✅ 오늘 학습 한 내용을 나만의 언어로 정리하기

오늘은 프로젝트 UI와 게임 오브젝트(플레이어, 적, NPC)의 데이터 흐름을 정리하기 위해 다이어그램을 직접 작성했다.

BaseUI를 상속받는 다양한 UI 컴포넌트(ConditionUI, PlayerUI, DialogueViewUI 등)를 구조화했고,

UIMediator를 중심으로 Player, Enemy, NPC의 상태 정보를 각 UI로 전달하는 흐름을 구상했다.

또한 MPV 패턴 적용 가능성도 검토했다. View(UI)는 UI 표시와 입력 처리만 담당하고, Model(Player, Enemy, NPC, Condition 등)은 데이터 저장 및 로직을 맡는다. Presenter는 이 둘 사이에서 데이터를 변환·전달하는 역할을 한다.

오늘은 구조를 잡는 과정에서 머리가 많이 복잡했지만, 하나씩 구현해 나가면 유지보수성과 확장성이 좋아질 것이라는 확신이 들었다.


📝 메모

오늘은 단순 기능 구현이 아니라 UI 전체 구조와 데이터 흐름을 고민하는 날이었다.

머리가 복잡했지만, 중재자 패턴과 MPV 패턴을 혼합해 쓰면 우리 프로젝트의 UI 관리가 깔끔해질 것 같다.

내일부터는 PlayerConditionUI → Presenter → Player 데이터 연동부터 시도해보자.

작은 단위로 성공 사례를 만들고 확장하는 방식이 부담도 줄이고 속도도 빠를 것 같다.


반응형
반응형

🗓️ 오늘 하루 일정

✅ 오전

  • 09:00 ~ 프로젝트 스크립트 구조 점검 및 정리
  • 기존 Equip, EquipTool 삭제
  • 수정된 코드들(Move_SportCar, JumpPad, ItemObject 등) 깃허브에 업로드
  • README용 프로젝트 설명, 폴더 구조, 블로그용 글 작성 시도

🍽️ 점심시간

  • 13:00 ~ 14:00 점심시간

✅ 오후

  • 깃허브 README 형식 개선 작업 시도
  • 트러블슈팅 문서 작성 형식 논의
  • 델리게이트 / 람다 공부 계획 수립

🍽️ 저녁시간

  • 18:00 ~ 19:00 저녁시간

✅ 저녁

  • 19:00 ~ 21:00 프로젝트 구조 심화 복습
  • 델리게이트(delegate) 심화 학습 및 람다(lambda) 표현식 정리

✅ 오늘 학습 키워드

  • 델리게이트 (Delegate)
  • 람다식 (Lambda Expressions)
  • Unity 프로젝트 구조 설계
  • GitHub README 작성 및 개선

✅ 오늘 학습 한 내용을 나만의 언어로 정리하기

 

Unity - Project_Up

🎮 Project_Up – Unity 3D 서바이벌 시스템 제작기안녕하세요! 오늘은 제가 진행한 Unity 프로젝트 Project_Up을 소개하려고 합니다.이 프로젝트는 3D 환경에서 플레이어가 이동하고, 오브젝트와 상호작

dev-jen.tistory.com

  • 델리게이트
    • 델리게이트는 메서드 참조를 변수처럼 저장하고 호출할 수 있는 타입이다.
    • 주로 이벤트 시스템 구현에 활용되며, 메서드 시그니처(매개변수, 반환값)가 동일해야 한다.
    • delegate 키워드로 선언하고, 인스턴스를 생성해 등록한 뒤 호출할 수 있다.
  • 람다식
    • 익명 메서드를 간단히 표현하는 문법.
    • (매개변수) => { 실행문 } 형식 사용.
    • 델리게이트나 LINQ에서 코드 가독성을 높여준다.
  • 프로젝트 구조
    • 불필요한 기능은 제거하고, 필요한 스크립트만 남겨 깔끔하게 유지해야 유지보수가 쉽다.
    • 각 기능별로 폴더를 구분하고, 네이밍 규칙을 통일해야 팀원이 봐도 이해가 빠르다.
  • README 작성
    • 프로젝트 목적, 기능, 설치 방법, 스크린샷(GIF) 등을 포함해 가독성을 높여야 한다.
    • 트러블슈팅과 폴더 구조를 포함하면 협업 시 이해가 빠르다.

📝 메모

오늘은 델리게이트와 람다 개념을 다시 정리하면서, 프로젝트 구조 관리의 중요성을 느꼈다.

특히 깃허브 문서화에서 통일된 형식을 유지하는 것이 협업과 유지보수에 정말 중요하다는 걸 다시 한 번 깨달았다.

앞으로는 문서와 코드 모두 깔끔하고 읽기 쉬운 구조 를 목표로 해야겠다.


반응형

Unity - Project_Up

Dev_Jen
|2025. 8. 13. 10:31
반응형

🎮 Project_Up – Unity 3D 서바이벌 시스템 제작기

안녕하세요! 오늘은 제가 진행한 Unity 프로젝트 Project_Up을 소개하려고 합니다.
이 프로젝트는 3D 환경에서 플레이어가 이동하고, 오브젝트와 상호작용하며, 자원을 채집하고 아이템을 사용하는 기본적인 서바이벌형 시스템을 구현한 예제입니다.

최근에는 장비(Equip) 시스템을 완전히 제거하고, 소비형 아이템 중심의 단순한 인벤토리 구조로 리팩토링을 진행했어요.
덕분에 전체 구조가 훨씬 가볍고 직관적으로 변했습니다.


📌 프로젝트 개요

  • 장르 : 3D 서바이벌 / 인터랙션
  • 엔진 : Unity 2021.3 LTS
  • 개발 언어 : C#
  • 주요 목표
    1. 캐릭터 이동, 점프, 달리기, 카메라 제어
    2. 상호작용 가능한 오브젝트와의 간단한 인터페이스
    3. 소비형 아이템 중심의 인벤토리 시스템
    4. 환경 오브젝트(점프패드, 이동하는 차량) 구현

🛠 주요 기능

1. 플레이어 시스템

  • 이동/점프/달리기
    기본 WASD 이동과 점프, Shift를 통한 달리기 기능을 구현했습니다.
    카메라는 3인칭 시점이며, 벽이나 오브젝트에 부딪히면 자동으로 충돌 보정이 됩니다.
  • 스태미나 관리
    달릴 때 스태미나가 소모되며, 스태미나가 0이 되면 더 이상 달릴 수 없습니다.
  • 상태(Condition) 관리
    체력, 스태미나, 속도 증가(버프) 상태를 관리하고, UI와 실시간 연동됩니다.
  • 애니메이션 연동
    이동 속도, 점프 여부, 낙하 여부에 따라 애니메이션 파라미터를 업데이트합니다.

2. 아이템 & 인벤토리

  • 아이템 타입
    • Consumable : 체력 회복, 스태미나 회복, 속도 증가 등 사용 시 효과 적용
    • Environment : 환경 오브젝트(자원, 오브젝트 배치용)
  • 인벤토리 UI
    • 슬롯 기반 UI로 구성
    • 같은 종류의 아이템은 스택 가능
    • 아이템 사용 시 해당 효과 즉시 적용
    • 인벤토리가 가득 차면 아이템을 버림
  • 아이템 상호작용
    월드에 떨어진 ItemObject와 상호작용하면 인벤토리에 추가됩니다.

3. 상호작용 시스템

  • 화면 중앙에서 Raycast를 발사해 상호작용 가능한 오브젝트를 탐지합니다.
  • 감지 시 상호작용 안내 UI(TextMeshPro) 표시.
  • E 키 입력 시 IInteractable 인터페이스의 OnInteract() 호출.

4. 환경 오브젝트

  • JumpPad
    플레이어가 올라서면 위로 점프시키고, 애니메이션이 재생됩니다.
  • Move_SportCar
    DoTween을 사용해 차량이 앞뒤로 왕복하거나 원형 궤도를 도는 움직임을 구현했습니다.
    이동 방향에 따라 휠이 회전하는 디테일까지 넣었습니다.
  • Resource
    채집 시 아이템 드롭 프리팹을 생성하며, 정해진 수량만큼만 채집 가능합니다.

5. UI & 시각 효과

  • UICondition : 체력, 스태미나, 버프 상태 표시.
  • DamageIndicator : 피해를 받으면 화면이 붉게 플래시됩니다.
  • FootSteps : 이동 속도에 따라 발자국 소리가 재생됩니다.

🆕 최근 리팩토링 포인트

이번 업데이트에서 특히 큰 변화는 장비 시스템 제거입니다.

  • 불필요하게 복잡했던 장착/해제 로직과 Equip 클래스 삭제
  • 인벤토리에서 장착/해제 버튼 제거
  • ItemType에서 Equipable 제거
  • 아이템은 Consumable 또는 Environment만 존재
  • Player 클래스에서 equip 필드 삭제

이렇게 하니 코드가 훨씬 단순해지고, 아이템 관리와 UI 동작이 명확해졌습니다.


📂 폴더 구조

Assets/
├── 02.Scripts/
│   ├── Character/
│   │   ├── CharacterManager.cs
│   │   ├── Player.cs
│   │   ├── PlayerController.cs
│   │   ├── PlayerCondition.cs
│   │   ├── PlayerAnimation.cs
│   │
│   ├── Interaction/
│   │   ├── Interaction.cs
│   │   ├── ItemObject.cs
│   │   ├── Resource.cs
│   │
│   ├── Inventory/
│   │   ├── ItemData.cs
│   │   ├── ItemSlot.cs
│   │   ├── UIInventory.cs
│   │
│   ├── UI/
│   │   ├── Condition.cs
│   │   ├── UICondition.cs
│   │   ├── DamageIndicator.cs
│   │
│   ├── Environment/
│   │   ├── JumpPad.cs
│   │   ├── Move_SportCar.cs
│   │
│   └── Sound/
│       └── FootSteps.cs

🎥 플레이 화면 (GIF)


💡 마무리

이번 프로젝트는 기본적인 서바이벌형 시스템의 뼈대를 구현하는 것이 목표였습니다.
장비 시스템을 제거하고 나니 인벤토리와 아이템 구조가 훨씬 명확해지고 유지보수가 쉬워졌어요.
다음에 추가하고싶은건 전투 시스템퀘스트 시스템을 간단하게 붙여서,
더 풍부한 플레이 경험을 줄 수 있도록 확장하고싶습니다!

반응형
반응형

🗓️ 오늘 하루 일정

✅ 오전

  • 09:00 ~ 11:00 : 점프 애니메이션 추가 (OnTriggerEnter에 JumpTrigger 트리거 연동, AddForce로 물리 튕김 적용)
  • 11:00 ~ 13:00 : 맵 제작 진행 (지형 구성, 오브젝트 배치 일부)

🍽️ 점심시간

  • 13:00 ~ 14:00 : 점심시간

✅ 오후

  • 14:00 ~ 16:00 : 맵 배치 마무리 작업
  • 16:00 ~ 18:00 : 챌린지반 강의 수강 (주제: 델리게이트)
  • 18:00 ~ 19:00 : 자유시간 및 휴식

🍽️ 저녁시간

  • 19:00 ~ 20:00 : 맵 최종 점검 및 세부 수정
  • 20:00 ~ 21:00 : 맵 제작 완성, 마무리 테스트

✅ 오늘 학습 키워드

  • Unity OnTriggerEnter 활용
  • Rigidbody 물리 처리 (AddForce, y속도 초기화)
  • Animator Trigger 파라미터 활용 (SetTrigger)
  • 맵 제작 및 오브젝트 배치
  • C# 델리게이트(Delegate) 개념 및 활용

✅ 오늘 학습 한 내용을 나만의 언어로 정리하기

오늘 오전에는 OnTriggerEnter를 이용해 플레이어가 특정 트리거 존에 닿았을 때 점프 애니메이션과 물리적인 튕김 효과가 동시에 적용되도록 구현했다.

Rigidbody의 y속도를 0으로 초기화해 낙하 중에도 깔끔하게 위로 튀어 오를 수 있도록 처리했고, anim.SetTrigger("JumpTrigger")를 사용해 애니메이션을 재생하도록 했다. 물리 처리는 AddForce(Vector3.up * jumpForce, forceMode)로 구현하여 위쪽으로 힘을 가했다.

오후에는 맵 제작을 이어서 진행했다. 지형과 오브젝트를 배치하고, 동선과 분위기를 고려한 레이아웃을 구성했다. 배치 작업은 생각보다 시간이 오래 걸렸지만, 어느 정도 완성도를 갖춘 상태로 마무리할 수 있었다.

또한 챌린지반 강의에서 C# 델리게이트에 대해 학습했다. 델리게이트가 메서드를 변수처럼 다룰 수 있게 해주는 타입이라는 점, 그리고 멀티캐스트, 익명 메서드, 람다식, 이벤트와의 관계까지 배우면서 이벤트 처리나 콜백 구조를 만들 때 얼마나 유용한지 이해할 수 있었다.


🧩 학습하며 겪었던 문제점 & 에러

1) 점프 애니메이션과 물리 힘 적용 타이밍

  • 문제정의
  • 트리거 존에 닿았을 때 점프 애니메이션은 실행되지만, 물리적으로 위로 튀는 타이밍이 애니메이션과 완전히 맞지 않아 시각적으로 어색했다.
  • 시도
  • 단순히 OnTriggerEnter에서 SetTrigger와 AddForce를 동시에 호출하여 처리했다.
  • 해결방법이후에는 Animation Event를 이용하면 타이밍을 더 정확히 맞출 수 있다는 점을 메모해 두었다.
  • 우선 애니메이션 트리거는 그대로 유지하되, 물리 힘은 y속도를 초기화한 후 즉시 적용하여 낙하 중에도 부드럽게 튀어 오르게 했다.
  • 예시 코드
private void OnTriggerEnter(Collider other)
{
    if (!string.IsNullOrEmpty(targetTag) && !other.CompareTag(targetTag)) return;

    Rigidbody rb = other.attachedRigidbody;
    if (rb != null)
    {
        if (resetVerticalVelocity)
        {
            Vector3 v = rb.velocity;
            v.y = 0f;
            rb.velocity = v;
        }

        anim.SetTrigger("JumpTrigger"); // 애니메이션 재생
        rb.AddForce(Vector3.up * jumpForce, forceMode); // 물리 힘 적용
    }
}
  • 새롭게 알게 된 점
  • 애니메이션과 물리 동작을 정확히 동기화하려면 Animator의 트리거만 사용하는 것이 아니라 애니메이션 이벤트코루틴 지연 실행으로 타이밍을 조절하는 것이 좋다.
  • 다시 만나게 된다면
  • 다음번에는 애니메이션 클립에 이벤트를 추가해, 특정 프레임에서만 힘을 적용하도록 구현할 것이다.

📝 메모

오늘은 오전에 점프 애니메이션과 물리 튕김 처리를 구현하고, 오후에는 맵 배치를 마무리했다. 사실 맵 제작은 하다 보면 끝이 없는데, 오늘은 적당한 선에서 마무리하기로 결정했다. 완벽하게 만들려고 욕심내기보다 지금 상태에서 충분히 플레이가 가능한 수준이라면 더 이상 붙잡지 않는 게 오히려 효율적이라는 걸 느꼈다.

델리게이트 강의를 들으면서, 메서드를 변수처럼 다루고 콜백 구조를 쉽게 만들 수 있다는 점이 인상 깊었다. 앞으로 이벤트나 UI 버튼 클릭 처리, 플레이어 상태 변화 알림 등 다양한 곳에 적용할 수 있을 것 같아 기대된다.

내일은 오늘 만든 맵에서 직접 플레이 테스트를 하면서, 필요한 최소한의 수정만 하고 다른 기능 구현에 들어가야겠다.


반응형