앨리스의 2기 애니메이션 제작 #2

5.20

입력고장은 간단한 문제였다. 캐릭터를 강제로 미는 값이 있다면 방어로 인식하게 했는데, 이것이 대쉬와 값이 겹치며 내는 오류였다.

문제는 점점 정교해진다. 이번엔 충돌이 문제다. 현재 캐릭터는 빠른 속도로 지나가는 캐릭터를 막지 못한다. 대시할 때 한 프레임에 움직이는 이동량이 캐릭터를 넘어버리기 때문에, 두 캐릭터의 위치가 바뀌게 되는 현상이 있다. 이는 곧 벽체크에 걸려 다시 제자리로 돌아오긴 하나, 완성도가 떨어져 보이므로 수정해야 한다.

새벽에 이 문제를 3시간동안 살피다가 포기하고 잤는데, 자고 일어나니 10분만에 해결했다. 허탈해! 충돌이 문제가 아니었어!

프레임과 타이밍을 조절하고, 세부 조절이 끝나면 본격적으로 애니메이션을 만든다.

연계기가 들어가니 또다른 문제가 보인다. 검기의 셰이더 드라이버가 한 프레임 늦게 갱신됨에 따라, 연계시에 잘못된 정보를 보여준다.

업데이트를 한탐 늦게 하면 될 줄 알았는데, 예상대로 안되길래 그냥 모션 시작시에 검기를 숨겨서 물리적으로 해결했다. 마음에 드는 해결책은 아니지만…이걸 시간들여 해결할만한 가치가 있는가? 도 의문이긴 하다.

연계기 – 강베기인데, 다 만들어 실제로 써보니 그렇게 예쁘지도 않고, 효용성도 떨어져서 삭제. 오래걸렸는데…흑흑.

이로서 연계기의 형태는 좀 더 단순해진다.

A-A-A

A-A-B.

스톰프는 이펙트가 있어야 완성된다. 타격은 2번 일어나는데 맞으면 한 번만 맞는다. 하단이지만 발동도 느리기 때문에 방어데미지를 주는 용도

5.23

모든 초안은 쓰레기다. 소점프킥 모션을 수정.

본체 애니메이션이 끝난 후, 세컨더리 애니메이션까지 완료. 이제 너무 자잘한 건 신경쓰지 않게 된다.

초필은 2라운드당 한 번 정도 사용하게 디자인할 예정이지만, 정말로 극단적인 경우 둘이 동시에 초필을 발동할 수도 있을 것이다. 그럴 경우를 대비해서 코드를 수정해 준다.

자잘한 버그 수정까지 했으니 이제 이펙트로 넘어가보자.

앨리스의 2기 애니메이션 제작

5.16

애니메이션 제작 계획은 3기로 나뉜다.

  • 1기 : 지금까지 작업했던 기본이동+공격들
  • 2기 : 커맨드 기술과 그에 따른 데미지, 방어, 스턴등
  • 3기 : 승리 및 등장, 도발, 캐릭터 선택, 다이얼로그등의 연출 애니메이션

양은 1기가 가장 많은데 후반으로 갈수록 애니메이션의 디테일이 높아진다.

이제 어렴풋한 생각들을 구체화시켜야 한다. 일단 필요한 작업들에 대해 목록을 뽑자. 모든 일의 시작이다. 이 때 개발 코드명을 같이 설정하면 좋다. 공용모션에 관한 목록들을 먼저 설정해보자.

  • 방어 (Block)
  • 앉아서 방어(CrouchBlock)
  • 소점프킥(SmallJumpKick) : 커맨드 ↑K . 이것은 점프 공격 후 높은 확률로 하단 공격을 하는 플레이의 이지선다를 위한 것이다. 모든 캐릭터가 가지고 있으며, 점프 공격으로 분류되기 때문에 서서 막아야 한다.
  • 소점프킥 착지(SmallJumpKickLanding) : 소점프킥 후 착지모션이다. 밸런스상 강공격으로 분류해야 하기 때문에 모션을 따로 둔다.
  • 일직선 날아가기(DamageFlying) : 화면끝으로 일직선으로 날아가 부딪힌다.
  • 날아가 벽에 부딪히기(DamageFlyingWall) : 벽에 부딪혀 아래로 떨어진다.
  • 바닥에 엎드려 떨어지기(KnockDownFront) : 일어서기와 연계되려면 DamageSlam의 끝 모션과 같아야 한다.
  • 공중에서 바닥에 꽂히기(DamageSlamAir) : 밑으로 내리치는 공격을 했을 때의 데미지 모션이다.
  • SlamAir의 넉다운 모션(KnockdownSlam) : 이는 DamageSlam의 중간부분을 짤라쓰자.
  • 회전하며 맞기(DamageScrewCW) : 몇몇 공격은 상대를 회전시킨다. 시계방향으로 돈다.
  • 회전하며 맞기(DamageScrewCCW) : 반시계방향으로 돈다.
  • 기절(Stun) : 데미지가 누적됐을 경우 헤롱헤롱

