앨리스의 잡기

2.23

공중에서 점프해서 캐릭터끼리 맞닿을 시에 덜덜거리는 현상이 있다. 이것을 추적하기 위해 코드를 살피던 중, 충돌코드에서 유니티가 기본적으로 제공중인 Intersect()를 쓰는 코드를 발견했다. 오래 전에 이것이 다리의 충돌검사를 제대로 하지 못한데다, 불필요한 연산이 들어가 있어서 직접제작한 걸로 바꿨는데 공교롭게도 이것이 캐릭터를 뛰어넘을 때 도움이 되고 있었다. 연산을 제대로 하니 다리 충돌이 걸려 캐릭터를 못뛰어넘는다.

이론적으로 접근하자면 물론 충돌 박스가 작게 수정되는 것이 맞다.그런데, 가만… 충돌에 한해서 다리를 빼는 것이 더 괜찮은 플레이경험을 제공한다면, 그 쪽이 낫지 않을까?

foreach (BoxCollider2D player1Collider in player1FSM.bodyColliders)
{
if(player1Collider.name.Contains("leg")) continue;

foreach (BoxCollider2D player2Collider in player2FSM.bodyColliders)
{
if(player2Collider.name.Contains("leg")) continue;

이제 뛰어넘을 수 있다.

앨리스는 늘 그래왔다. 언제나 첫작업으로 쓰였기 때문에 많은 시행착오를 거쳐 완성하곤 했다. 이번에도 그러고 있다. 잡기 첫모션 제작 중. 오늘은 여기까지

2.24

잡기 1번은 완료. 방향키+강펀치로 발동한다. 어느 쪽으로 집어던질 지 결정할 수 있다.

2번의 구상은 좀 복잡하다. 한 팔로 멱살을 끌어당긴 후, 균형을 잃은 상대의 등 혹은 뒤통수를 돌아서 발로 차서 넘어뜨리고 등을 찌른다. 복잡하다! 구상대로 잘 될까… 이 작업만 며칠 걸릴 지도 모르겠다.

타이밍은 대충 이렇다. 이제 디테일 파보자….지만 오늘은 여기까지인가.

2.25

오늘의 깨달음. FK-IK를 오가는 애니메이션을 할 때엔 겹키를 주는 것보단, 그냥 해당키에서 각각 FK/IK스위치를 한 번씩 해주는 것이 더 효과적이다. 이렇게 되면 각각의 컨트롤러가 알맞게 보간되어 알아서 부드러운 애니메이션이 된다. 맥스-바이패드의 Plant Key를 사용하던 버릇 때문에 지금까지 겹키를 주는 방식을 택하고 있었는데 블렌더에서는 그럴 필요가 없을 듯? 확실히 적응하니 더 편하다.

..지만 그렇다고 하더라도 점프직후의 까치발을 위해선 겹키를 주어야 한다. 음.. 뭐 그렇다고 해도 이 정도면 품이 많이 드는 것이 아니라 괜찮다.

캐릭터 2명은 뷰포트에서는 꽤 느려서 풀 프레임으로 재생할 수가 없다. 때문에 솔리드 모드에서 전체 모션을 확인해야 한다. 오늘은 여기까지.

2.26

칼로 등을 찌르는 모션을 구현하기 위해서는 몇 가지 단계가 필요하다. 애초에 염두에 두긴 했으나 생각보다 더 귀찮은 작업인 것 같다. 먼저, 피격자가 등을 차인 후 앞으로 쓰러지는 모션은 분리해 제작되어야 한다. 이는 몇몇 기술이 머리를 쳐서 바닥에 처박힐 때 공용으로 사용될 것이다. (KOF의 료가 사용하는 수박깨기처럼) 그렇다면 필연적으로 일어나는 모션이 추가된다. 이를 DamageSlam, GetUpSlam으로 제작한다.

그 후엔 앨리스의 잡기 피격 모션으로 복사해서 이식해서 다른 모션과 이어지도록 제작해야 한다. 발차기 이후의 스테이트를 따로 쓸 수도 있겠으나, 그 어떤 게임적 요인으로 인해 위치가 정확하지 않을 가능성이 있다.

또한 화면 끝에서 기술을 사용할 경우, 발차기를 하는 순간에 필요한 거리만큼 밖으로 빼내주어야 한다. 잡기 세트 모션중에는 충돌체크를 하지 않기 때문에, 수동으로 밀어주어야 하는 것이다. 이 때 밀어주는 거리는 어느 정도 정형화되는 편이 좋다. 안그러면 위치가 튈테니까.

마지막으로 모든 세트 모션이 끝난 후, 제자리에 다시 독립된 개체로 누워있을 수 있도록 피격자의 위치를 교정해주어야 한다. 하지만 이 때까지도 피격자는 Caught모션일 것이다. 잡기는 타격자가 먼저 활동이 가능해지기 때문에 충돌 무시 플래그를 피격자에게 심어놨는지, 타격자에게 심어놨는지 조사해 봐야한다. 이것이 피격자라면 타격자로 바꾸자. 또한 스테이트에서 길이를 15프레임 정도 길게 설정해서 누워있는 대기시간을 주어야 한다. 현재 이것을 Length를 강제로 교정하는 식으로 처리해 놨는데 AdditionalLength같은 식으로 변경하는 쪽이 좋아보인다.

오늘의 깨달음. 차일드를 자주 바꾸는 본은 traj보단 그냥 부모없음.으로 설정하는 편이 애니메이션하기에 더 편하다. 주로 대각선 애니메이션을 할 때!

먼저 DamageSlam, GetUpSlam을 제작

피격자의 애니메이션 제작 중. 애니메이션 자체는 내일 마무리할 수 있을 것 같다.z

2.27

좌우를 와리가리하는 애니메이션을 제작하다보니 머리카락 앤젤링의 코드에 문제가 있는 것을 발견했다. 해당코드는 뷰에 따른 UV를 위아래로 움직이기 위해 바이탄젠트를 쓰고 있는데 좌우가 반전되면 방향도 바뀌는 문제가 있는 것이다. 게임은 로컬 스케일의 X값을 사용해서 캐릭터를 반전하고 있으니 이를 알아내어 곱하면 될 것이다. 이를 위해 챗GPT에게 의뢰하니, unity_ObjectToWorld라는 행렬을 이용하면 된다고 한다.

| r11  r12  r13  tx |
| r21 r22 r23 ty |
| r31 r32 r33 tz |
| 0 0 0 1 |

행렬의 대각선값(r11,r22,r33)은 스케일이다. 나머지는 회전값, 오른쪽 3열은 이동값을 기록한다. 따라서 [0].x를 쓰면 될 줄 알았는데…정작 해보니 변화가 없다…? 생각해 보니 그건 어디까지나 메쉬 오브젝트의 행렬이지, 게임오브젝트와는 관련이 없는 것도 같다. 그럼 수동으로 해 줄수밖에… CPU가 수고 좀 하자.

스케일팩터를 추가하고 방향이 변할 때마다 바꿔주어야 한다.

마참내! 앨리스의 잡기 완료. 코드를 또 한 번 신나게 리팩토링했다.
FSM코드만 1000줄이 넘어가지만 아직까지는 알아볼만 하다.

이제 닐리의 잡기로 넘어가자.

잡기 준비작업

2.19

작업의 방향성을 정하는데 많은 시간을 소요했다. 사실 그동안 계속 고민해오던 문제이긴 하다. 결과적으로 쉬운 방법과 어려운 방법이 있고, 양자택일을 해야 한다. 방향을 정하면 돌아가지 못한다. 쉬운 방법은 모든 잡기를 대략적으로 비슷하게 만드는 것이고, 어려운 방법은 잡기마다 세트 모션을 만드는 것이다.

세트 모션을 만들 경우 잡기 모션 하나당 모든 캐릭터에게 이를 당하는 모션을 추가해주어야 한다. 모든 캐릭터가 잡기를 가지고 있을 테니 그 수는 곱절로 늘어난다. 때문에 처음엔 이를 고려하지 않았는데, 쉬운 방법을 선택하자니 마음이 동하지 않았다. 그래서 스스로 재앙을 만들었다.

시작하기 전에 몇가지 확인이 필요하다. Link로 애니메이션 제어가 되는가?

안된다. 링크로 연결된 객체는 그 무엇도 제어할 수가 없다. 그렇다면 블렌더를 2개 켜놓고 애니메이션을 바꿔서 저장 후에 리프레시하는 방법을 사용해야 된다. 게다가 씬에 같은 파일을 링크할 수는 없다. 흐음.. 그렇다면 같은 캐릭터일 경우 작업용 파일을 복사해서 사용하고, 모션을 만든 후에 합쳐야 한다. 조금 귀찮게 됐다.

컬렉션을 링크하면 Scene탭에 인스펙터가 보인다. 여기서 새로고침을 해주면 저장한 모션으로 변경된다.

먼저 코드 구현을 위한 더미 모션을 만들자. 앨리스는 힘이 세다는 설정이므로 집어 던진다. 이 때 필요한 모션이 다음과 같다.

  • 앨리스 : GrapplingPunch (Kick을 눌러 잡으면 모션이 달라야 한다.)
  • 달래 : GrappledAlicePunch , DamageGrappledFlying(이 모션은 Knockdown으로 연결되어야 한다.)

데미지 모션은 잡기상황을 벗어났을 때 공용으로 사용할 모션이다. 잡기는 여러형태가 있을 수 있다. 예를 들어 백드롭을 하면 DamageGrappledBackdrop이 되어야 할 것이다. 여기까지 고려해서 모션명을 정해야 나중에 삽질이 적다. 파이썬을 제외한 변수나 리소스명은 낙타문자를 사용하고, 숫자를 사용할 땐 가독성을 위해 양 옆으로 언더바를 붙인다.(숫자는 대체로 중요한 정보이다!) 오래된 내 습관이다.

머리가 굳었는지 오랫만에 코드를 보니 정신이 아득해진다. 내일 하자…

2.20

잡기는 가까이 있을 때 방향을 정하고 펀치나 킥을 누르면 발동된다. 하지만 한 가지 의문이 생긴다. 만약 두 캐릭터가 동시에 잡기를 했다면? 이 경우 Update를 먼저 도는 쪽이 이기게 된다. 대체로 데이터가 먼저 만들어지는 1P일 것이다. 그렇다면 1P에게 조금이나마 유리한 부분이 생기게 된다. 유저가 이걸 확인할 길은 없다. 잡기는 딜레이가 없기 때문이다. 때문에 그냥 ‘아차, 내가 늦었구나.’라고 생각하게 되고, 게임은 그럭저럭 돌아갈 것이다.

하지만, 이건 분명히 불합리하다. 격투게임은 원래 1프레임차이로 명암이 갈린다. 그렇다면 잡기에도 명확한 기준이 필요하고, 동시에 잡았을 경우, 공격이 무산되어야 한다. 때문에 2가지 모션이 더 필요하다. 잡기를 시도하는 것과, 동시에 잡았을 때 실패하는 것

  • GrapplingTry
  • GrapplingFail

재료를 더 준비했으니 코딩을 해보자.

러프한 구현. 여엉차!

2.21

작업을 하다보니 잡기를 한 쪽과 당한 쪽의 코드명이 헛갈리는 경우가 많았다. 이에 잡는 쪽은 Grappling, 잡힌 쪽은 Caught로 바꿔쓰기로 했다.

잡기 테스트. 아휴… 생각보다 많은 부분을 뜯어고치고 있다.

2.22

캐릭터마다 잡기는 모두 넣을 예정이지만, 미래는 알 수가 없다. 어쨌거나 강펀치 혹은 킥을 누르면 잡기를 수행하는데 이 데이터가 없을 경우 일반 공격이 나가게 하는 처리가 필요하다. 그리고 이걸 하려면 스테이트 매니저를 캐릭터별로 분리해야 한다. 좀 더 먼 훗날의 일인 줄 알았는데, 생각보다 일찍 분리해야 한다.

앨리스의 설정을 담은 초기화 함수를 만든다. 기본 데이터 위에 캐릭터 별로 다른 데이터를 얹는 식이다. 스테이트 구조체는 정보가 많아서 이를 일일이 컨트롤하기는 힘들기 때문에, 필요한 데이터만 선별해서 바꿔주는 식이다. 잡히는 정보가 없다면 해당기술이 없는 걸로 간주하고 그냥 근접공격을 내보낸다.

잡기든 다른 공격이든 넘어졌다가 일어났을 때 바로 잡히면 안되기 때문에, 약간의 무적시간을 준다. 무적시간은 state에 귀속되어 있지만, GetUp스테이트만은 예외다. 이로서 공격자는 재공격이 불리하게 되고, 피격자는 반격을 노릴 수 있다.

동시에 잡았을 땐 그 누구도 이득을 얻지 말아야 한다.

더미모션을 넣어놨더니 ‘앗..아…’하는 애매한 마무리가 되어버렸다.

예정했던 잡기용 코드 작업은 끝났다. 하지만 프로그램 작업으로 넘어온 김에 노션에 써놨던 작업을 마무리 하고 넘어가도록 하자.

오로라의 애니메이션

2.12

명절이 끝났다. 다시 작업을 시작하자.

오로라의 대기자세는 고민이 많았다. 양손으로 가방끈을 잡고 있는 자세가 실루엣을 단순하게 만든다는 점 때문이었다. 하지만 가방이 주력인 캐릭터이기 때문에 이보다 어울리는 자세를 찾기가 힘들었고, 결국 초안대로 작업되었다. 애니메이션을 적용하니 예상보다 어색하지는 않다. 다행인 일이다.

오로라가 유독 프레임레이트가 안나온다. 본은 닐리가 더 많을텐데… 이것이 블렌더 4.0의 문제일지, 아니면 오로라의 문제인지는 지켜보도록 하자.

유니티로 컨버팅 완료. 이전에 기계팔 컨버팅을 위해 커스텀 본 세팅을 모두 해둔 상태였기 때문에, 큰 문제는 없었다.

머리카락 위로 보이는 눈썹 셰이더가 가장 잘 보이는 캐릭터가 아닐까.

키는 작은데 다리는 더 굵다.

2.13

오로라의 기본 애니메이션 완료. 우우.. 후드티의 리깅이 너무나 후지다. 그것도 문제지만, 실루엣 문제가 의외의 말썽을 일으킨다. 가방을 잡고 있는 팔이 덩치를 작게 만드는 바람에, 점프할 때 갑자기 덩치가 커지는 것처럼 느껴진다. 마치 목도리 도마뱀같이!

기본 모션에 시간을 좀 더 써보는 편이 좋겠다. 하지만 오늘은 여기까지

2.14

프레임 레이트가 잘 안나온다. 캡처가 제대로 안될 정도로 느리다. 블렌더는 죄가 없고, 오로라의 데이터가 무겁다. 그런데 그 이유를 잘 모르겠다. 분명 로봇팔은 고성능의 IK가 하나 더 달려있긴 하지만, 겨우 그것 때문에…?

보기와는 달리 잡기 캐릭이라 전반적으로 공격이 느려야 한다. 안그래 보이지만 실제로 해보면 꽤 답답.

2.15

오로라의 기본 공격 모션. 손이 하나만 나오면 느낌이 약한느낌이니 내일은 두개를 다 꺼내보자.

2.16

몸-> 얼굴을 때린다는 느낌으로 2타 가격.

앉아서 강손은 원래 이게 아니고, 웅크린 상태에서 로봇팔만 나가서 깍지를 낀 상태로 바닥을 치는 거였다. 그런데 예상외로 팔이 짧아서 깍지가 불가능한 게 아닌가. 계획이 틀어져서 ‘어떻게 하지…’ 라며 이것저것 움직여 보던 중에 나온 이상한 만세 자세를 만들어 놓고 일단 자러 갔는데, 다음 날 보니 이게 생뚱맞아 보이는 게 꽤 괜찮아 보였다. 그래서 그대로 확정지은 앉아 강손. 로봇팔은 양쪽이 다 나오는 것이 확실히 안정감도 있고 보기에도 좋아 보인다.

기계팔 제어가 생각보다 어렵고 시간이 오래걸린다. 생각해 보니 팔이 4개니까… 오래걸리는 것이 당연하다. 다리가 4개가 아닌 것이 어디냐… 싶기도

2.17

오토리그 프로엔 캐릭터 전체의 움직임을 제어하기 위한 c_traj이 있다. c_pos는 총 사령관이고, 그 아래 붙어서 전체적인 캐릭터의 위치를 조율하는 역할을 한다. 지금까진 이걸 사용하지 않았다. 필요한 경우가 없었던 것은 아니지만, 무기 본에 붙는 Child of 조건과의 상성이 좋지 않아 의도적으로 기피하고 있었다.(위치가 이상해진다.)

하지만 오로라의 경우 만세 포즈가 많아 대칭자세가 꽤 많은데, 이럴 경우 상당히 편리하다는 깨달음을 얻었다. 어차피 본의 일종이므로 Idle에 기본값으로 0을 넣어두고, 필요할 때 사용해서 깨지지 않으면 사용해도 된다. 엔진에도 잘 넘어가는 것을 확인했다.

점프킥 자세처럼 좌우 대칭모션에 사용하기 좋다.

오로라의 기본 공격모션 완료. 앞선 세 캐릭터는 제자리 점프킥의 모션이 달랐는데, 오로라는 달리 그럴 필요가 없어서 모션이 하나 적다.

이제 다 때렸으니 좀 맞자.

2.18

데미지 모션은 순간적으로 지나간다. 하지만 그 중에서도 정지 포즈에 신경을 써야 하는 모션이라면 바로 knockdown이다. 캐릭터가 누워있는 순간은 꽤 많다. 다리가 걸렸거나 KO됐을 때 캐릭터는 바닥에 눕는다.

애니메이션 중 바닥과 연관있는 애니메이션은 제법 난이도가 있지만 중요도는 낮은 편이다. 이렇게 바닥에 눕거나 튕기거나 일어서거나. 그렇다고 또 대충 만들면 티가 많이 난다. 아쉽게도 중력에 의한 물체의 움직임은 이미 우리 눈에 너무나 익숙하기 때문에, 모든 사람이 전문가적 시각을 갖추고 있기 때문이다. 들이는 공에 비해 보상이 적은 작업. 현업이라면 누군가는 이런 일을 해야 한다. 만약 내 일이 쉽다면, 누군가는 죽어가고 있는 것이다. 하지만 백수인 지금 이런 생각을 하는 것이 마치 전생의 일 같이 느껴진다. 백수 좋아~♬ 늘 새로워. 짜릿해.

오로라의 데미지 모션완료. 이로서 네 캐릭터의 기본 모션은 끝났다. 삽질을 여러차례 거쳐서인지, 오로라의 데미지 모션 작업은 작업시간이 좀 더 단축됐다. (하루만에 끝났다!) 데미지 모션에서 시간을 많이 잡아먹는 부분이 블렌더-유니티를 오가며 타격감을 보는 부분이었는데, 이 부분이 어느정도 공식이 정해지며 시간을 아낄 수 있었다.

이제 다음 단계로 넘어가자. 사실 FSM(Finite State Machine – 유한상태머신)을 제작하며 작업하지 않은 것이 하나 있다. 당시의 난 회사원과 백수의 중간 단계에 있었고 무언가 싱숭생숭한 기분 속에서 아트 작업으로 선회를 했었다. 하지만 이제는 작업을 해야 할 때가 온 것 같다. 바로 ‘잡기’다.

달래의 애니메이션 #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모션. 왼손잡이가 오른손잡이가 되는 마법.

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

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