달래의 애니메이션 #2

2.3

검기를 재활용하면 편할 줄 알았는데 붙이는 것도 꽤나 일이다.

달래의 스탠딩 일반공격. 펀치와 킥은 가까이 있을 때 모션이 달라야 한다. 대금을 들고 있어서 짠손이 너무나 고성능인데… 밸런싱은 나중에 손보자.

2.4

달래의 앉아서 공격 완료, 점프 공격 일부 제작. 이동점프가 한바퀴를 돌다 보니 갑작스레 공격모션이 튀어나오는 것이 조금 어색해 보인다. 육아를 하며 좀 더 자연스러운 모습이 없을까 고민해 볼 필요가 있겠다.

기존의 근접 강펀치는 앉아서 강펀치로 바꿨다. 격투게임의 경우 ‘앉아 강펀치’는 위를 공격해서 간이 대공기로 사용할 수 있는 캐릭터가 많다.

특별한 문제가 발생하지는 않고 있지만, 치마 뒷부분의 작업이 좀 눈에 거슬린다.치마가 생각보다 더 말썽. 아마도 그냥 못본 채 묻고 갈 것 같다.

2.5

작업은 주로 애를 재우고 새벽에 이루어지는데, 어제는 깜빡 잠이 들었다. 덕분에 늘어지게 잤는데, 왜 잠은 잘 수록 느는 걸까…외출 전 막간을 이용한 점프킥 작업. 내일은 데미지 모션들을 작업해야겠다.

2.6

눕기 작업을 하던 중 스키닝에 큰 구멍을 발견했다. 이것때문에 한 세월.

작업을 하다보니 오일러는 잘 안쓰게 된다. 초기 작업을 할 때 이걸 결정하는데 꽤나 고민을 많이 했는데, 처음 잡은 액션이 후속 액션에 지속적으로 영향을 끼치기 때문이다. 당시엔 오일러 중심으로 작업하되, 회전이 불규칙적인 팔다리관절만 쿼터니온을 쓸 생각이었지만 커브를 잘 사용하지 않는 나로서는 결국 쿼터니온의 압승. 애니메이터는 커브를 잘 써야 한다던데, 나와는 맞지 않는다. 루핑빼고는 커브 쓸 일도 딱히 없고…원하면 오일러로도 바꿔쓸 수도 있긴 하다.

어쨌거나 액션초기화 시 애드온을 모두 쿼터니온으로 바꾸도록 수정해 두자. 현재는 Idle에 지정된 상태를 사용하도록 되어 있다.

달래의 데미지 모션 처리. 남은 건 턴같은 사소한 모션, 그리고 어색한 모션 보강작업. 오늘은 여기까지

2.7

턴 모션은 상대가 방향을 바꿀 때 해당방향을 자연스레 바꾸기 위한 모션이다. 2D격투게임의 특성상 좌우반전이 기본이기 때문에 오른손잡이가 왼손잡이가 되는 기적을 보여준다. (철권같은 풀3D게임은 좌우를 뒤집지 않는다.) 애초에 말이 안되는 동작이지만, 손을 바꾸는 거야 물리적으로는 가능하니까 그렇다 치는데, 달래는 특히 말이 안되는 것이… 어깨에 맨 각궁이 목을 베고 반대편으로 이동한다! 이걸 위해 활을 빼서 다른 어깨에 걸치려면 매우매우 많은 프레임이 필요하기 때문에 무리. 때때로 애니메이션은 자연스러운 궤적이 물리법칙을 무시한다.

어쨌거나 이로서 달래의 기본모션도 작업 끝!

역광은 이상한 점이 있다. 정면셰도우가 좀 약하게 나온다..?

솔리드 셰이더의 뷰기준 폼셰이딩 밝기가 블렌더와 같지 않은 문제가 있었다. 또하나의 구멍을 메웠다.

몇가지 프로그램 이슈가 있긴 했지만, 큰 문제는 아니었다. 설연휴를 쇠고 다음캐릭터인 오로라로 넘어가도록 하자.

달래의 애니메이션 #1

1.31

먼저 대기자세부터 만들자.

뒤로 걷는 건 좀 신나보이는데…?!

오늘은 여기까지.

2.1

액션을 처음 만들 땐 신경써야 할 것들이 많아서 매크로를 만들어 사용한다. 이 매크로 기능 중엔 표정의 초기화도 들어있었는데, 달래처럼 표정이 엄근진한 캐릭터는 초기화될 때마다 헤이해진다. 앨리스와 닐리는 이것이 어울렸었는데, 달래는 그렇지가 않다. 애초에 왜 페이셜 초기화를 넣었지?를 생각해보면 Idle이 NLA첫트랙에 들어가기 전의 일이다. 하지만 이제 NLA에 Idle을 넣어두었으니 캐릭터성이 변할 일은 없다. 페이셜 코드는 삭제하는 편이 좋겠다.

처음보는 문제가 발생했다. 캐릭터가 거꾸로 빙글 돌자, 치마가 다 깨진다.

자세히 보니 치마의 웨이트가 역정렬되고 있다..볼륨유지 옵션을 의심했지만, 아니다!

원인을 찾았다. 치마본이 돌아간다…왜지?

치마본의 제약조건은 위치값 복사와 스트레치의 합작이다. 하지만 어쩐지 별도의 부모본이 설정이 되어 있지 않았다. 따라서 캐릭터가 회전하면 트랜스폼 정보가 꼬이게 된다. 그렇다면 닐리도 그럴까? 싶어서 찾아보니 또 닐리는 제대로 해놨네…? 그냥 단순한 실수였다. 치마본들의 부모를 root.x로 설정해주자.

이제 제대로 표현된다. 오늘 작업 다했네..싶었는데 다행이다.

테스트를 위해 데이터를 넘겼더니 역시나 엉망진창이다. 대체로 커스텀 본 설정을 빠뜨려서 생기는 오류들이다. 혹은 저번처럼 5각 이상의 버텍스때문인지도 모른다.

빠르게 해결하고 색칠하자.

