Why?나는 Perception자극을 Squad단위로 전파하길 원한다.이는 Team단위에서 더 쪼개진 단위로, 각 Actor 무리들은 Squad ID를 가진다.이때, 이 Squad를 Spawn하는 단계에서 문제점이 발생했다.NewActor->SpawnCollisionHandlingMethod = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;이런 방식으로 Spawn을 할 때, Z값에 대해서도 Adjust가 적용되어, Actor위에 Actor가 올라타있는 경우가 생기고, 만약 Step On을 허용하지 않는다면, Spawn단계에서 팅겨져 나가는 경우가 발생한다.따라서 나는 지정된 위치에서 XY방향으로 고르게 퍼져나가며 Spawn하..
When?인공지능의 행동 양식을 구현할 때 사용한다. Why?간단한 행동양식인 경우에는 각 FSM과 같이 State를 이동하며, 행동양식을 만들 수 있다.하지만 복잡한 행동양식인 경우에 State가 많아질수록 기하급수적으로 복잡해진다는 단점이 있다.이를 해결하기 위해, Tree형태로 행동양식을 결정하는 Behavior Tree가 등장했고, 유지보수에 강한 장점이 있다. How?AIController 내부에는 BrainComponent와 BlackBoardComponent가 준비되어 있다.BrainComponent는 BehaviorTree의 부모로, RunBehaviroTree() 에서 BTComp와 BBComp가 NewObject를 통해 만들어진다.두 Component의 내부에는 당연히도 BT와 BB..
When?인공지능을 통해 Actor가 목표 지점으로 길찾기를 할 때 쓰인다. Why?Actor가 목표 지점으로의 길을 찾아야 할 때, 어떤 길, 어떤 경사로 등 다양한 조건들을 체크할 수 있어야 한다.Actor의 높이나, 넓이에 따라 선택적으로 길을 찾을 수 있어야 하며, 지형 정보에 따라 선호하는 길을 찾을 수 도 있어야 한다.이런 것을 NavMesh를 통해 구현할 수 있으며, 이는 Detour & Recast Library를 Unreal에 통합하여 Engine에서 지원하는 것으로 보인다. How?1. NavMesh Bounds Volume먼저 어떤 길에 NavMesh를 생성하려면 어디서부터 어디까지 생성할지 범위에 대한 지정이 필요하다.그것을 NavMesh Bounds Volume을 통해 지정할 ..
Why?나는 항상 좋은 구조에 대한 의구심을 품어왔다.내가 이전에 진행하다 갈아엎은 프로젝트들은 Component사이의 종속성이 생기고, Character가 할 수 있는 행동들은 많은 클래스들에 퍼져있었다.이렇게 되면 컴포넌트들을 재사용할 수 없는 것은 물론, 갈수록 가독성이 떨어지고 복잡성이 증가해 유지보수가 힘들어진다.이런 상황속에서 나는 Component들이 API만을 제공할 때, 그 API를 조합하여 행동을 정의할 수 있는 Ability를 떠올렸다.이전에 GAS를 공부하며, 사용해 봤을 때, Ability 하나를 정의하기 위해 수 많은 코드를 작성해야 하는 어려움과, 워낙에 방대한 프레임워크이기 때문에 내가 제대로 알고 있음을 알 수 없는 어려움이 있었기에 나는 이를 경량화하여, 내가 완전히 이해..
When?Animation Graph에서의 작업의 효율성과 프레임워크를 부여할 때 사용한다. Why?Shooter Game에서 Pistol, Rifle, Unarmed 등 다양한 상태가 존재하고, 이들 하나하나에 대한 분기를 Editor상에서 작성하다보면, 점점 더러워질 뿐더러, 어디서 뭐가 어떻게 작동하는지 파악하기 힘들다.더불어, 새로 추가되는 상태가 있다면 그에 대해 어떤 작업을 해줘야 하는지 기억하기 어렵고, 빼먹기 쉽다.Linked Animation Layer를 이용하여, 위의 문제점들을 해결할 수 있다. How?1. Animation Layer Interface를 만들어준다.어떠한 행동, 기능을 설명하는 Layer를 정의한다.여기서 외부에서 받은 Input Pose, Variable들을 정..
When?어떤 기능이 한 클래스의 상속 구조에 적합하지 않고, 같은 부모를 가지지 않는 여러 클래스들이 가질 수 있는 기능이어야 할 때, 쓰인다. Why?Interact라는 기능을 생각해보자.Actor 돌맹이도 Interact할 수 있고, Character NPC와도 Interact할 수 있다.만약 상속구조에 이 기능을 넣게 된다면, 중복해서 같은 기능을 가지는 Code를 추가해야 할 것이다. How?Basicclass UBN_LevelChangeable : public UInterface{ GENERATED_BODY()};class PROJECTBN_API IBN_LevelChangeable{ GENERATED_BODY()public: UFUNCTION(BlueprintCallable, Bluepr..
구현 목표비동기 레벨 로딩Transition Map When?Level을 바꿀 때 사용한다. Why?Level을 바꾸는 정보를 가진 주체는 여러가지 일 수 있다.예를 들어, 버튼이 될 수도 있고, 어떤 포탈 혹은 UObject의 로직이 될 수도 있다.따라서 다양한 경우에 대응할 수 있어야 한다. How?Interface를 상속받은 객체는 레벨 전환에 사용할 구조체를 반환하는 함수를 구현한다.USTRUCT(BlueprintType)struct FBN_LevelInfo{ GENERATED_BODY() UPROPERTY(EditDefaultsOnly, meta = (AllowedTypes = "Map")) FPrimaryAssetId TargetMapID; UPROPERTY(EditDefaultsOnly,..