주로 강한 공격에 관한 데미지 모션들이다. 다음은 스킬.

커맨드 기술을 2기 작업으로 잡아놓은 것은 기획을 못했기 때문이다. 앨리스는 1번캐릭터니까 아도겐,어류겐은 있어야지…싶었는데, 정작 계획하고 나니 그런 캐릭터들이 너무 많다! 때문에 앨리스는 장풍을 배제했다.

  • 3연참(AliceTripleSlash_01_A, AliceTripleSlash_01_B) : [↓→A or B] 앞으로 대쉬하며 공격, A,B는 대쉬거리의 차이. 이후 A,B 입력에 따라 연계기 형태가 바뀐다.
    • AliceTripleSlash_02_A : 짧고 약하게 공격. 01을 히트했다면 무조건 히트한다. 상단
    • AliceTripleSlash_02_B : 길고 강하게 공격. 상단
    • AliceTripleSlash_03_A : 짧고 약하게 공격. 02를 히트했다면 무조건 히트. 넉다운 된다.상단
    • AliceTripleSlash_03_B : 소점프 베기. 공중공격으로 분류된다.
    • AliceTripleSlash_03_B_Landing : 공격 후 딜레이.
  • 어류겐(AliceUpperSlash_A, AliceUpperSlash_B) : [→↓→A or B] 대공기. A, B는 점프높이의 차이. B의 경우 K를 눌러서 추가타를 넣을 수 있다. 상단
    • AliceUpperSlash_B_K: 추가타.
  • 발도장(AliceStomp) : [↓←K] 발을 굴러 땅을 진동시킨다. 하단
  • 매우 쎈 강베기(AliceBash) : [↓→↓→B] 초필. 하오마루의 그것. 막아도 아프다.

근사한 이름이 있었으면 좋겠다… 여튼 설정은 끝났고, 하나하나 제작해보도록 하자.

일단 가드부터.

소점프킥.

어류겐 러프.

5.17

대공기 후에 추가타를 맞으면 캐릭터는 수직 비행해야 한다. 이것의 이름에 Flying을 사용하려 했는데, 이것이 기존에 사용하던 잡기 후 날아가기와 겹친다. 따라서 기존의 Flying은 Throwing으로 바꾸고 Flying은 일직선 이동을 의미하도록 변경하는 편이 좋겠다.

이런 리팩토링 작업은 꽤 성가시지만, 문제가 너무 깊어지기 전에 해결하는 편이 나중을 위해 좋다.

어류겐 강공격후 발차기 연계 러프. 이걸 하나 하려고 Flying관련 스테이터스를 추가하고 카메라 흔들기를 구현…하고 나니 소점프킥이 고장났다.. 내일하자.

연계기 처리 리팩토리. 중복코드는 최대한 피하고 싶은데 마음처럼 깔끔하게 되지가 않는다. 선입력 때문에 키입력 시간과 스테이트 발동시간이 일치하지 않기 때문. 점점 코드에서 스파게티 맛이 난다. 흑흑

5.18

오늘의 깨달음. 익스포트 시 모션이름에 빈 칸이 있으면 데이터가 제대로 넘어가지 않는다.

앨리스의 필살기 러프 스케치. 아우. 타이밍 어려워! 조작도 어려워!

코드를 또 한 번 정리했다. 다행히 잘 돌아가는 것 같다.

필살기는 스테이트 데이터가 매우 복잡한 양상을 띈다. 내일은 필살기 나머지를 구현하고 타이밍을 맞추자.

5.19

발도장은 하단이다. 얘는 구현이 별 게 없다.

초필은 사실 넣을까 말까 많은 고민을 했다. 왜냐면 이게 조작이 어렵고, 연계기를 통한 뉴비학살 기술로 많이 쓰이기 때문이다. 때문에 진입장벽을 높이는 주원인이 되는데, 곰곰히 생각해보니 멀티를 구현할 것도 아닌데 이 화려함을 포기할 필요가 있을까? 싶어 그냥 넣기로 했다. 스파2로 시작했지만 결과적으로 KOF와 비슷해지고 있다.