옷이 너무 빛난다…?! 왜 그럴까 조사해봤더니… 최종계산에서 Saturate를 빼먹고 있었다. 이걸 왜 지금까지 몰랐지…? 작업하다 보니 맷캡도 마스킹 코드가 빠져있었다. 구멍이 슝슝.

여튼 색칠 완료.

닐리에 비해 확실히 작다!

앨리스와는 비슷하다.

걷기를 몇 번째 수정하고 있다. 예상 외로 이미지 얻기가 꽤 힘든 캐릭터.

2.2

오늘의 깨달음.

옆걷기를 제작할 땐 상하진폭을 좀 더 크게 해주는 편이 좋다.

달래의 이동 애니메이션 제작. 앉기를 어떻게 할 지 여전히 고민이다.

저렇게 앉으면 종아리가 두꺼워진다…그걸 바라고 드라이빙한 것이긴 한데, 이 캐릭터는 특히 티가 많이 나니 조금은 줄이는 편이 좋겠다.

요 정도…? 다른 캐릭터에게도 적용해두자.

상태머신 보강 #2

1.26

이번 보강작업엔 굵직한 이슈들이 몇가지 있다. 저번처럼 모든 작업이 하루만에 끝나기를 기대하는 것은 어려워 보인다. 작업을 시작해 보자.

장풍을 맞고 모션이 변하지 않는 버그가 있었다. 이건 노션에 적힌 문제는 아니다. 로그를 찍어봐도 도무지 뭐가 문제인지 모르겠다.

현직 프로그래머들이 들으면 기겁을 할 지도 모르겠지만, 난 지금까지 브레이크 포인트를 써본 적이 없다. 모든 것을 로그를 찍어 추리로서 문제를 해결해 왔다. 어떻게 쓰는 지 몰랐기 때문이다. 그럼에도 지금까지는 잘 버텨왔는데, 이제는 배워야 할 때가 된 것 같다. 이런 야밤엔 챗 GPT가 좋은 스승이 되어 준다.

빨간 점을 찍어보니 문제는 단번에 파악된다. 장풍의 데미지 처리는 장풍의 Update()에서, 모션의 처리는 캐릭터의 LateUpdate()에서 처리한다. 그런데 장풍이 부딪히는 시기가 캐릭터의 Update()보다 반드시 뒤쪽에 온다는 보장이 없다. 때문에 때때로 제대로 표현되기도 했던 것이다. 오. 빨간 점은 좋은 것이었구나…!

계속 버그를 잡자. 역광을 비쳤을 때 입이 제대로 표현되지 않는 버그가 있었다.

아이고.. 괜히 한참을 찾았네. 케스케이드 그림자 관련된 전처리 지시문 처리가 빠져 있었다. 즉 그림자가 표현되지 않고 있던 것이다.

셰이더 코드를 짤 때 셰도우 캐스터 빼면서 ‘입은 뭐, 그림자 없어도 되겠지…’라는 생각이었던 것 같다. 셰이더는 화면에서 차지하는 면적이 중요하다. 해당 면적만큼 계산이 일어나기 때문이다. 아무리 복잡한 코드라도 면적이 작다면 그럭저럭 괜찮다. 그런데 입은 어차피 면적도 작은데 이거 아껴서 뭐할라고 그랬을까….

휴. 많이 처리했다. 오늘은 여기까지.

1.27

장풍을 처리하기 위해 풀매니저를 붙여야 한다. 솔직히 풀관리가 그렇게 필요하지는 않다. 게임은 길어봐야 99초일테고, 두번째 라운드는 씬전체를 로드하는 방식을 사용할 것이다. 유니티의 가비지 컬렉터는 악명이 높지만, 겨우 캐릭터 2명 나오는 게임의 리소스를 쓰레기처럼 쌓는다고 해도 게임을 끌 때까지 그렇게 부담을 줄 것 같지는 않다.

하지만 이걸 붙이는 이유는 그냥 만들어 둔게 있기 때문이다. 오래 전 관둔 벨라 프로젝트의 스크립트를 가져와서 붙이자. 성능은 후지지만 스스로 만든 것이기에 새로 배울 것이 없다는 장점이 있다.

파이어볼은 이제 하이라키에 남는다. 이후에 장풍을 사용하게 되면 이를 재활용하게 된다. 사실 장풍보단 타격효과나 먼지 효과등의 공용이펙트에 더 효과적이다. 초안이기 때문에 아마 정식데이터를 붙이면 문제가 많을 것으로 예상되지만 이런 최적화들은 뭐랄까… 마음의 안정을 준다. 풀매니저란 이름은 이펙트 매니저란 이름으로 바꿨다.

이제 2개 남았다. 오늘은 여기까지

1.30

이틀간 놀았다. 백수에게도 쉬는 날이 있어야지.(??)

장풍의 처리. 이제 버튼에 따라 장풍 속도가 달라진다.

예정엔 없던 작업이지만 문득 생각나서 노션에 노트해둔 작업. State변경을 LateUpdate()에서 처리하고 있어 문제가 없을 줄 알았는데, 예상과는 달리 동시타격할 경우, Player1의 판정이 더 좋은 문제가 있다.

동시에 치면 동시에 맞아야 한다. 자주 일어나는 일은 아닐테지만, 결정적인 순간에 시스템의 판정으로 진다면 꽤 억울할 것이다. 이걸 작업하며 여러개의 데이터 유형을 Tuple로 넘길 수 있는 사실을 처음 배웠다.

목표했던 코딩 작업은 끝났다. 이제 달래의 애니메이션으로 넘어가도록 하자.

닐리의 애니메이션 #2

1.22

포즈모드에서 alt+e를 누르면 슬라이드 조절바가 뜬다. 간혹 회전값 초기화를 위해 alt+r을 잘못누를 때 발동되는 이 기능은 Relax Pose라는 기능이다. 버튼 한번으로 끝나지 않고 슬라이드를 조절한 후 마우스를 한 번 더 눌러야 적용되기 때문에 조작이 다소 성가신 편인데, 처음엔 이 기능은 대체 뭐길래 내 작업을 방해하나 싶었다.

하지만 그 기능은 양쪽 키의 중간값으로 보간해주는 좋은 기능이었다! 지금까지는 중간값을 보간해 주기 위해서 해당키를 삭제하고 다시 만들어 주었는데 그럴 필요가 없어졌다. 이는 부드러운 애니메이션 궤적을 만들 때 많은 도움이 되고 있다.

