유니티의 셰이더는 프로퍼티의 이름이 변하면 정보가 초기화된다. 때문에 애써 맞춰놓은 색상정보가 날아가기 쉽다. 원론적으로 이야기하자면 프로퍼티의 이름이 변하면 안되지만, 개발하며 어디 그게 쉬운 일인가. 이름으로 판독하는 처리가 얼마나 많은데.
때문에 나중에 닥쳐올 불행을 미리 대비하는 마음으로 레벨데이터 매니저를 새로 만들었다. 씬의 번호에 따라 미리 세팅된 조명과 먼지의 색정보등을 넣어주는 방식이다.
하지만 작업을 하고 나니 문제가 또 있는데, 셰이더가 늘어난다…! 별로 바람직하지가 않다. 프로퍼티로 구분하면 안될 것 같고, 파티클이름으로 구분해야 할 것 같다. 그럼 파티클을 만들 때마다 이름에 신경써야 하잖아…싶었는데 별수가 없다. 다시 되돌리자.
많은 고민 끝에 배경과의 호환을 위해 파티클의 게임오브젝트에 이름을 예약어로 사용하기로 했다. dust, stratum, soil, crack의 이름은 예약어로 사용된다. 리소스의 이름엔 항상 앞에 대문자를 붙이는 규칙이 있으니, 원칙적으로는 충돌하지 않는다. 그 외 HDR로 지정된 컬러프로퍼티엔 리니어변환을 해주어야 한다. 그런데 이게 정확하지가 않다… 이에 대해 조금 조사를 했는데 최종 화면에 나오는 컬러를 구하는 법은 톤매핑까지 거치며 매우 복잡해지는 것 같다. 뭐 그렇게 중요한 것은 아니고 비슷하게는 나오니, 넘어가기로 하자.
이제 스테이지별로 이펙트가 다른 색깔로 표현된다.
머티리얼을 정리하고, 발도장 이펙트도 완료…했는데 너무 후져서 사거리 좀 늘려야 할 듯
5.29
아휴. 안끝나…
어류겐할 때 검기 모양이 동그란게 안어울려서 셰이더 로직을 수정하자.
하고 싶은 걸 해봤는데 별로 안예쁘다…되돌리자.
요 기술엔 둥그런 먼지를 추가.
공중에서 Slam데미지를 맞을 경우의 처리가 되어있지 않아서 처리했다.
데미지 모션이 정말 많다. 포스트는 이펙트 작업인데, RnD작업이 훨씬 더 많아.
5.30
이래저래 삽질이 많았던 작업프로세스는 점차 분명해져간다. 모든 문제는 결국 어떤 방향으로든 해결되기 마련이다. 그렇다면 이 쯤에서 효율성에 대해 한 번 더 고민을 해보자.
지금은 이펙트를 Left/Right를 분리해 만들고 있다. 파티클시스템은 단순히 스케일-1로 해결되지 않는 경우가 많기 때문이다. 이거… 정말 안될까?
스케일을 좌우반전했을 때, 문제가 되는 부분은 파티클이미터가 기울어져 있는 경우이다. 이것은 트랜스폼이 아니고 이미터의 정보이기 때문이다. 그럼 트랜스폼을 기울이면 될 것 아닌가?
…는 전혀 엉뚱한 값이 튀어나온다. 안되나 보다.
위치는 반전이 된다. 그렇다면 기울어져 있는 이미터의 각도만 바꿔주면 되는 것 아닐까?
이미지를 바꿔보니 문제가 하나 더 있다. 이미지는 Flip되어야 한다. 일단 여기까지 적용가능 여부를 확인해보자.
오? 일단 요기까지는 작동한다. 시운전 끝났으니까 실전에 적용해보자.
2시간 가까이 시도했…지만, 실패했다. 고려할 게 너무 많다. 그렇다고 조건을 줄이면 이펙트 제작에 제약이 많아진다. 이거 정말 안되네. 에이…
오늘의 깨달음. 프로퍼티의 HDR은 단순히 숫자를 1이상 쓸 수 있도록 해주는 것이 아니다. Color프로퍼티를 좀 일원화시켜보고자 이를 적용해봤는데, 그냥 컬러는 톤매핑을 거치지 않은 러프한 색을 내보낸다.
방어 이펙트도 작업완료. 맞은 후엔 배우는 것이 있다.
5.31
일단 이렇게 앨리스의 이펙트를 완료. 파란색 머리는 2P가 헛갈려서 바꿔놓은 것이다.
이펙트 시스템을 구축하며 헤집어 놓은 코드들 때문에 버그가 많이 쌓였다. 이를 한 번 정리하고 가는 편이 좋아보인다.
먼저 기존의 이펙트를 조금 손보아야 한다. 먼지 이펙트는 지금까지 무언가 2%부족한 느낌이 있어서 바닥과의 연결부가 되는 이펙트를 추가하자. 원래는 캐릭터처럼 뒤쪽에 그림자를 뿌려볼 생각이었는데, 파티클이 머티리얼을 1개밖에 받지 못한다. 그래서 셰이더를 개조해 한 번에 2번을 그릴 수 있는 2pass셰이더로 만들었더니, 이번엔 또 두번째 패스에서 커스텀 데이터를 받지 못한다. 옘병!
별 수 없이 아랫부분에 그림자스러운 그라데이션을 약간 주고, 점프할 때 ‘팟!’하는 느낌의 쇼크이펙트를 추가하자. 이것은 시간으로 따지면 0.2초 정도 되는데, 이 짧은 순간의 유무가 완성도에 상당한 영향을 끼친다.
그리고 이 결론을 얻기까지 저녁 작업 시간을 모두 할애했다….나머지는 내일
스샷찍고 나니 위치가 좀 안맞는다…
이제 먼지는 된 것 같고,
파티클은 좀 더 작은 입자를 추가.
기존 작업 수정은 끝났고, 해야 할 것들에 대해서 정리해 보자.
공용 이펙트:
Grappling – 잡았을 때.
DustDamageSlam – 내리꽂기 공격을 당했을 때. (돌이 튀어야 한다.)
DamagePush – 데미지를 받고 크게 밀릴 때
Block – 방어했을 때
앨리스 이펙트
AliceCrouchKickDust – 둥글게 땅을 훑는 스타일의 먼지
AliceCrouchPunchHeavyDust
AliceTripleAttack_Dust_01
AliceTripleAttack_Dust_02 : 01과 같은데 좀 더 길다.
AliceUpperSlash
AliceStomp
AliceBash
그런데 이펙트의 위치를 어떻게 잡을 것인가? 결국은 데이터가 필요하다. 먼저 애니메이션 이벤트리스너에 Effect()를 추가하고, 여기에 데이터문자열을 건네준다. 데이터는 스트링과 구조체의 딕셔너리로 이루어진다.
effectData["SuperAttack"] = new EffectDataStruct{
prefabString = "SuperAttack",
followCharacterDirection = true,
};
effectData["DustLanding"] = new EffectDataStruct{
prefabString = "DustLanding",
};
쓰고 나니 현재 열거형으로 사용하고 있는 State도 딕셔너리로 처리하면 편하지 않았을까. 싶긴 한데, 속도면에선 그냥 열거형에 접근하는 쪽이 아무래도 빠를 것 같다. (업데이트에서 정말 뻔질나게 찾으니까…)
이로서 애니메이션 이벤트에서 이펙트를 부를 수 있게 됐다. 이걸 위해 흩어져 있던 이펙트코드를 한 데 모아 처리하는 정리작업을 병행했다. 그 와중에 버그가 있어 그걸 추적하느라 시간이 좀 더 걸렸다.
5.26
잡기이펙트는 순간 삐죽한 웨이브가 둥글게 회전하는 형태로 만들고 싶다. 이를 구현하려면 먼저 셰이더를 개발해야 한다.
대강 이런 느낌이다. 파티클에 입히자.
적용하기 위해선 코드를 수정해야 한다.
..가 버그를 안내려면 데이터를 등록해야 한다.
…를 정확한 위치에 뿌리려면 본의 위치를 참조해야 하므로 애니메이션을 수정해서 다시 익스포트를 해준다.
이제 적용됐다. 하루가 다 갔다. 아이고.
5.27
글 제목은 ‘앨리스의 이펙트’인데 아직도 공용이펙트만 작업중이다. 그런데 앨리스는 늘 그랬다. 그래서 가장 애정이 가는 캐릭터이기도 하다.
이제 내리 꽂혔을 때의 데미지 이펙트를 만들어보자. 땅이 갈라지며 조금 튀어나오면 좋겠다. 파티클로 사용하기 위해 치즈조각을 하나 모델링하자.
갈라지는 지형은 배경마다 다르다. 이를 위해 바닥과 지층을 구분해 칠할 것이다. 잠깐 나오고 사라질 애니까 텍스처까지는 좀 거하고 버텍스 컬러를 써서 구분하도록 하자.
이제 여기에 사용할 셰이더를 만들어주자. 솔리드 셰이더를 간단하게 축소하면 될 것이다.
여기저기 각이 져서 간단히 NdotL만 해도 예쁘다.
그렇게 완성된 이미지. 이 이펙트는 맞은 직후가 아니라, 맞고 나서 2프레임 후에 출력되어야 하기에 이와 관련된 코드작업을 병행했다. 하지만 새로운 문제가 발견됐다. 프레임이 안맞아! 맞는 순간 1프레임이 먼저 재생된다.
이제 와서 이를 해결하기 위해선 약간의 비효율을 감수해야 한다. 하지만 대충 하자.
먼지와 암석의 색깔등은 스테이지마다 달라야 한다. 이를 위해 데이터 베이스를 구축해야 한다. 원래는 좀 더 후반작업으로 생각하고 있었는데, 셰이더가 많아지면서 더 늦추면 안되겠다는 생각이 들었다.
입력고장은 간단한 문제였다. 캐릭터를 강제로 미는 값이 있다면 방어로 인식하게 했는데, 이것이 대쉬와 값이 겹치며 내는 오류였다.
문제는 점점 정교해진다. 이번엔 충돌이 문제다. 현재 캐릭터는 빠른 속도로 지나가는 캐릭터를 막지 못한다. 대시할 때 한 프레임에 움직이는 이동량이 캐릭터를 넘어버리기 때문에, 두 캐릭터의 위치가 바뀌게 되는 현상이 있다. 이는 곧 벽체크에 걸려 다시 제자리로 돌아오긴 하나, 완성도가 떨어져 보이므로 수정해야 한다.
…
새벽에 이 문제를 3시간동안 살피다가 포기하고 잤는데, 자고 일어나니 10분만에 해결했다. 허탈해! 충돌이 문제가 아니었어!
프레임과 타이밍을 조절하고, 세부 조절이 끝나면 본격적으로 애니메이션을 만든다.
연계기가 들어가니 또다른 문제가 보인다. 검기의 셰이더 드라이버가 한 프레임 늦게 갱신됨에 따라, 연계시에 잘못된 정보를 보여준다.
업데이트를 한탐 늦게 하면 될 줄 알았는데, 예상대로 안되길래 그냥 모션 시작시에 검기를 숨겨서 물리적으로 해결했다. 마음에 드는 해결책은 아니지만…이걸 시간들여 해결할만한 가치가 있는가? 도 의문이긴 하다.
연계기 – 강베기인데, 다 만들어 실제로 써보니 그렇게 예쁘지도 않고, 효용성도 떨어져서 삭제. 오래걸렸는데…흑흑.
이로서 연계기의 형태는 좀 더 단순해진다.
A-A-A
A-A-B.
스톰프는 이펙트가 있어야 완성된다. 타격은 2번 일어나는데 맞으면 한 번만 맞는다. 하단이지만 발동도 느리기 때문에 방어데미지를 주는 용도
5.23
모든 초안은 쓰레기다. 소점프킥 모션을 수정.
본체 애니메이션이 끝난 후, 세컨더리 애니메이션까지 완료. 이제 너무 자잘한 건 신경쓰지 않게 된다.
초필은 2라운드당 한 번 정도 사용하게 디자인할 예정이지만, 정말로 극단적인 경우 둘이 동시에 초필을 발동할 수도 있을 것이다. 그럴 경우를 대비해서 코드를 수정해 준다.
이제 어렴풋한 생각들을 구체화시켜야 한다. 일단 필요한 작업들에 대해 목록을 뽑자. 모든 일의 시작이다. 이 때 개발 코드명을 같이 설정하면 좋다. 공용모션에 관한 목록들을 먼저 설정해보자.
방어 (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의 료가 일격필살을 사용했을 때 데미지 모션이 꽤 인상적이었기 때문에 넣기로 했다.
방어는 꽤 어렵다. 오래전 짜 놓았던 코드 때문인지 작동은 되는데… 입력 조건을 어찌짜야할지 고민이다. 내일할까…
본의 마디가 많을 때, 루트와 중간본의 애니메이션은 따로 제작하자. 물론 루트 적용해보고 잘 나오면 좋고.
세컨더리가 필요한 부분에 대해서는 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;
이제 정상작동하는 것을 확인할 수 있다.
달래가 은근 달린 것이 많다 보니 타격등에서 캐릭터경직이 일어날 때 다이나믹본이 움직이는 것이 꽤 거슬린다. 그래서 경직중엔 업데이트가 되지 않도록 수정했는데, 이렇게 되니 세컨더리본들의 움직임이 초기화되기 때문에 자연스럽게 보이기 위해 맞을 때 세컨더리본을 ‘예쁘게’수정해 주어야 한다. 내일은 이걸 해보자.
…
맞을 때 세컨더리본을 수정하기 위해선 꽤나 많은 품이 드니까 다이나믹본 코드를 수정해보자. 그런데 코드에 타임스케일을 곱해주면 오류가 난다. 하지만 변수를 별도로 할당해서 처리하면 오류가 나지 않는다. 왜지…?!
난 스프링본에 대해 부정적이었다. 스프링본 특유의 달랑거리는 느낌이 싫었고, 충돌이 항상 말썽을 일으키기도 했기 때문이다. 무엇보다도 본 움직임의 제어권을 시스템에 빼앗기는 것이 싫었다. 키를 원하는대로 움직일 수 없다면, 결국은 언젠가 문제가 생긴다. 하지만 다이나믹본은 키애니메이션위에 물리적인 움직임이 블렌딩된다. 이럴 수가! 이걸 진작에 알았더라면, 시간을 아주 많이 절약할 수 있었을텐데!
다이나믹본은 캐릭터의 움직임에 따른 운동량을 계산해준다. 하지만 기본적으로는 스프링이기 때문에, 원심력과 중력을 계산하지는 못한다. 엄밀히는 중력 계산을 할 수 있지만, 닐리가 상대를 들어올렸을 때처럼 특이한 상황에만 중력이 적용되어야 하기에, 의도적으로 연출된 움직임을 제어하려면 키애니메이션이 편하다.
그렇다면, 할 일은 원심력과 중력만 적용된 데이터를 유니티에 넘기는 것이다. 해보자.
바닥에 드리워지는 옷자락의 표현. 플랜 콜라이더는 별 기대 안했는데 예상 외의 괜찮은 퀄리티를 보여준다.