내일은 초필을 맞았을 때의 스크류 데미지 처리, 그리고 방어를 구현해 보자.

5.20

맞았을 때 빙그르르. 예전 홍콩 느와르 영화에서 많이 보이던 맞기 동작이다. KOF의 료가 일격필살을 사용했을 때 데미지 모션이 꽤 인상적이었기 때문에 넣기로 했다.

방어는 꽤 어렵다. 오래전 짜 놓았던 코드 때문인지 작동은 되는데… 입력 조건을 어찌짜야할지 고민이다. 내일할까…

또 한 번 대규모 리팩토링. 그런데 또 체인콤보가 고장났다.

세컨더리 애니메이션 보강

5.14

타격 시 캐릭터는 잠깐 멈춘다. 이 때의 다이나믹 본은 많이 흐트러져 있기 때문에 그리 예쁘지가 않다. 특히 잡기의 경우, 사용자의 입력에 따라 캐릭터가 갑자기 워프하기 때문에 다이나믹본은 변화가 크다고 인식하고 엉뚱한 값을 적용해버린다.

이걸 잡아보자. 작업이 크기 때문에 일부만 작업해서 느낌을 보는 샘플 작업이 필요하다.

확실히 낫다. 영상으로 보면 큰 티가 안나지만, 이 작업의 최대장점은 스샷이 예쁘게 찍힌다는 것이다.

단점은 너무너무 귀찮다는 것.

앨리스는 닐리에 비하면 별로 할 게 없다. 쉬어가는 코스.

달래도 머리카락만 대충 맞춰주고 마무리

오로라는 머리가 짧아서 안해도 될 것 같으니 패스하자.

버그 픽스

5.13

작업을 하며 버그가 발견된다고 해도 바로 손보지는 않는다. 하던 작업을 중단하고 다른 작업에 손을 대는 것은 꽤나 피로한 일이다. 대신, 적어둔다. 그리고 나중에 한 번에 처리한다. 이는 생각을 한 분야로 집중할 수 있어 효율적이다.

장풍은 아직 본격적인 구현은 이르지만, 오래전 구현해둔 바가 있다. 하지만 중간에 추가된 시스템들이 많아 역시 리팩토링이 필요했다.

스파2를 기준으로 하기 때문에 장풍을 맞았을 땐 슬로우 모션이 적용된다. 생각해보니 대부분의 게임이 그렇다. 굳이 느려질 필요는 없는데… 전통인가? 전통이면 따라야지!

스샷을 찍고 나니 보이는, 바로 앞에서 쏘면 밀려나는 문제는 버그다. 적어두자.

삐죽이 문제를 해결하는 김에 잡기할 때의 히트 포인트문제도 고쳐두자. 기존까지는 잡기후 타격이 일어날 때, 히트포인트 갱신이 안돼서 지저분하게 삐죽이가 생겼다.

이제 히트 포인트 갱신으로 히트포인트와 삐죽이가 제대로 표시된다. 이펙트까지 붙이니 좀 더 아파보인다.

그 다음 작업. 캐릭터 별 히트컬러 분리도 완료. 이 컬러는 1P와 2P가 고정이다.

해적의 집 깃발도 움직여 주자. 그렇게 예쁘게 움직이진 않지만, 안움직이는 것보다야 낫다.

타격형 잡기의 때리는 위치에서 이펙트가 나오도록 개선.

플레이어2의 입력처리는 예정에 없었지만, 버그 픽스를 위해서 필요했다.

짠손대전. 리치깡패 닐리. 어…달래랑은 어떨까…

..?! 달래도 이긴다.

야호!

다음 작업은 세컨더리 애니메이션이 보강이다.

오로라의 세컨더리 애니메이션

5.9

으아아아. 생각보다 잘 안되는 머리카락 본.

앉을 때나 일어날 때 모션의 변화가 급격하다보니, 물리엔진이 이를 급격한 애니메이션으로 보고 본을 크게 움직이는 경우가 있는데, 지인이 ‘그렇다면 스테이트를 바꿀 때 초기화를 해주면 어떤가?’라는 아이디어를 줘서 적용해봤다.

앉을 땐 비교적 괜찮으므로, 일어설 때만 적용해봤다. 가슴은 여전히 흔들리게 하고 싶었으므로 가슴을 제외하고 나머지는 초기화. 오. 결과가 괜찮아보인다.

페이셜 작업. 영상편집은 할 줄 모르기 때문에 날 것 그대로 기록.

예쁘게 나온 컷을 기록