그럼 계속 만들어보자.

닐리의 각 공격 러프 애니메이션 추가. 클립챔프로 녹화하니 프레임이 부드럽지 못해 그냥 윈도우 기본 녹화 프로그램을 이용했다. 어째… 그래도 용량은 똑같다. 클립챔프는 편집 시에만 이용하도록 하자.

특별히 기술적 이슈가 없으니 바로 디테일에 들어간다.

근접했을 땐 로우킥!

이는 편 손의 약간 변형형이지만, 은근 자주 사용하는 손모양이라 프리셋으로 만들었다.

음!확실히 편하다.

오늘의 깨달음. 유니티의 애니메이션은 0부터 프레임을 센다. 뭔 당연한 말인가 싶지만, 블렌더에서 타격키로 4프레임을 예상했다면 1프레임 빼서 생각해야 자연스럽다. 즉 유니티에서 2->3을 갓넘어간 시점이 가장 자연스럽다. 지금까진 3->4를 갓 넘어간 시점이라 생각했었다.

근접 강손은 싸다구! 마법은 언제 쓰니.

근접약손은 원거리약손과 같다. 뭔가 학생에게 고나리질 하는 선생같이 나와버렸다. 의도했던 건 아닌데 공격 상당수가 당하면 기분나쁜 걸로만 만들어지고 있다는 느낌

1.23

벌써 1월이 끝나간다. 끝이 보이지 않을 것 같았던 아이의 기나긴 방학도(병설 유치원은 방학이 길다.) 다음주면 개학을 맞이한다. 잘 버텼고, 한 달 더 버텨야 한다. 아이고 죽겠다.

점프 애니메이션까지 완료. 초안에서 크게 벗어나지는 않았다. 이제 다음은 데미지 애니메이션.

로브때문에 덩치가 크니 맞는 게 훨씬 잘 보인다. 실제로 게임을 하다 보니 닐리가 너무 큰 느낌은 있다.하지만 이제 와서 손을 보기엔 좀 늦었지. 그냥 진행하기로 하자.오늘은 여기까지

1.24

데미지 모션 작업 중. 어제오늘 너무 많은 클립을 단시간에 작업하다보니 충분한 공이 들어가지 않는 클립들이 몇가지 발견된다. 데미지 모션을 하기 싫은 것도 있긴 한데, 그것보단 뭔가 마음이 급하다. 코인으로 돈을 잃어서 그런가!(내가 봐도 난 트레이드를 정말! 못한다!)

오늘은 타임오버. 내일은 데미지 모션을 다듬고 마법을 쏘아보자.

1.25

데미지 모션을 만들 때 평면적으로 회전하기보단 중심의 Roll 중간키를 좀 주어서 살짝 비틀어 주는 게 효과적이다.

파이어볼 모션까지 완료. 이제 엔진에 가서 발사해 보자.

이로서 닐리의 기본 애니메이션 완료. 모션 테스트를 하며 작업보드에 또 한가득 이슈가 쌓였다.

이걸 손보고 달래로 넘어가자.

닐리의 애니메이션 #1

1.18

작업에 앞서 앨리스에게서 발생했던 목달랑거림 문제를 해결하자. 모든 캐릭터에게 적용되어야 할 것이다.

  • head.x의 Rotation Lock를 모두 푼다.
  • head.x를 Deform -> Main 레이어로 옮긴다.
  • c_head.x를 Main -> Secondary로 옮긴다.
  • head.x의 부모를 neck.x로 변경한다.
  • head.x의 커스텀 오브젝트를 cs_circle_01로 변경한다. 오프셋은 다음과 같다.
    • Scale : 0.6
    • Translation Y : 0.15
    • Rotation Z : 90

4.0으로 업데이트 후에 몇몇 애드온들이 충돌을 일으킨다. Weight Tools또한 없어서는 안될 필수 애드온인데, 4.0에서 파이메뉴가 작동하지 않는다.

https://bartoszstyperek.gumroad.com/l/weight_paint_tools?layout=profile

개발자가 다행히 4.0대응을 해놓았다. 새로 업데이트 받자.

삽질 내용은 모든 캐릭터에게 적용해야 한다. 이후의 캐릭터는 레퍼런스 모델에서 교정된 모델을 토대로 작업할 것이기 때문에 알아서 수정될 것이다.

대기자세부터 만들어보자. 원래 지팡이를 오른손에 들었었으나, 공격모션이 예쁘게 나오지 않을 것 같아서 왼손으로 변경했다.Idle은 NLA에 첫트랙으로 등록해서 초기값으로 사용한다.

1.19

러프 애니메이션을 끝내고 엔진으로 옮겨오는 도중 문제가 생겼다.

…는 그냥 노말맵 세팅이 잘못되어 있었다.

데이터가 복잡하기 때문에 임포트는 한 번에 안된다. 처음 데이터를 임포트하면 수많은 에러가 뜬다. 무려 2948개의 버텍스가 부모본을 못찾고 있다. ARP의 커스텀 본 세팅을 빠뜨린 모양이다.

애니를 재생해보면 원인은 바로 나타난다.

원인을 조사해보니 4각이 넘어가는 폴리곤이 있을 경우 이런 경고문을 띄운다고 한다. 하지만 앨리스를 작업할 때엔 보지 못한 경고문이다. 아마도 닐리의 악세사리에서 사용한 평면적인 베벨이 문제를 일으키는 것이 아닐까 싶다. 엔진이 보기엔 ‘이런 거에 폴리곤 낭비하지마!’같은 느낌이겠지. 하지만 난 그게 필요하단다. 일단 4각이하로 폴리곤을 정리해주기로 하자. 

블렌더에선 Select Silmilar(shift+G)로 선택한 폴리곤과 같은 각의 폴리곤들을 모두 선택할 수 있다.

