본문 바로가기

Memorize: RECALL

자연스러운 무기 교체 (2)

서론

 애니메이션 블렌딩을 통해 애니메이션은 해결되었다. 이제 남은 것은 메시를 자연스럽게 만드는 것이다. 그러면 이제 메시를 보간하는 코드를 어디에 작성하는지를 고민해야 한다. 나는 3가지의 방법을 생각하였다.

  1. Character
    • Character의 코드에 Weapon 관련된 코드는 넣지 않았기 때문에 이 작업 역시 Character에는 넣으면 안 된다.
    • Weapon의 Mesh Component들은 Character에 있지만, 오직 Weapon Component에 넘기기 위함이다.
  2. Weapon Component
    • Weapon Component가 Weapon에 관한 코드를 전부 담고 있기에 가장 적절한 장소일 것이다.
    • 이를 역으로 생각하면 Weapon에 관한 모든 코드가 있기에 메시에 관한 코드까지 넣으면 복잡해진다.
    • 메시에 관한 부분이 추가되면 Weapon Component가 더 비대해질 것이다.
  3. Weapon Mesh를 담당하는 새로운 Component
    • MVC 패턴은 View, Model, Controller를 분리하여 많은 이득을 본다. Weapon 쪽 역시 WeaponMesh, Weapon, WeaponComponent로 나누어 이득을 볼 수 있다.
    • Weapon의 메시와 관련된 코드만을 집중할 수 있고, 코드를 결집할 수 있다. 그래서 기능의 확장도 손쉽게 가능할 것이다.
    • 기존에 Weapon Component에 존재하는 Detach 등의 코드도 옮길 수 있다. 덕분에 Weapon Component가 더 가벼워질 것이다.

 그래서 Skeletal Mesh Component를 상속받는 Weapon Mesh Component를 만들었다. 그 후 Detach 등의 기존 Weapon Component에 있던 메시 관련 코드를 옮겼다. 그리고 메시를 세팅하는 인터페이스를 두고, Weapon Component에서 무기 변경 시에 호출하였다.

 

Scale 조정을 통한 자연스러운 메시 변경

 메시를 즉시 변경하면 부자연스러울 수밖에 없다. 이를 자연스럽게 하는 방법 중에 내가 생각한 방법은 메시의 크기를 줄인 후, 메시를 변경하고, 다시 키우는 것이다. 이 방법을 사용할 경우, 3가지의 경우를 고려해야 한다.

  1. 메시가 없는 상태에서 메시가 생길 때: 교체 즉시 메시의 Scale을 0에 수렴하게 변경 후, 늘려야 한다.
  2. 기존의 메시를 삭제할 때: Scale을 0에 수렴하게끔 줄인 뒤, 메시를 삭제하면 된다.
  3. 기존 메시를 새로운 메시로 교체할 때: Scale을 줄인 뒤, 메시를 교체하고, 메시 Scale을 다시 키운다. 두 행동을 해야 하므로, 속도가 2배여야 한다.

  이를 모두 고려하여 작성한 코드가 아래의 코드다. 여기서 주의할 점은 Scale을 0에 수렴하게 하되, 0이면 안된다는 것이다. Scale이 0일 경우 경고가 발생하게 된다.

매 프레임 실행되는 Mesh Scale 변경 코드

 

Material을 이용한 효과 추가

 그냥 Scale만 변경해도 큰 문제는 없지만, 무기 메시가 변경된다는 느낌을 주고 싶었다. 이를 위해 변경 중에만 Material을 변경하여 효과를 주었다. Material은 단순히 흰색으로 빛나는 Material이다. Mesh가 변경될 때 SetMaterial 함수를 통해 Material을 변경하고, 변경이 마무리될 때 EmptyOverrideMaterials 함수를 사용해 Material을 복구하였다.

 

Editor Time에는 즉시 변경

 Editor Time에는 효과를 적용할 수가 없고, 적용할 필요도 없다. 적용할 수 없는 가장 큰 이유는 Editor Time에는 TickComponent가 동작하지 않기 때문이다. 그래서 HasBegunPlay를 통해 현재 게임이 실행 중인지 확인하여 Editor Time일 경우에는 바로 메시를 변경하도록 구현하였다.

 

Editor Time에는 즉시 교체