마참내! 끝났다! 목표했던 1차 마일스톤 작업의 끝은 여기다. 캐릭터 4개를 만들고 각각의 기초 공격 애니메이션과 이펙트, 잡기, 세컨더리 애니메이션 제작 시스템의 정립까지. 빌드해보자.

버그나지 마라.버그나지 마라.버그나지 마라.버그나지 마라.버그나지 마라.

예쁜 메세지

잘된다!

백업부터 하자. 집컴퓨터 옆에 있는 나스에 꾸역꾸역

달래의 세컨더리 애니메이션

5.5

달래는 닐리보다는 쉬울 것이다. 앨리스보다도 쉬울 것으로 예상한다.

지금까지 작업을 하며 했던 삽질들을 한 번 정리하고 넘어가도록 하자.

  • Flipped애니메이션들은 모든 정방향 애니메이션이 끝난 후에 제작하는 편이 좋다.
  • 본의 마디가 많을 때, 루트와 중간본의 애니메이션은 따로 제작하자. 물론 루트 적용해보고 잘 나오면 좋고.
  • 세컨더리가 필요한 부분에 대해서는 Idle에 초기값을 넣어둘 뿐, 애니메이션 하지 않는다.

달래의 이슈는 스커트다. 대부분의 문제가 치마에서 발생하는데, 3D는 원래 몸에 딱 달라붙는 옷을 표현하는 것이 어렵다. 조금만 어긋나도 뚫리고, 오차값을 너무 허용하면 순식간에 펑퍼짐해져서 테가 안난다.

이번에 세컨더리 애니메이션 작업을 하며 Shrink Wrap에 대한 걸 배웠다. 달래의 스커트에 응용할 수 있지 않을까?

….는 테스트 결과, 안된다. 애초에 Shrink Wrap이 완전하지 않기는 하다. 하지만 적어도, 이 제약조건은 충돌스크립트를 탄생시켰고, 이에 따라 수동 노가다의 길을 더 원만하게 해줄 것 같긴 하다. 따라서…

치마 본의 컨트롤러 제약은 삭제하고 일반적인 방법으로 대처할 수 있을 것 같다.

허나 이를 위해선 치마본 설계를 다시 하여야 한다. 기억이 가물가물한데… 여기서 세로 본은 컨트롤러일 뿐이고, 실제로 치마를 움직이는 것은 가로 본이다. 기존까진 2마디였는데, 닐리와 같이 3마디를 쓰자.

이미 앨리스보다 쉬울거라는 예상은 벗어난 것처럼 보인다. 차근차근 웨이팅해보자.

치마본의 스케일에 사용된 드라이버는 상당히 복잡하다. skirt_scaler에 할당된 저 값들은 대체 무엇을 의미하더라….

def skirt_scaler(z, x, y, front, side, back, level, limit):

코드를 봐도 모르겠네?! 한 분야를 너무 깊숙히 들어가면 이런 코드가 나온다…

5.6

코드를 건들수록 망가지는 것 같아서 다시 롤백했다. 과거의 나를 믿어야 한다.

어디까지 다이나믹 본으로 돌려야 할까? 를 고민하다가 루트본만 애니메이션을 하는 쪽으로 가닥을 잡았다. 그런데 잠깐… 닐리도 이렇게 하면 다이나믹본을 사용할 수 있지 않을까?

사실 문제가 되는 모션들은 바로 이런 것이었다. 사정없이 깨지고 뚫리는 것이 싫어서 수동노가다를 선택했던 것인데, stiffness값을 올려주니 이런 부분들이 많이 상쇄되는 것을 발견했다.

엉덩이 부분이 뚫리는 것은 컬라이더를 조금 보강하면 될 것이다. 필요한 경우, 애니메이션 이벤트에서 동적으로 설정해줄 수도 있을 것 같다. 다이나믹본은 기존의 애니메이션에 물리계산을 덧붙인다. 그렇다는 것은 의도적인 천의 모양도 잡아줄 수 있다는 이야기이다. 생각보다 더 좋은 것 같다. 지금까지 난 뭘 한거지…흑흑

과감히 노선을 틀어보자. 달래를 중단하고 다시 닐리로

5.8

닐리와 앨리스의 작업을 해결했으므로 다시 이어서 해보자.

가슴본에 저고리 고름이 달린 형태라 애를 좀 먹었는데, 다이나믹본은 본에 본을 달았을 경우 exclusion을 통해 자식본을 계산에서 제외해도 작동이 안된다. 이유는 모르겠지만, 물리계산에 필수적인 end본 계산부분에서 뭔가 오류가 있거나, 아니면 원래 그렇게 사용하는 것이 아니거나.