이걸 누른 후 4각을 숨기면 폴리곤이 몇 개 안남는다. 같은 방법으로 3각도 숨겨준다. 그러면 정말 몇 개 안남는데, 이걸 모두 선택하고 Triangulate Faces(ctrl+T)를 누르면 얘네들은 삼각형으로 변한다. 삼각보단 사각화하고 싶으면 이 상태에서 Quad로 변경해주면 된다.(alt+J) 다만 애초에 5각 이상인 애들이라 예쁘게는 안된다. 큰 기대는 말자.

이제 에러는 나지 않는데 어쩐지 화가 나있는 것 같다.

음… 걷기 모션의 변화폭이 크니 별로 어울리지 않는다. 수정하자.

야호… 이 모자 그림자를 표현하고 싶었다. 블렌더에선 저게 안된다!

허리의 움직임에서 목달랑거림현상과 같은 프레임 지연현상이 나타난다. 결국, 허리 전체의 구조를 바꿔주는 편이 좋아 보인다.

…를 시도해 보았으나 실패. 이건 머리와 다른 문제로 보인다.

심지어 알바디에서도 같은 문제가 발생한다!

그런데… 보간키를 삭제하니 문제가 사라졌다.?! 해결책을 찾았다.

루프 애니메이션을 만들 땐 사이클링을 한다. 위의 그림으로 예를 들면 0-40프레임의 재생을 위해 클립 양쪽에 애니메이션을 보간해주는 키를 별도로 둔다. 블렌더의 fcurve에디터엔 사이클링 기능이 있지만, 이것은 유니티로 익스포트가 안된다.

그런데 이것이 문제가 되는 모양이다. 해결책은 그냥 보간키를 지워주면 된다. 그래도 커브가 깨지지는 않는다. 신기하다.

이제 해결됐다. 원인은 찾지 못했다. 내부적인 문제일테니 신경쓰지 않기로 하자.

1.20

원활한 작업을 위해 앨리스로부터 충돌박스용 본을 들고 왔다. 그런데 이걸 합쳤더니 모션이 깨진다. 이상한 일이네… 모션은 다 빼고 본만 들고 왔는데.

추적끝에 찾아낸 원인은 NLA. 앨리스의 아마추어에서 분리했기 때문에 기본동작인 Idle을 들고 있다. 이것이 기본 애니메이션보다 상위에 존재하게 되어 애니메이션을 제대로 출력하지 못하게 방해한다. 그냥 지워주기만 하면 된다.

앞걷기/뒤걷기. 이미지 자체는 처음부터 잡혀있었지만 어쩐지 예쁜 모양이 안나와서 꽤 오래걸렸다.

닐리의 기본 애니메이션 제작. 실전에 들어가니 설계했던 제약조건 및 드라이버 몇몇개는 쓸모가 없었다.

앉은 포즈는 공격이 고민이다. 강손을 때리면 뭘 어떻게 쳐야 하지…

1.21

허리의 덜컥거림 문제가 재발했다. 이번엔 앞선 키를 지워도 해결이 되지 않았다. 베이킹도 해보고 마이너스 프레임도 제거해봤지만 결과가 같았다. 앞선 방법들이 해결책이 아니라 차라리 다행이다. 그 상태로는 작업이 힘들테니까.

문제를 추적끝에 결국 애니메이션 커브의 보간문제로 밝혀졌다. 전에는 이전 키를 하나 지워서 해결했었는데, 이번엔 그보다 더 앞선 키를 하나 더 주는 걸로 해결을 할 수 있었다. 전에 가장 먼저 의심했던 요소지만 이번엔 접근을 달리 해봤다. 개발하다보면 이런 게 참 어렵다. 이런 건 인터넷을 검색해도, 챗GPT에게 물어봐도 답을 주지 않는다.

닐리의 강손은 처음부터 장타(손바닥치기)를 때릴 생각이었는데, 로브애니메이션이 아직 덜되어 그런지 생각만큼 예쁘지는 않다.

닐리의 애니메이션 추가 중. 작업 속도가 조금씩 개선되고 있다. 오늘은 여기까지

상태머신 보강

1.17

애니메이션을 제작하며 발견되는 버그를 그 때 그 때 노션에 적어두고 있다. 작업을 변경하는 건 정신적으로 꽤 큰 피로감이 있기 때문에 이렇게 몰아서 하는 편이다.

…는 생각보다 일찍 끝났네?! 카메라는 어차피 배경들어간 후에 작업해야 하고…

이제 캔슬기는 히트시에만 사용할 수 있다.

짠손은 강손으로, 강손은 스킬로, 스킬은 초필로 캔슬할 수 있다.

다음은 닐리의 기본 애니메이션을 만들어 보자.

앨리스의 애니메이션 #4

1.14

페이셜 키를 넣는 자동으로 넣는 코드에 버그가 있었다. 키가 있는지 없는지는 fcurve를 조사하고 있는데, 정확히는 fcurve의 data_path를 조사한다. 여기에 정보가 있다면 커브데이터가 있는 것이라 키를 넣었다고 봐도 무방하다…. 드라이버가 없다면 말이다.

드라이버는 drivers리스트에서 별도로 관리된다. 즉, fcurve의 리스트에는 잡히지 않는다. 그런데 data_path는 공유해서 쓴다. 즉슨, 키가 없어도 드라이버가 있다면 데이터 패스는 존재하기 때문에 커브가 있다고 오인할 수 있다.처음엔 이것이 업데이트 때문에 구조가 바뀌었고 -> 그로 인한 구시대의 잔재가 쓰레기 데이터로 남아 날 괴롭히고 있다고 생각했지만, 여기까지 고려한다면 커브와 드라이버의 데이터패스 충돌문제라고 추측할 수 있다. 때문에 코드상으로는 드라이버+커브의 조합은 있을 수 없지만, 실제로 작업은 된다(?!)

이 혼돈에서 탈출하기 위해 그냥 오퍼레이터를 쓰자… 조사범위도 커브에서 본으로 바꾸면 될 것이다. lock을 걸어둔 항목은 정보를 넣을 필요가 없다. 코드는 길지만 속도는 빠르다. 이것 때문에 또 한 고생했다. 삽질이 없는 날이 없구나. 아이고.

