🎮 [개발 일지] 2025년 12월 14일
🧱 오늘의 작업 요약CAnimNotify_Dodge노티파이의 시작과 끝을 구분해두고 회피시 이동 제어, 회피 판정과 타이밍 제어에 사용마찬가지로 노티파이의 시작과 끝에 회피 판정을 위한 GE_Dodge 클래스를 활성화 및 비활성화GE_Dodge게임플레이 이펙트 클래스를 상속받아 만든 클래스, 내부에 해당 이펙트가 활성화 되면 특정 이펙트 태그 호출로 적용되는 게임플레이 이펙트를 면역 할 수 있기에 Effect.Damage 태그를 면역으로 설정하여 회피시 무적 판정으로 이용또한, 지속시간을 무제한을 주어서 노티파이에서 시작과 끝을 조절할 수 있도록 설정⚙️ 트러블슈팅 / 현재 고민 중인 사항GA_Dodge 회피시 캐릭터의 이동 제어캐릭터의 키 입력을 막고 속도를 제어하여 이동을 제어완료GA_Dodge 회..
🎮 [개발 일지] 2025년 12월 13일
🧱 오늘의 작업 요약GA_DodgeUAbilityTask_WaitGameplayEvent를 사용해 캐릭터를 자연스럽게 방향에 맞추어서 밀어냄어빌리티의 활성화시 캐릭터의 속도 초기화와 이동 제어를 off하며 회피 모션이 온전히 나올 수 있도록 구현CAnimNotify_Dodge노티파이의 시작과 끝을 구분해두고 회피시 이동 제어, 회피 판정과 타이밍 제어에 사용⚙️ 트러블슈팅 / 현재 고민 중인 사항GA_Dodge 회피시 캐릭터의 이동 제어캐릭터의 키 입력을 막고 속도를 제어하여 이동을 제어완료GA_Dodge 회피시 캐릭터의 무적 및 버프 기능Effect 클래스 추가로 구현 예정진행중💡 해결 방안 / 시도 중인 솔루션캐릭터가 회피 할 경우 루트 모션이 아닌 애니메이션을 사용중이기에 왼쪽으로 회피를 하다 ..
🎮 [개발 일지] 2025년 12월 12일
🧱 오늘의 작업 요약GA_Guard태그를 통한 어빌리티 활성화로 기존 데미지 처리 연산 식에서 가드 태그가 존재시 데미지 연산 수치를 조정하여 가드 판정을 구현, 연출 효과는 아직 미정몽타주를 섹션별로 나누어 가드 시작 - 루프 - 종료 와 가드 히트시 애니메이션 까지 하나의 몽타주에서 관리GA_ParryGA_Guard 활성화 시 플레이 되는 몽타주에 패링 태그가 부여되는 구간에 데미지가 들어오면 패링으로 처리이벤트 방식으로 활성화 되며, Guard보다 앞서 조건문 판별을 하여 패링 성공시 가드가 아닌 패링으로 빠지게 됨패링을 위한 글로벌 슬로우 노티파이 구현GA_Dodge무기 장착전에는 달리기, 무기 장착시에는 회피로 동작하는 Shift 키에 기능을 바인딩In-Place 애니메이션을 사용하여 캐릭터 ..
UML Diagram & FlowChart(작성중)
Character GroupAActor를 상속받는 캐릭터와 관련된 클래스들의 집합UCCharacterProfile : 각 캐릭터가 사용하는 전투 애니메이션 및 공통 애니메이션ACPlayer : 플레이어블 캐릭터ACPlayer_MorganaACPlayer_CelesteACPlayer_MannequinACEnemy : 적 캐릭터ACEnemy_AI : AI가 활성화(포함)된 적 캐릭터ACBoss : 적 보스 캐릭터ACBoss_CyberNinjaACCompanion : 플레이어의 동료 캐릭터Component Group커스텀 및 언리얼 엔진의 기존 컴포넌트를 상속받아 구현한 클래스들의 집합CAbilityManagerComponent : 어빌리티 등록과 키 입력에 따른 어빌리티 활성화 CAIBehaviorCompo..
🎮 [개발 일지] 2025년 10월 28일
🧱 오늘의 작업 요약DamageHandler 리펙토링기존 Data값을 받아와서 적용시키던 데미지 처리를 GAS를 통해서 처리하도록 변경무기에 존재하는 액션 노드에 `FActionCombatData` 구조체를 생성하여서 해당 액션에 대한 수치 값들을 관리하도록 등록함각 무기의 액션 노드 마다 베이스 데미지, 데미지 배율, 크리티컬 배율, 확률이나 그로기 수치값과 같은 부분을 각각 따로 설정할 수 있도록 하였음해당 데이터 값들에게 `ApplyDataToSpec(...)` 함수를 통해서 FGameplayEffectSpec을 생성시에 각 값에 태그들을 부착함GECalc_Damage 구현실제로 데미지를 연산하는 클래스를 구현FGameplayEffect 클래스인 GE_Damage는 해당 이펙트가 " 어떠한 연산을..
🎮 [개발 일지] 2025년 10월 21일
🧱 오늘의 작업 요약WeaponDriver 리펙토링WeaponDriver의 OnPressed() 함수 리펙토링기존의 Enum과 Enum으로 매핑하던 구조를 1개의 열거형으로 변경애니메이션 정리 시작, 캐릭터, 적군, 보스 애니메이션 폴더정리⚙️ 트러블슈팅 / 현재 고민 중인 사항GAS 시스템 연계성기존 Combat/State 구조와 GAS 간의 책임 분리 확인 중⚖️ 구조 점검 중GAS 유효성 검증Attribute, Effect, Cue 사이의 흐름 검증 필요✅ 일부 테스트 완료💡 해결 방안 / 시도 중인 솔루션GAS 핵심 로직(Effect → Attribute → Cue) 흐름을 CombatComponent에 병합 테스트GameplayCue 실행 시 Camera/FX 연출 자동화 구조 추가 예정🚧..
Snell`s Lawn
Snee`s Law (스넬의 법칙)스넬의 법칙은 빛이 한 매질에서 다른 매질로 진행할 때 경계면에서 굴절되는 각도를 나타내는 법칙입니다. 예를 들어, 공기 중에서 물속으로 들어가는 빛은 속도가 달리지기 때문에 진행 방향이 바뀌게 되는데, 이때 입사각과 굴절각 사이의 관계를 수학적으로 나타낸것이 바로 스넬의 법칙입니다. 수학적 표현$$n_1 \sin\theta_1 = n_2 \sin\theta_2$$ $n_1$: 첫 번째 매질의 굴절률$n_2$: 두 번째 매질의 굴절률$\theta_1$: 입사각 (법선과 입사광선 사이 각도)$\theta_2$: 굴절각 (법선과 굴절광선 사이 각도)물리적 의미스넬의 법칙은 사실 파동의 위상 연속성에서 유도 됩니다.빛이 경계면을 지날 때, 경계선 위에서 파동의 위상(phas..
UFUNCTION()선언과 액터의 삭제 및 컴포넌트 간단 예제
이번 포스트에서는 UFUNCTION 사용부터 커스텀 컴포넌트 제작, 델리게이트 처리까지 C++ 기반의 언리얼 개발에서 꼭 알아야 할 핵심 기능들을 하나씩 정리해보려 합니다.1. UFUNCTION과 이벤트 함수 정의UFUNCTION() 매크로는 블루프린트와 연동할 수 있는 함수를 정의할 때 사용해요. 특히 BlueprintCallable, BlueprintImplementableEvent, Server, Client 등의 옵션으로 네트워크나 블루프린트 이벤트에 연결 가능합니다.UFUNCTION(BlueprintCallable, Category="Test")void MyCustomFunction();2. Destroy와 Timer로 액터 삭제 처리GetWorld()->GetTimerManager().SetT..
C++ 디버깅과 프로파일링
중단점(BreakPoint)를 활용하면 C++ 프로그램의 실행을 잠시 멈추곡 프로그램의 동작 상태나 변수에 입력된 값들에 대해 분석할 수가 있고 단계별로 코드를 실행하면서 변수의 변화를 추적할 수도 있습니다. 비주얼 스튜디어에서는 중단점을 걸고 싶은 라인에서 F9를 누르거나 코드 라인 왼쪽 코드 줄 표시가 된 여백을 클릭하면 됩니다. 중단점VS(Visual Studio) 에서는 위의 설명한 일반적인 중단점 말고도 조건부로 중단점을 설정할 수가 있습니다. 예를 들자면 for 문과 같은 반복문을 돌릴때 특정 조건이 맞았을 경우에만 값을 확인하고 싶다면 조건부 중단점을 사용하면 됩니다. 중단점을 우클락하여서 조건을 걸 수가 있습니다.디버거(debugger)는 변수 상태를 포함해 실행 중인 코드의 모든 정보를 ..
알고리즘의 정의 및 5가지의 필요조건
알고리즘은 문제를 해결하기 위한 일련의 절차나 방법을 체계적으로 나열한 것입니다. 컴퓨터 프로그래밍에서 알고리즘은 특정 작업을 수행하거나 문제를 해결하기 위해 컴퓨터에게 지시하는 단계별 명령의 집합이라고 하는데 왜냐하면 알고리즘은 프로그램의 효율성, 성능, 문제 해결 능력을 결정짓는 요소이기 때문입니다. 따라서 알고리즘은 문제를 해결하기 위해 명확하고 유하한 순서의 단계들의 집합이라고 볼 수 있습니다. 쉽게 말해, 입력 - 처리 - 출력의 과정이 잘 정의된 문제 해결 방법 입니다.알고리즘의 5가지 필요조건일반적으로 좋은 알고리즘이 갖춰야 할 필수 요소는 다음과 같습니다.첫번째로는 입력(Input) 이며 알고리즘은 0개 이상의 외부로부터 제공되는 데이터를 가져야 합니다. 그 다음은 출력(Output)으로..
DirectX - 투영 변환을 행렬로 표현
여러 가지의 서로 다른 행렬을 일일히 찾는것은 어려우니 일관성을 위해서 투영 변환을 하나의 행렬로 표현하는 것이 좋습니다. 그러나 NDC를 변환하는 식 같은 경우 비선형이므로 행렬 표현이 존재하지 않습니다. 다행히 이 문제를 피해가는 방법이 있는데 바로, 공식을 선형인 부분과 비선형인 부분을 분리하는 것입니다.공식에서 비선형인 부분은 $z$로 나뉘는 연산입니다. 이 $z$ 좌표를 정규화를 하는 것입니다. 그러나 나중에 나누기를 수행할 때에는 원래의 $z$ 좌표가 필요하므로, 투영 변환 전에 원래의 입력 $z$ 좌표를 저장을 해두어야 합니다. 다행히 동차 좌표에는 남는 자리가 하나 있습니다. 즉, $z$좌표를 $w$좌표에 복사해 두는 것입니다. 행렬 곱셈의 관점에서 이는 3행 4열 성분을 0으로 설정하는..
DirectX - 정규화된 장치 좌표(NDC)
앞 절에서는 투영된 점의 좌표를 시야 공간에서 계산했습니다. 시야 공간에서는 투영 창의 높이가 $2$이고 너비가 $2r$로 표기하는데 여기서 $r$의 의미는 종횡비를 의미합니다. 이 방식의 문제점은 투영 창의 크기가 종횡비에 의존하게 됩니다. 하드웨어가 투영 창의 크기가 관여하는 연산( 투영 창을 후면 버퍼로 변경하는 등)을 수행할 수 있으려면 하드웨어에게 종횡비를 알려 주어야 함을 뜻합니다. 만일 종횡비에 대한 이러한 의존성을 없앨 수 있다면 작업이 조금 더 수월해 질것입니다.해당 문제에 대한 해법은 투영된 점 $x$ 좌표성분을 다음과 같이 $[-r, r]$ 구건에서 $[-1,1]$로 비례시키는 것입니다.$$-r \le x' \le r$$$$-1 \le \dfrac{x'}{r} \le 1$$이러한 변환..
메모리 관리
C에서 메모리에 대한 할당과 해제의 기본적인 방법은 `malloc()` 과 `free()`가 있습니다. 이 함수들은 C++에서도 여전히 유효하게 사용이 가능하며 프로그램이 필요로 하는 메모리를 시스템 메모리에 할당하여, 이 영역은 다른 프로그램에서 접근하거나 사용할 수 없는 공간이 됩니다. C++에서는 이러한 메모리 할당 `New`와 `Delete`을 주로 사용합니다. 하지만 해당 명령어들은 언리얼 엔진에서 관리되지 않고 언리얼 엔진만의 메모리 할당과 해제에 대한 명령어가 따로 정의되어 있습니다.관리되지 않는 메모리 `malloc()`, `free()``malloc()`과 `free()`의 특징으로는 다음과 같습니다.`malloc(size)` size 바이트 크기만큼 연속된 메모리 블록을 할당`free..
UENUM 지정자
`UENUM()` 은 C++에서 `enum class` 를 직렬화 하기 위한 매크로 입니다. 선언하는 방식은 아래와 같습니다.UENUM()enum class ESample : uint32{ A = 0, B, C ,D}`UENUM` 은 다른 `UCLASS`와 `USTRUCT`와 다르게 안에 `GENERATE_BODY`를 선언할 필요가 없습니다. 하지만 다른 지정자와 같이 메타데이터 지정자를 사용할 수 있습니다.`UENUM` 메타데이터 지정자`Bitflags`이 열거형 타입이 `Bitmask` 메타데이터 지정자로 설정된 인티저 `UPROPERTY` 변수에 의해 플래그로 사용 될 수 있습니다.`Experimental`이 타입의 라벨을 실험단계 및 미지원으로 지정합니다.`ToolTip = "Hand-writte..
USTRUCT 지정자
구조체는 멤버 프로퍼티를 체계화 및 조작할 수 있는 데이터 구조체입니다. 구조체 USTRUCT는 UPROPERTY를 지원하지만 가비지 컬렉션 시스템에 의해 관리되지 않으며 UFUNCTION 함수를 사용할 수 없습니다. 구조체를 USTURCT로 만들기 위해서는 간단하게 아래와 같은 단계를 따라가면 됩니다.C++ 구조체 정의 위에 `USTRUCT` 매크로를 배치정의의 첫 번째 줄에 `GENERATED_BODY()` 매크로를 포함합니다.USTRUCT()struct FSampleStruct{ GENERATED_BODY()}`USTURCT` 지정자구조체 지정자는 구조체가 엔진 및 에디터의 다양한 측면에서 작동하는 방식을 제어하는 메타 데이터를 제공합니다.`Atomic` 이 구조체는 항상 하나만 직렬화되어야 합니다..
UCLASS 지정자
언리얼에서 새로운 C++ Class를 생성하게 되면 클래스의 상단 부분에 대부분 자동으로 들어가는 키워드가 있습니다 `UCLASS`는 언리얼 엔진의 객체 관리 시스템에서 클래스를 인식하고 관리 할 수 있도록 해주는 매크로 입니다. 언리얼의 `UObejct`기반 클래스에 반드시 붙여야 하며, 이 매크로가 붙은 클래스만 블루프린트, GC, 에디터에서의 노출 등이 가능합니다.즉 `UCLASS` 매크로는 언리얼의 리플렉션(Reflection) 시스템을 통해 클래스와 오브젝트를 관리 할 수 있게 해주는 일종의 표식이라고 볼 수 있습니다. UCLASS의 주요 역할블루프린트 생성 가능`UCLASS`의 지정자중 하나인 `Blueprintable` 옵션이 있으면 에디터에서 이 클래스를 블루프린트로 생성이 가능리플렉션 지..
DirectX - 절두체
시야 공간에서 투영의 중심을 원점에 두고 양의 $z$축을 바라보는 시야 절두체를 네 가지 수량을 이용해서 정의할 수 있습니다. 4 가지 수량이란 원점과 가까운 평면 사이의 거리 $n$, 먼 평면 사이의 거리 $f$, 수직 시야각 $a$, 종횡비 $r$입니다.시야 공간에서 가까운 평면과 먼 평면은 $xy$ 평면과 평행입니다. 따라서 원점과 그 평면들 사이의 거리는 그냥 $z$축 상의 거리일 뿐입니다. 종횡비(aspect ratio)는 $r = w/h$로 정의 되는데 여기서 $w$는 투영 창의 너비이고 $h$는 투영 창의 높이 입니다. 투영 창은 시야 공간 안의 화면의 2차원 이미지이고 이 이미지가 결국에는 후면 버퍼로 사용되므로, 투영 창의 너비와 높이의 비율을 후면 버퍼의 너비와 높이의 비율과 같게 만들..
Smart Pointer(스마트 포인터)
언리얼 엔진에서 Smart Pointer(스마트 포인터) 는 메모리 할당과 추적의 편리함을 주도록 설계된 C++ 스마트 포인터들의 커스텀 구현입니다. 스마트 포인터에는 Shared Pointers(쉐어드 포인터), Weak Pointers(위크 포인터) 그리고 Unique Pointers(유니크 포인터)가 포함되어 있습니다.스마트 포인터 타입스마트 포인터들은 갖고 있거나 참조하는 오브젝트의 생명 주기에 영향을 줄 수 있으며, 다른 스마트 포인터마다 오브젝트에 주는 제한사항과 효과도 달라집니다.Shared Pointers (`TSharedPtr`)쉐어드 포인터는 참조하는 오브젝트를 소유하며, 무기한으로 오브젝트의 소멸을 방지하고, 참조하는 쉐어드 포인터 또는 쉐어드 래퍼런스가 없을 경우에 오브젝트를 소멸시..
DirectX - 시야 공간
최종적으로 화면에 표시되는 것은 화면의 2차원 이미지이다. 그 이미지를 만들기 위해서는 화면에 가상의 카메라를 배치해야 합니다. 그 카메라는 월드에서 관찰자가 볼 수 있는 영역, 즉 월드에서 2차원 이미지를 생성해야하는 영역을 결정합니다. 그러한 카메라에 아래 그림과 같이 로컬 좌표계를 부여한다고 할때 이 좌표계가 바로 시야 공간 (View Space)으로, 시점 공간(eye space) 또는 카메라 공간 (camera space)이라고 부르기도 합니다.카메라는 이 공간의 원점에 놓여서 양의 $z$축을 바라봅니다. $x$축은 카메라의 오른쪽 방향이고 $y$축은 카메라의 위쪽 방향입니다. 렌더링 파이프라인의 후반부 단계들에서는 화면의 정점들을 세계 공간이 아니라 이 시야 공간을 기준으로 서술하는 것이 편한..
DirectX - 지역 공간과 세계 공간
지역 공간(Local Space)와 세계 공간(World Space)DirectX에서 공간을 나누어서 작업을 하는데 크게 두 가지 지역 공간(local space, 국소 공간)과 세계 공간(world space)로 나뉘어 집니다. 지역 공간은 물체 자체의 위치나 회전량을 가지고 있으며 세계 공간은 렌더링된 세계의 특정한 지점을 기준으로 위치 좌표나 회전값을 계산하는 방식입니다. 좀 더 구체적으로는, 전역 공간 좌표계를 기준으로 한 국소 공간 좌표계의 원점과 축들의 위치 및 방향을 지정하고, 그에 해당하는 좌표 변경 변환을 수행해야 합니다. 지역 좌표계 기준의 좌표를 월드 좌표계로 변경하는 과정을 세계 변환(World Transform)이라고 부르고, 해당 변환 행렬을 세계 행렬(World Matrix)라..