이럴 경우 똑같은 본을 복사해서 해당 본의 자식으로 달아주고, 그 본을 연산에서 제외시키면 된다. 이 과정에서 사본의 본 움직임을 원본과 똑같이 하는 Constraint도 적용해보았는데, 작동되지 않는다. 애니메이션 키만 따라가는 모양. 혹은 Update()시점의 차이일지도 모른다. 뭐든 안된다. 어차피 더 좋은 방법을 알았으니 쓸 필요가 없다.

아직은 순조롭게 진행 중. 세컨더리 애니메이션의 대부분을 다이나믹 본에 의지함으로서 그동안 만들었던 애드온의 기능 중 많은 기능이 쓸모없어졌다. 오로라까지 작업한 이후에 쳐낼껀 쳐내도록 하자.

5.9

캐릭터가 앞으로 이동할 때 머리카락이 캐릭터를 가린다. 아이고, 예쁜 얼굴을 가리면 어떡하니. 해결방법을 찾아보자.

컬라이더를 조금 앞으로 빼주는 것으로 해결. 그렇게 예쁘지는 않은 것 같지만… 그래도 가성비가 좋은 방법이다.

입셰이더에는 각도에 따라 입이 돌아가는 코드가 들어가 있다. 난 입을 그릴 때, 특히 옆모습을 그릴 때 얼굴 옆에 그리는 습관이 있기 때문에 이런 코드를 넣은 것이다. 그런데 이것이 오작동해서 입이 비뚤게 보이는 버그가 있었다.

// 뷰에 따른 오프셋 계산. 0.04는 임의의 속도.
float3 leftWS = normalize(TransformObjectToWorld(float3(1,0,0)));
float3 view = _WorldSpaceCameraPos.xyz - OUT.positionWS.xyz; 
float3 V = normalize(float3(view.x, 0, view.z));
offset.x += dot(leftWS, V) * 0.04;

이것이 문제의 코드. 원리는 오른쪽과 카메라를 Dot시켜 나오는 값을 더한 것. 그런데 leftWS의 벡터를 위치로 계산하고 있는 것이 문제였다. 셰이더에서 벡터를 다룰 때, 위치인가? 방향인가?는 계산방법이 조금 다르다. 복잡한 건 모르겠으니 그냥 유니티에서 제공해주는 걸 사용하면 된다. 따라서 이 코드는 이렇게 수정되어야 한다.

// 뷰에 따른 오프셋 계산. 0.04는 임의의 속도.
float3 leftWS = normalize(TransformObjectToWorldDir(float3(1,0,0)));
float3 view = _WorldSpaceCameraPos.xyz - OUT.positionWS.xyz; 
float3 V = normalize(float3(view.x, 0, view.z));
offset.x += dot(leftWS, V) * 0.04;

이제 정상작동하는 것을 확인할 수 있다.

달래가 은근 달린 것이 많다 보니 타격등에서 캐릭터경직이 일어날 때 다이나믹본이 움직이는 것이 꽤 거슬린다. 그래서 경직중엔 업데이트가 되지 않도록 수정했는데, 이렇게 되니 세컨더리본들의 움직임이 초기화되기 때문에 자연스럽게 보이기 위해 맞을 때 세컨더리본을 ‘예쁘게’수정해 주어야 한다. 내일은 이걸 해보자.

맞을 때 세컨더리본을 수정하기 위해선 꽤나 많은 품이 드니까 다이나믹본 코드를 수정해보자. 그런데 코드에 타임스케일을 곱해주면 오류가 난다. 하지만 변수를 별도로 할당해서 처리하면 오류가 나지 않는다. 왜지…?!

뭐 일단 작동하니까 넘어가도록 하자.

닐리의 세컨더리 애니메이션 #3

5.7

난 스프링본에 대해 부정적이었다. 스프링본 특유의 달랑거리는 느낌이 싫었고, 충돌이 항상 말썽을 일으키기도 했기 때문이다. 무엇보다도 본 움직임의 제어권을 시스템에 빼앗기는 것이 싫었다. 키를 원하는대로 움직일 수 없다면, 결국은 언젠가 문제가 생긴다. 하지만 다이나믹본은 키애니메이션위에 물리적인 움직임이 블렌딩된다. 이럴 수가! 이걸 진작에 알았더라면, 시간을 아주 많이 절약할 수 있었을텐데!

다이나믹본은 캐릭터의 움직임에 따른 운동량을 계산해준다. 하지만 기본적으로는 스프링이기 때문에, 원심력과 중력을 계산하지는 못한다. 엄밀히는 중력 계산을 할 수 있지만, 닐리가 상대를 들어올렸을 때처럼 특이한 상황에만 중력이 적용되어야 하기에, 의도적으로 연출된 움직임을 제어하려면 키애니메이션이 편하다.