하루에 모션을 잡는 수는 제한되어 있다. 내 하루 작업시간은 3시간 남짓이지만, 작업시간이 늘어난다고 더 많은 모션을 잡을 수는 없다. ’예쁜 모션’을 잡기 위해선 예상보다 생각을 많이 해야 하는데, 이 ‘생각’의 힘이 소진되면 더 이상 머릿 속에 아무 것도 떠오르지 않는다… 이는 예전에 그림을 그릴 때도 마찬가지였는데, 개인적으로 RPG게임의 MP에 덧대어 ‘Drawing Point’의 약어인 DP라고 부르곤 했다. DP가 떨어지면 이후에 그리는 것들은 내일의 재작업분량이 된다.

하고 싶은 말이 뭐냐면 만약 나중에 출근하면 4시간만 일하면 안될까요? 미래의 사장님.

애드온에 또 문제가 있다. 액션이 어셋으로 지정되어 있을 경우는 페이스 키를 넣으면 안된다. 이건 내일 작업해보도록 하자.

1.15

데미지 모션을 만드는 건 생각보다 쉬운 일이 아니었다. 최대한 아프게 보여야 하는데, 그렇다고 몸을 과도하게 구부리면 전체적인 실루엣이 망가지고, 그렇다고 구부리지 않으면 느낌이 살지 않는다. 어려운 일이다.

넉다운 애니메이션은 근래의 작업 중 가장 힘들었다. 0프레임에 튕기기 직전의 준비 프레임, 1프레임에 ‘텅’이다. 고작 1프레임차이인데, 차이가 난다.

후다닥. 일어나는 애니메이션은 난이도가 제법 어려운 애니메이션에 속한다. 일단 몸을 팔꿈치로 지탱해서 몸을 반쯤 일으킨 후에 허리힘을 이용해서 상체를 세운 뒤 반대손을 무릎으로 짚어서…등등의 복잡한 과정이 들어간다. 하지만 격투게임은 그럴 시간이 없어서 그냥 호다닥 일어나야 한다. 오히려 편해

데미지 모션이 생각보다 오래 걸리고 있다. 내일은 끝낼 수 있을까

1.16

지금까지는 NLA의 모든 모션을 지우고 있었다. 여러모션이 섞이는 것이 별로 달갑지 않았기 때문인데, 이 때문에 본의 제약조건들이 액션마다 서로 다르다면, 초기값을 못찾고 마지막으로 설정됐던 값이 그대로 반영되는 현상이 발생한다. 뭐든 수가 많아지면 문제도 많아진다.

때문에 NLA트랙엔 Idle 하나는 있어야 한다는 결론을 얻었다. 이것이 일종의 ‘기준값’역할을 한다. 코드에도 이를 추가하고 애드온을 업데이트 해두자.

애드온은 그냥 수정할 때마다 버전을 하나씩 올리고 있는데 벌써 21이다. 앞번호는 대규모 카테고리가 추가됐을 때 붙이는데, 회전툴을 붙이면서 0.1을 올렸다.

필요없는 듯 하지만 있어야 하는 Turn모션. 왼손잡이가 오른손잡이가 되는 마법.

이게 없으면 좀 딱딱해 보인다. …나쁘진 않네?

데미지 모션처리까지 완료했다. 기본모션은 모두 끝났고, 스킬과 잡기 작업이 남았는데… 들어가기 전에 상태머신 수정이 좀 필요할 것 같다. 버그를 잡자!

앨리스의 애니메이션 #3

1.9

검기가 필요하다! 프레임이 너무 빨라 트레일은 부적합하고 예쁘지도 않다. 메쉬로 만들자. 그리고 이를 위한 셰이더도 만들자.

uv를 풀러서 v에 사인을 적당히 비벼서 만들었다. flow수치를 따로 빼내어 애니메이션 할 것이다.

입컨트롤러 아래에 검기전용 컨트롤러를 만들었다.. 검기는 평면이므로 본을 만든 후, Z스케일에 드라이브시키면 될 것이다. 스케일은 0이 되면 안되니까, 드라이브 수치는 var + 0.01로 해야 한다.

완성됐다. 이제 모션에 붙여보자.

계획대로 잘 움직이는 것 같다. 이제 유니티로 넘기자.

??? 내가 뭘 잘못한 걸까…

조사해 보니 드라이버를 사용하는 트레일 메쉬의 모델스케일이 0.01로 되어 있었다. 팩터를 스케일에 매핑하고 있으므로 이것은 곧 밝기가 된다. 즉 100배 조도로 작동하고 있었다.

이제 잘 작동한다. 그런데 스샷이 무슨 개그만화처럼 찍혔어!?

1.10

며칠전에 발생했던 목덜렁현상이 재발했다. 이번엔 위치의 오프셋대신 회전값의 로테이션이 문제다. 이번에는 전처럼 본이 32개를 기준으로 오류현상이 발생하지 않고 30개쯤에서 발생한다. 메모리 문제가 맞는가…

컨트롤러를 버려보기로 한다. ARP는 머리를 컨트롤러로 제어하고 있다. 이걸 직접제어로 바꾼다.

  • 아마추어 32번레이어에 있는 head.x의 회전락을 푼다. 함께 설정되어 있던 Copy Rotation도 삭제한다.
  • 제어가 쉽도록 1번레이어로 옮기자.

디폼과 컨트롤러가 분리되어 있지 않은 케이스는 이미 존재한다. 손가락이다. 익스포트만 문제가 없다면, 이대로 사용해도 될 것이다.

잘 넘어오는 것 같다.

하지만 기존의 head.x는 컨트롤러에 의해 제어되고 있었기 때문에, 애니메이션이 모두 초기화되었다. 이는 fcurve를 복사해 붙여주거나, 다시 잡아주어야 한다. fcurve를 수동으로 복사해주자.

스탠딩 어택은 가까울 때와 멀리 떨어져 있을 때 모션이 다르게 나타난다. 오늘까지 이걸 처리했다. 내일은 제발 기술적 이슈가 없기를. 흑흑

1.11

오늘의 깨달음.

쿼터니온값의 부호를 바꾸면 360도 돌아간 값으로 새겨진다. 이는 캐릭터가 한바퀴를 도는 애니메이션을 제작할 때, 처음과 끝을 같은 모양으로 맞춘 애니메이션을 제작할 때 용이하다.

