본문 바로가기

자연스러운 무기 교체 (2) 서론 애니메이션 블렌딩을 통해 애니메이션은 해결되었다. 이제 남은 것은 메시를 자연스럽게 만드는 것이다. 그러면 이제 메시를 보간하는 코드를 어디에 작성하는지를 고민해야 한다. 나는 3가지의 방법을 생각하였다. Character Character의 코드에 Weapon 관련된 코드는 넣지 않았기 때문에 이 작업 역시 Character에는 넣으면 안 된다. Weapon의 Mesh Component들은 Character에 있지만, 오직 Weapon Component에 넘기기 위함이다. Weapon Component Weapon Component가 Weapon에 관한 코드를 전부 담고 있기에 가장 적절한 장소일 것이다. 이를 역으로 생각하면 Weapon에 관한 모든 코드가 있기에 메시에 관한 코드까지 넣으면 복..
자연스러운 무기 교체 (1) 서론 Memorize: RECALL의 가장 큰 특징 중 하나는 무기 교체 시스템이다. 공격, 회피, 피격 상태가 아니라면 언제든지 무기를 교체할 수 있으며 이를 통해 콤보를 이어나가는 것 역시 가능하다. 그런데 무기 교체 후 Mesh와 Animation이 즉시 바뀌면 부자연스럽다. 그렇기에 Mesh와 Animation의 교체를 부드럽게 해주는 작업이 필요하다. Pose Snapshot을 이용한 애니메이션 블렌딩 Anim Instance의 무기 교체 인식 우선 문제가 되는 것은 Anim Instance에서 어떻게 무기 교체를 인식할 것인가였다. 여기서 나는 3가지의 방법을 생각해보았다. Weapon Component에서 Anim Instance의 함수를 직접 호출한다. Editor Time에는 Anim I..
Catmull-Rom Spline을 이용한 도약 공격 제작 Catmull-Rom Spline이란? Catmull-Rom Spline은 보간 스플라인의 한 종류로, 최소 4개의 Control Point를 정의하면 Alpha 값을 통해 P1과 P2 사이의 벡터 값을 얻을 수 있다. Catmull-Rom Spline의 가장 큰 특징은 제어점을 무조건 지난다는 것이다. 그렇기에 제어점을 지나지 않는 Bezier Curve와 B-Spline 대신 Catmull-Rom Spline을 선택하게 되었다. 적용 추후 Spline의 활용을 염두에 두고 Leap 클래스와 분리하였다. Spline 클래스에는 제어점을 가지는 Points 변수와 Vector 값을 계산하는 Compute 함수만을 두어, Spline 알고리즘에만 집중하였다. Leap 클래스에서는 제어점을 설정하고, 제어점..
UObject에서 Replication 지원하기 왜 UObject에서 Replication이 필요한가? Memorize: RECALL은 최대한 많은 것을 Server에서 처리한다. 그렇기에 모든 Weapon과 Skill 객체들은 Server에만 존재하며, 애니메이션을 플레이하는 등의 Visual적인 부분에만 Multicast를 통해 클라이언트에 호출한다. 여기서 문제가 발생한다. Skill 객체는 Server에만 있는데 어떻게 Multicast를 할 것인가. 난 이를 네트워크 관련 작업을 담당하는 클래스를 따로 두어 해결하였다. 이 기능에 Skill에 필요한 Utility적인 함수를 모아 만들어진 클래스가 SkillContext이다. 이제 SkillContext를 Actor나 ActorComponent에서 상속받아 Replication만 활성화하면 끝..
Weapon 초기화를 위한 새로운 설계 원래 Player와 AI의 Weapon 초기화를 BeginPlay에서 수행했다. 단말 Blueprint의 BeginPlay에서 직접 Wepaon을 생성하는 방식으로 동작하였고, 기존에는 큰 문제가 없었다. 그러나 Anim Montage 등의 각종 Animation Data를 Weapon에 종속적으로 하고, Unequip 상태를 나타내는 Dummy Weapon의 생성 과정에서 다수의 Bug가 발생했고, Refactoring을 감행했다. Refactoring 중 문제가 발생했다. Player와 AI에 모두 적용 가능한 무기 생성 코드를 어떻게 작성해야 할까? BeginPlay에서 수행할 경우, Unequip Weapon의 Getter를 제작해야 하며 Base Class -> Blueprint -> Child..
Runtime에 생성된 Anim Instance의 BeginPlay 추후 Ai 캐릭터의 확장 등을 고려하면 Anim Instance가 Mob의 종류마다 다를 필요가 있다. 그래서 Mob 설정을 저장하는 Data Table에 AnimClass Property를 추가하였다. Property의 추가 이후, 이를 적용하는 Blueprint를 작성하고 테스트하는 과정에서 문제가 발생했다. Mob의 Anim Instance는 BeginPlay가 호출되지 않는 것이었다. 이 때문에 필요한 Delegate를 Bind하지 못해서 모든 Character들이 Animation없이 A 포즈로 움직였다. 이를 해결하기 위해 평소처럼 Document를 찾아보며 Function의 Call Timing과 대체할 만한 다른 Function을 찾아보던 중 중요한 사실을 발견했다. Anim Instanc..
Blueprint의 BeginPlay는 BeginPlay가 아니다. Skill 클래스를 구현하던 중 C++로 작성한 Base Class BeginPlay가 Blueprint로 작성된 Child Class BeginPlay보다 늦게 호출되는 상황이 발생했다. 때문에 Child Class의 BeginPlay에서 User에 접근하면 값이 Null이어서 에러가 발생했다. Skill Class의 BeginPlay는 부모 함수 호출과 User 초기화 밖에 없기에 의심할 코드는 오직 부모 함수 호출이다. 그래서 Actor Class의 BeginPlay 코드를 뜯어보았다. 확인해본 결과 Actor의 BeginPlay는 크게 6가지를 수행한다. 잘 못된 호출인가를 검사하는 ensure문 LifeSpan 설정 Tick 함수 예약 컴포넌트의 BeginPlay 수행 ReceiveBeginPl..
포트폴리오 Notion: https://www.notion.so/f91f3feec98e4566974a8add0ccef77f