그렇다면, 할 일은 원심력과 중력만 적용된 데이터를 유니티에 넘기는 것이다. 해보자.

바닥에 드리워지는 옷자락의 표현. 플랜 콜라이더는 별 기대 안했는데 예상 외의 괜찮은 퀄리티를 보여준다.

움직이는 게 많으니 뭔가 좀 어지럽긴한데, 제작이 느무 쉽다! 달래도 이렇게 해보자.

닐리의 세컨더리 애니메이션 #2

4.29

땅에 끌리는 로브자락을 위해 Floor제약조건을 시도했지만 실패. Floor는 이동값만 제약이 걸린다. 궁여지책으로 바닥에 충돌박스를 만들어서 충돌을 사용했는데, 생각보단 결과가 괜찮다. 다만, 덜덜 떨리는 애니메이션은 피할 수 없다. 너무 많은 시간을 소요하고 있기 때문에 어느 정도 선에서 타협을 보아야 할 것 같다.

오늘의 고민은 이 자세에서 모자를 떨어뜨려야 하나, 말아야 하나.(중요한 것은 그게 아니겠지만서도…)

끝판왕다운 면모를 보이고 있는 닐리. 아직 절반도 안끝났다.

아이고.. 되다. 다이나믹 본 알아보자…

개인계정으로는 구입안해놨었네..?! 일단 구입

테스트삼아 로브에만 적용. 음. 생각보다 충돌을 잘 못거른다.

그럼 지금까지 했던 로브의 애니메이션을 적용해 보자.

다소 딱딱한 느낌이 들긴 하지만, 역시 이 쪽으로 해야 한다는 느낌…

잠깐 한눈을 팔아봤는데 역시 안될 것 같다. 흑흑

4.30

벌써 4월의 끝인가…. 시간 참 빠르구나. 닐리는 정-말 공이 많이 들어간다. 내일은 좀 많이 진행할 수 있기를

5.1

몇 번을 뒤엎었는지 모르겠다. 분명 내가 만든 툴인데 스스로 툴에 익숙치가 않아서 괜찮은 수치를 얻기까지 시행착오가 길었다. 모든 원인은 루트 애니메이션을 모든 본에 재활용하려는 욕심에서 비롯되었다.

루트는 보통 머리, 혹은 허리에 달려있다. 이 말은 세컨더리 본의 부모와 자식본의 회전값이 현저하게 다르다는 걸 뜻한다. 이 툴을 제대로 사용하려면, 루트와 차일드본을 분리해서 애니메이션하여야 한다. 생각해보면 당연한 이야기인데, 왜 이걸 깨닫지 못했을까!

어쨌거나 지금은 별다른 시행착오 없이 애니메이션을 할 수 있게 됐다. 이제 다시 달려보자.

5.2

디버깅용으로 캐릭터를 실시간으로 바꿔보려고 삽질을 하다가 실패하고 롤백. 생각보다 얽혀있는게 많다. 괜히 시간만 버렸네.

우여곡절 끝에 1차 제작은 끝났지만, 퇴고를 거쳐야 한다. 이 작업이 또 한참이다. 흐아…

착지 모션은 앨리스에게 별로 중요한 모션이 아니었지만 닐리는 중요할 것 같다. 그냥 그럴 것 같다.

초반에 작업했던 앞머리가 마음에 안드는 경우가 많다. 계속 수정 중. 몇 번이나 고쳤을까…

5.3

가슴의 애니메이션을 수정하던 중 문득 떠오른 생각. 대부분의 물리애니메이션의 문제는 충돌에서 일어난다. 그렇다면 충돌이 필요없는 본의 애니메이션은 물리를 사용해도 되는 것 아닌가…?!

그..그렇다. 다이나믹본은 이걸 위해 만들어진 것이로구나! 마찬가지로 앨리스의 머리도 처리할 수 있을 것 같다.

5.4

닐리의 세컨더리 애니메이션 완료. 모자와 가슴부분의 애니메이션은 다이나믹 본으로, 나머지는 수동으로 키를 잡았다. 정말 힘들었던 작업이었다. 아휴…다시 안보면 좋겠는데, 아직 애니가 많이 남았지…

뒷 일은 나중에 생각하고 일단 달래로 넘어가도록 하자.

닐리의 세컨더리 애니메이션 #1

4.23