이제 앉아서 공격들을 만든다.

익스포트 후.. 내가 뭘 또 잘못한거지..

조사 결과, 스케일이 모두 음수값으로 익스포트되고 있었다. 이것이 블렌더의 문제인지, 아니면 유니티의 문제인지, 혹은 ARP의 문제인지 불분명하다. 이것에 대해선 내일 조사해보기로 하자.

1.12

스케일이 모두 음수값으로 익스포트 되는 것은 ARP의 문제로 밝혀졌다. 심화단계로 가니 FBX 익스포트에 소소한 버그들이 발견된다. 제작자에게 메일을 보낼까 하다가 스샷찍고 파일정리할 게 귀찮아 그냥 고쳐쓰기로 했다. 검기의 x축을 뒤집어 쓰고 싶은 것뿐이니 그냥 180도 돌리면 된다.

하지만 검기가 항시 표현되고 있는 것이 생각보다 작업을 많이 방해하는 느낌이다. 클립해서 보이지는 않으나 GPU란 놈은 계산을 모두 끝낸 후에 버리는 비효율적인 짓꺼리 또한 할 것 같으니 그냥 계산면적을 줄여주는 편이 좋겠다. 애드온 기능이 또 필요하다.

  • 액션 초기화 시 본에 trail이 붙은 본의 트랜스폼을 초기화해주고 스케일을 0.01로 줄여준다. (0은 안된다.)
  • 모든 액션에 같은 행동을 해야 한다.

이를 위해 모든 액션에 필수키를 추가하는 버튼을 만들었다. 이 버튼은 주요관절에 로테이트 모드를 고정하고 트레일이 붙은 본은 초기화해서 0프레임에 트랜스폼 키를 넣는다. 이 과정을 통해 키가 없는 액션의 데이터가 엉망이 되는 경우를 방지할 수 있다. 테스트 해보자.

본의 이름을 변경할 일이 있었다. 블렌더에서는 이름으로 데이터를 찾기 때문에 이름이 바뀌면 액션의 데이터 호환이 안된다. 즉, 데이터는 있는데 모션이 깨진다. 이를 위해 스크립트를 제작해야 했다.

이제 문제 없다. 그런데 사소한 문제가 하나 더 있다. 모션이 안예뻐…

자세를 좀 더 낮게 수정. 이 쪽이 더 마음에 든다. 내일은 기술이슈가 없기를(…)

1.13

이 게임을 만들면서 격투게임의 제자리 점프 공격과 앞으로(혹은 뒤로)점프 공격의 모션이 다르다는 걸 처음 알았다. 생각보다 굉장히 많은 공이 들어간다.

검기의 회전값이 작동하지 않는 현상이 있었다. 원인은 모르겠지만, 회전모드를 오일러로 바꿔서 한 번 돌린 후에, 다시 쿼터니온으로 바꾸면 잘 작동한다. 일단 블렌더를 업데이트 했지만 여전히 발생하는 버그. 검색해도 같은 문제의 사례가 발견되지 않는 걸로 봐서 아마도 표시는 쿼터니온으로 되어 있으나 계산은 오일러로 되고 있는 상황같아 보인다. 왜 이런 현상이 발생하는 거지…

졸지에 블렌더만 업데이트한 셈이 됐다.

아하. 4.0에선 레이어 방식이 변했다. 이제 레이어는 얼마든지 추가할 수 있고 이름도 지정할 수 있다. 좋은 개선이다.

업데이트 후 페이셜 키 중 찡그린 눈썹의 키가 작동되지 않는 현상이 있었다.

어쩐지 저게 자물쇠가 걸려 있다. 이걸 해제해주면 된다. 이것이 4.0으로 오면서 데이터가 포팅된 것인지, 아니면 그냥 단순히 원래 있던 내 실수였는지는 모르겠다. 후자라면 좋겠다.

공격 모션은 대략 완성했다. 이제 데미지 모션을 처리해야 한다.

데미지 모션을 제작하다 알아낸 사실. 모든 모션에 페이셜 키를 0프레임에 추가해주어야 한다. 기존에 짜놓았던 코드가 있어서 어렵지 않게 해결. 내일은 데미지 모션을 만들어보자.

앨리스의 애니메이션 #2

1.4

타이밍은 대충 맞췄다. 애니메이션 심화학습단계로 진입하자. 블렌더를 사용한지는 2년이 넘었지만, 사실 맥스에서 블렌더로 넘어오기 가장 힘들었던 부분이 바로 이 애니메이션 부분이다. 바이패드와 ARP는 시스템이 매우 다르다. (처음엔 Rigify를 사용했지만, 시스템이 다르기는 마찬가지다.)

블렌더의 애니메이션 시스템 중 가장 힘들었던 점은 팔다리의 제어다. 바이패드는 FK/IK구분 없이 움직임은 무조건 IK기준으로 제어할 수 있다는 장점이 있다. 툴에 익숙해지기만 한다면 이것은 상당한 장점이 된다. 작업이 빠르다. 하지만 다른 툴로 전향하고자 한다면 이것은 도리어 약점이 된다. FK/IK 적응이 상당히 힘들다. 팔다리 움직임의 중요성이야 말할 것도 없는데, 이것이 불편하다면 블렌더가 좋게 생각되겠는가?

하지만 돌아갈 수 없다. 컴퓨터를 새로 바꾼 후에 맥스는 깔지도 않았다. 그렇게 작정하고 덤비니 …오. 바이패드보다 좋은 점도 상당히 많아 보인다. 뭐, 이제 시작이긴 하지만 역시 사람은 적응의 동물이다. 확실하다. 맥스의 시대는 갔다.

익스포트한 데이터의 목이 달랑거리는 문제가 있다. 이걸 해결해야 한다.

1.5

처음엔 머리가 달랑거리는 원인으로 제약조건이 잘못설정되어 있을 것으로 생각했다. 난 기본값을 건든 기억이 없지만, 작업을 하다보면 나도 모르는 새에 무언가를 건드리기 마련이다. 하지만 기본값은 모두 깨끗했다. 도무지 원인을 파악할 수 없어 빙챗에게 물어봤는데 역시 뾰족한 해결책을 내려주지는 않았다.