앨리스는 튜토리얼에 불과했다. 튜토리얼 끝나자마자 바로 끝판왕이다.닐리의 세컨더리 본은 지금까지 제작했던 모든 캐릭터를 통틀어 가장 많으며 앞으로도 그럴 것 같다. 차근차근 진행해보도록 하자.

어려움은 항상 충돌에서 온다. 그런데 그 어려움이 예상했던 부위가 아니었으니…

머리카락이 가슴에 묻힌다… 가슴이 작으면 머리카락을 살짝 앞으로 빼기만 하면 될 것이지만, 그것이 안된다.품이 꽤 들어간다.

그리고 이걸 위해 또 애드온을 개량. 차일드 본 교정은 부모본을 위로 올렸을 경우, 자식본의 회전값이 너무 커지는 것을 막기 위함이다. 예를 들어 부모를 5도 돌려줬다면 자식본은 -5도를 해준다. 반복키 자동교정은 대기처럼 루프애니메이션을 만들 때 수정한 프레임을 기준으로 양쪽에 재생시간만큼의 키를 넣어서 루프키를 자동으로 생성해주는 기능이다.

이로서 대기애니메이션 완성. 코트의 칼라가 묻히는 것이 좀 아쉬운데, 들어봤더니 더 이상해서 그냥 냅두기로.

작업 순서가 앨리스와는 조금 다르다. 치마의 뚫림이 중요했던 앨리스는 충돌체크를 많이 이용했지만, 닐리는 그것보단 그냥 회전 더하기를 많이 사용하게 된다. 툴이 없었다면 힘들었을 작업이긴 하지만, 툴을 사용해도 꽤나 시간이 걸린다.

4.25

닐리의 로브가 워낙 커서 작업의 덩어리가 커지니, 디테일이 좀 더 필요했다. 이로 인해 부족한 기능을 추가했다. 행렬연산은 건들기 싫지만, 원하는 기능을 위해 기꺼이 두통을 감수해야 한다.

이제 회전값은 로컬/월드 혹은 섞어서 작업할 수 있다.

하지만 그렇다고 작업이 쉬워지지는 않았다는 후문.

머리카락은 상대적으로 쉽다. 모양도 예쁘게 잘 나오는 것 같고.

결국 또 기능을 추가. 그룹본을 통째로 위로 올리는 기능과, 중간에 끼인 본의 회전값을 보간하는 기능이다.

4.26

큰 로브의 말단부는 다소 독립적으로 움직인다고 보아야 한다. 이를 위해 통일된 키복사로는 한계가 있다는 사실을 절감하고 인덱싱 기준으로 중간부터 키를 물려주는 기능을 만들었다.

옵션은 하나지만, 구현이 꽤 힘들었다.

닐리의 로브는 몸에 가까운 부분일수록 경직되어 움직여야 하고 말단부로 갈수록 좀 더 자유로운 움직임을 보여야 한다. 보다 섬세한 컨트롤이 필요한 것이다. 이를 위해 추가한 기능이다. 다만 이것은 키 인덱싱을 기준으로 하기 때문에 몇 가지 제약조건이 있다.

  • 키를 물려줄 때 간격축소와 보간비율을 0으로 놓고 사용할 것
  • 중간에 임의의 키를 넣지 않을 것

4.27

마침내 작업에 불편한 점이 없다. 작업의 퀄리티는 무수한 수정에서 나오므로 툴의 편의성은 매우 중요하다고 할 수 있다.

모든 초안은 쓰레기다. – 헤밍 웨이

4.28

지인 몇 명이 내게 왜 물리를 사용하지 않느냐고 물었다. 그럴 때마다 원하는 움직임을 내기 힘들다고 대답했지만, 손으로 작업하자니 너무나 품이 많이 드는 건 사실이다. 지금이라도 갈아탈까… 흑흑

앨리스의 세컨더리 애니메이션 #4

4.20

치마의 애니메이션이 너무 찰랑거리는 느낌이 있어서 수정했다. 실제 교복 치마는 좀 더 뻣뻣한 재질을 가지므로, 말단부의 본 애니메이션 좀 더 약한 느낌이어야 한다. 그리 눈에 띄지는 않는 작업이지만, 안해두면 계속해서 거슬릴 것이므로 확실히 해두도록 하자.

이제 페이셜 애니메이션을 해야 할 시간이다. 몇몇 입이 그 전부터 마음에 들지 않았기 때문에 이를 고치는 일부터 시작해 보자. 입의 굴곡을 지나치게 살리는 것은 마치 ‘도라에몽’에 나오는 캐릭터처럼 보이기 때문에 꽤 올드해 보인다는 느낌을 받는다. 이를 단순하게 고치고, 다듬는다.