하지만 AI와의 대담(?)중 메모리 부족이 아닐까요? 하는 이야기에 실험을 해보기로 했다. 그런데 놀랍게도 그게 맞다! 머리카락 본을 모두 지우고 익스포트를 하게 되면 머리가 달랑거리는 현상은 일어나지 않았다. 그러고보니 이전에 대규모씬을 작업할 때에도 머리가 항상 한템포 늦게 따라오는 현상이 있었다. 메모리?! 캐릭터가 하나밖에 없는데 메모리라고?! 데이터가 크긴 크구나.

익스포트하자고 머리카락을 지울 수는 없는 노릇이다. 상상도 못한 정체에 약간 멘붕이 온다. 이번 문제는 주관식이다. 어떻게 할까. 좀 더 정밀한 테스트를 진행해보니 머리에 연결된 본이 32개 이상이면 딜레이 현상이 발생한다. 딱 32에서 걸리는 걸 보면 메모리 문제가 아닐 것 같다는 생각도 든다. 애드온 코드를 살펴보니 저세상 난이도이다.어..으..

물리적으로 해결해보기로 했다. 머리가 달랑거릴 여지를 주지 않도록 본의 부모를 바꾸도록 하자.

  • head.x 의 부모를 c_head.x → neck.x로 변경한다.
  • 그런데 이러면 머리가 컨트롤러를 안따라가니까 head.x가 컨트롤러를 따라가도록 Rotation_Copy(World)를 준다.

해결했다. 목에 완전히 Connect해버렸기 때문에 이제 목을 늘이는 처리가 안된다. 전혀 상관없지. 스키비 토일렛이라도 만들지 않는 이상은.

(한 때 사촌조카로부터 구전되어 내 정신을 오염시켰던 스키비 토일렛)

오늘의 깨달음. 키 사이에 얇은 줄이 그어져 있는 경우는, 프로퍼티의 값에 애니메이션이 들어가 있을 경우를 뜻한다.

앞으로 걷기. 오늘은 여기까지

1.6

착지 및 점프 준비. 순간적인 동작이지만, 없으면 안된다.
뒤로 걷기
제자리 점프

앞으로 점프. 앨리스는 큰 차이가 없지만, 스피드형 캐릭터는 공중제비등으로 차이를 줄 수 있다.

앉기

이 쯤에서 한 번 익스포트해서 느낌을 보자.

조금 뻣뻣한 느낌이 든다. 좀 더 유연할 필요가 있어보인다. 수정해보자.

1.7

어셋브라우저의 블렌드 포즈는 정말 편하다.

오늘의 깨달음.

쿼터니온과 오일러는 정해진 답이 없다. 그냥 모션마다 유리한 방식이 있으니 그에 맞춰서 키를 주자.

짠손 파파파파파파팟

강손

게임에 넣어봤더니 타이밍이 영 마음에 들지 않는다. 기획상 강펀치와 킥은 캐릭터마다 어느 것이 더 강한지에 대한 근소한 차이는 있지만 기본적으로 같다고 가정하고 제작하고 있다. 때문에 딜레이가 꽤 길어도 괜찮다고 생각했지만 정작 유니티에 넣어보니 중요모션은 10프레임 이내에 끝나야 자연스럽다. 짠손은 겨우 4프레임이다!

게다가 강손은 점프강손과 이미지가 너무 겹치는 감이 있다. 다시 만들어야 할 것 같다. 하지만 오늘은 타임오버. 내일 다시 제작해보자.

1.8

앨리스의 강베기 변경. 이 동작은 검기가 없으면 조금 빈약해 보인다.

쿼터니온과 오일러가 생각보다 많은 충돌을 일으킨다. 작업을 하다보니 중요관절에 오일러를 사용하는 경우는 생각보다 드물다. 그렇다고 또 모든 관절을 쿼터니온으로 바꾸자니 일이 커진다.

오퍼레이터가 필요하다.

그래서 만든 액션 초기화. 이 버튼의 기능은 새로운 액션을 추가하고 페이크유저로 바꾼 후, 중요관절에 현재 있는 그대로의 로테이션 모드 키를 넣어준다.코드자체는 chatGPT가 짜주니까 어렵지 않았는데, 몇가지 이유로 fcurve의 group이 지정되지 않는 문제가 있어서 이 원인을 찾느라 시간이 한참 걸렸다.

결국은 이거 하나밖에 못했다. 내일은 검기를 달아보자.

앨리스의 애니메이션 #1

12.29

타이밍을 재기 위한 러프 애니메이션 작업. 좋은 조작감을 위해서는 프레임이 생각보다도 더 적어야 한다는 결론을 얻었다.

턴동작 튀는 것은 왜 그런지 모르겠는데… 이론상 안그래야 하는데…

  • JumpReady는 2프레임
  • Crouch/Stand도 2프레임
  • Landing은 Crouch로 캔슬되어야 한다.
  • 상대방 너머로 점프했을 때 Landing -> Idle -> Turn의 상태를 거친다. Idle은 스킵되어야 한다.

실제 리소스를 적용하고 나니 점프높이가 너무 높아보여서 수정했다. 앨리스는 갑옷을 입었으니 조금 무거운 느낌의 점프를 주고 싶었던 것도 있으나 기본 점프높이가 너무 높아서 점프 시 얼굴을 가리는 현상이 마음에 들지 않았던 것이다.

이제 최고 높이에서도 얼굴을 가리지는 않는다.하지만 실제 완성본이라면 HP바가 가릴 예정.

상대방 너머로 점프했을 때 Landing -> Idle -> Turn의 상태를 거치는 문제는 Play()의 호출시기 문제였다. 여러가지 이유로 지금까지는 Play()를 LateUpdate()에서 호출하고 있었는데, 이 때문에 애니메이션이 1프레임 느리게 나와서 정보가 제대로 되었음에도 불구하고 한 프레임이 튀는 현상이 발생했던 것이다.