애니를 하다가 간헐적으로 나오는 이런 포즈들이 꽤 마음에 든다.

모션들이 짧기에 페이셜은 어렵지 않다. 다음 작업으로 넘어가자.

다음은 충돌 박스를 맞추는 일이다. 지금까지는 충돌박스가 움직이지 않았다.(그런데 놀랍게도 크게 어색하지 않다.) 하늘색박스는 바디, 노란색 박스는 어택박스다. 바디는 머리/몸통/다리로 나뉘어지고, 다리는 점프 시에 충돌체크를 하지 않는다. 이렇게 되면 머리는 사실상 별로 쓸 일이 없는데, 캡콤이 그렇게 해서 무지성으로 따라했다(…) 사실 등빨이 넓은 캐릭터라면 이게 의미가 있을 것 같은데 여캐밖에 없다 보니 이게 그렇게 쓸모가 있을 것 같지는 않지만… 뭔가 이유가 있겠지.

모션에

정작 작업을 하려 보니 심히 귀찮다… 자동화할 수 있지 않을까.

이미 박스는 처음부터 1m x 1m로 규격화 해 놓은 상태다. 이는 유니티로 넘어갔을 때 컬리전박스를 연동시키기 위함이다. 머리는 조건이 명확하다. 몸통도 비교적 괜찮다. 하지만 다리가 애매…하다. 될 것 같기도 하고, 안될 것 같기도 하다.

다리는 예상대로 잘 안된다. 그냥 수동 노가다 해줄수밖에 없나…

4.21

블렌더로 스크립트를 짜고 있노라니, 문득 드는 생각이 있었다. 컬리전 박스를 자동화 해줄 거라면, 그냥 실시간으로 처리해도 되지 않나…? 어택 컬라이더는 검기의 위치가 불안정해서 불가능하지만, 바디컬라이더라면 가능하지 않을까?

그래서 빠르게 러프하게 코드를 짜본 결과

…오? 되겠다. 이건

일단 구현까지는 했는데, 코드가 너무 지저분하다. 정리를 해야 한다.

4.21

코드를 구현하다가 일이 커졌다. 컬리전만 건드리려고 했던 건데, 전체적인 코드를 리팩토링 하게 됐다.

충돌을 정확히 계산하기 위해서는 게임매니저 – 캐릭터순으로 업데이트가 돌아야 했다. 현재는 게임매니저 아래에 캐릭터가 붙어있으므로, 이를 확신할 수 있는 정보가 필요해서 챗GPT에게 물어봤는데, 전혀 뜻밖의 힌트를 주었다. 업데이트를 명시적으로 관리하라는 내용. 그렇다! 업데이트를 왜 중앙관리할 생각을 못했지..?!

지금까지는 Update()의 순서가 뒤죽박죽이었다. 이를 게임매니저에 몰아준다. 컬라이더를 시스템에서 생성하도록 바꾸고, 발사체등의 외부요인이 캐릭터의 스테이트를 바꿀 수 있으니 LateUpdate에서 최종적으로 처리해준다. 깔끔하다! 이렇게 되면 최종 판정은 현재 기준으로 발사체-커맨드-잡기-데미지 순으로 처리된다. 잡기에 성공해도 타격이 들어왔으면 맞는다. 물론 이를 바꿀 수도 있다. 판정이 항상 애매했는데, 정리하니 한결 나은 느낌이다.

그런데…사이드이펙트가 굉-장하다! 버그 투성이.. 한동안은 이걸 잡아야할 것 같다.

리팩토링 완료! 생각보단 일찍 끝났다. 이제 다시 세컨더리 애니메이션에 힘써보자.

4.23

마참내! 앨리스의 세컨더리 애니메이션 완료.

바겉으로 변한 건 없어 보이는데 내부적으로 꽤 많이 바뀌었다. 충돌체크를 위해 무려 4번이나 검사하던 로직을 한 번으로 줄이고, 충돌체들을 본 기준으로 자동 생성한다. 다만 어택 컬라이더는 기존방식을 그대로 쓴다. 검기등의 공격범위는 정형화할 수 없기 때문이다.

격투게임이니 모션의 대부분이 공격일 것 같지만, 그것보단 데미지 모션이 더 많다. 잘 때리는 것보다 잘 맞는 게 중요하기 때문이다. 어쨌거나 고생한 보람이 있기를.

이제 끝판왕(튜토리얼 깨고 나니 바로 끝판왕) 닐리의 세컨더리 애니메이션으로 넘어가도록 하자.