Landing 후 Crouch스킵은 보호프레임이 설정되어 있었다. 보호프레임은 타격이 일어나기 전에 애니메이션의 재생시간을 보장하기 위해 넣은 시스템이다. 데미지등의 강력한 외부요인이 없는 한 보호되게끔 코딩해 놓았다. 착지모션에 이걸 왜 넣어놨지…?

12.30

발차기모션을 만들던 도중 마스터의 회전이 불완전하게 움직이는 현상이 있어 이를 쿼터니온으로 변경했다. 그랬더니 각종 모션이 깨지는 현상이 발생

(좀비가 됐다!)

게다가 손의 IK-FK스위칭에서도 문제가 일어난다. 이는 키를 주지 않은 기능에 대해서는 기본값을 유지하는 블렌더 시스템의 특징때문이다. 작업에 앞서 규칙을 확실히 정하는 편이 좋겠다.

12.31

블렌더는 기본적으로 애니메이션을 위한 툴이기 때문에 모든 액션은 NLA에디터에 자동으로 삽입된다. 여기서 새로운 액션을 만들 경우, 반드시 Push Down으로 NLA에 등록을 해주어야 한다. 그렇지 않을 경우, 블렌더는 이 클립을 미사용클립으로 인지하고 가비지 컬렉터에 의해 다음 로딩 시 제거당한다. 영원히 지워진다는 이야기이다. 이를 피하려면 액션에 Fake-user를 켜주어야 한다.

저 방패모양이 fake-user. 가비지 컬렉터로부터 지킨다는 의미다. 블렌더에서 user는 데이터를 사용하는 주체를 말한다. 예를 들어 머티리얼 데이터는 모델링에서 사용된다. 3D데이터는 유기적으로 연결되어 있기 때문에, 이런 데이터 블럭들은 여기저기 쓰인다. fake-user는 말그대로 ‘쓰고 있는 주체가 있는 것처럼 간주해라.’라는 뜻이다. 그럼 가비지 컬렉터로부터 보호된다. 초보 시절엔 이 시스템을 이해못해서 하루종일 잡은 키를 날린 적도 있다. 이런 걸 보면 블렌더는 최적화에 신경을 굉장히 많이 쓰는 것을 알 수 있는데, 애니메이션은 좀 수정됐으면 좋겠다. 데이터가 큰 것도 아니면서…

오늘의 깨달음. Mark as Asset으로 등록해두면 Idle모션을 어셋으로 등록해둘 수가 있다. 이렇게 해두면 새로운 동작을 만들 때 Idle의 첫프레임을 붙여놓고 시작할 수가 있다.

충돌을 설정하기 위해 컬리전을 설치. 작업초반인데도 익스포트가 잦다.

컬리전박스 호환이 안되어 뱅가드가 생각보다 일찍 퇴장했다. 앨리스가 대신 맞기로 하자.

컬리전 세팅만 했는데 타임오버! 2023년의 마지막 밤작업은 이렇게 막을 내린다. 애가 방학이라 작업시간이 매우 쪼그라든 상태다. 병설 유치원은 방학이 2달이다! 앞으로 계속 별다른 작업은 힘들 것 같다.흑흑

1.1

새해엔 게임하느라 작업을 쉬었다. 새해 복 많이 받으세요!

1.2

타격감을 보기 위해 데미지 모션을 먼저 처리해야 할 필요가 있다. 그리고 이를 위해선 데미지 모션 리스트를 먼저 확정해야 한다. 여러가지 생각을 해보았지만 서서맞는 경우, 데미지의 강약과 머리,복부를 맞는 경우를 가정하기로 했다. 그리고 이것들의 더미 모션들을 먼저 제작한다.

오늘의 깨달음.

모션을 새로 만들 때 그냥 Fake-User로 모션을 보호하는 편이 PushDown보다 편하다. 이처럼 비슷한 모션을 만들 경우엔 더더욱 그렇다.

본격적인 애니메이션 제작에 앞서 타격을 먼저 붙여보자. 타이밍을 재는 것이 주 목적이므로 애니메이션의 퀄리티는 중요하지 않다. 예상보다 버그도 많고, 문제도 많다. 으으흐흑

충돌체크가 원활하지 않아서 한참을 헤멨다. 원인은 바로 Bounds클래스 내의 Intersect()메서드였다. 이 메서드는 박스가 충돌할 경우 True를 리턴하는 함수인데, Collider2D를 사용하는 지금은 Z의 계산을 하지 않아도 별 상관이 없는데 엉뚱하게 z를 계산하고 있었다. 아오 빡쳐!!! bounds라면 어차피 x,y2개뿐인데 z를 왜 계산해, 이놈들아…!!

Intersect()함수에서 z부분을 빼서 컬라이더용 함수를 따로 만들어야 한다.

bool IsCollision(BoxCollider2D c1, BoxCollider2D c2){

Bounds b1 = c1.bounds;
Bounds b2 = c2.bounds;
return b1.min.x <= b2.max.x && b1.max.x >= b2.min.x && b1.min.y <= b2.max.y && b1.max.y >= b2.min.y;
}

이제 문제없다.

1.3

기본 공격모션들의 러프한 모션들을 붙여 느낌을 보자. 그렇게 생동감넘치는 동작들은 아니지만, 기본적인 타이밍을 보기엔 부족함이 없다. 가까이 있을 때와 멀리 있을 때의 모션이 다르고, 앞으로 점프할 때와 제자리 점프의 모션 또한 다르다. 기본 공격 모션은 생각보다 많다.

스테이트는 예상치의 절반정도를 추가했을 뿐인데도 이 정도. 물량이 많아지면 몇가지 문제가 발생한다. 일단 익스포트가 꽤 오래걸린다. 툴을 자유로이 오가야 하는 입장에선 이런 것들이 꽤나 성가신 문제로 발전할 수 있다. 파일을 나누어야 한다.

처음엔 블렌더 파일을 나눌 생각이었는데, 그럴 필요가 없다. ARP의 액션매니저가 이를 대신해준다! ARP는 정말 돈값 이상을 한다. 블렌더로 게임제작을 위해선 반드시 구비해야 할 애드온이다.

오늘의 깨달음. 실제 모션을 만들 땐 공격하는 부위가 살짝 앞으로 오게 만들면 좋다. 이처럼 겹치는 걸 방지하기 위함