프리오리 리깅

9.5

프리오리의 리깅 작업 중 머리카락 – 손

손의 웨이트 데이터 이전이 잘 안되는 문제가 있었다. 프리오리는 한 쪽에 장갑을 끼고 있기 때문에 맨손과 버텍스가 다소 차이가 난다. 하지만 그렇다고 해도 오차범위를 벗어나는 것이 이상해서 와이어를 켜보니 폴리곤이 비정상적으로 많은 문제가 있었다. 섭디가 2번 된 것이다. 이것 때문에 원본 모델에서 다시 이식을 하는 바람에 삽질의 품격을 한단계 더 높이는 계기가 됐다.

프리오리는 미니 스커트를 입고 있으므로 치마본을 닐리에게서 이식해야 할텐데, 이게 잘 될런지 모르겠다. 일단 상체를 모두 작업하고 생각해 보자.

9.6

닐리의 치마본을 이식해와야 한다. 보기에도 복잡하지만 이걸 만드느라 한달 넘게 걸렸었다. 이식도 간편하진 않을 것이다… 두근거리는 마음을 안고 옮겨보자.

아마추어를 병합할 땐 유효하지 않은 드라이버 정보를 삭제해주어야 한다. 이는 병합하기 전에 하는 것이 좋은데, 같은 소스에서 분리된 아마추어일 경우, 드라이버가 2중으로 설정되기 때문이다. 표면적으로는 별 다를 것이 없지만, 이 정보가 누적되면 성능이 눈에 띄게 저하된다. 이는 전 직장에서 일할 때 자동 병합 시스템을 만들며 알아낸 것이다.

그래서 결론. 합치기 전에 요걸 눌러서 지워주면 된다.

오! 그냥 착 붙는다! 이렇게 한 번에 될 줄은 몰랐는데! 그럼 웨이팅만 하면 되겠다.

데이터도 제법 깔끔하게 넘어왔다. 과거의 고생이 헛되지 않았음을 증명해준다. 흑흑.

이제 웨이팅은 끝났지만, 옷에 두께를 주어야 한다. 웨이팅 전에 두께를 만들어 놓으면 값이 복사가 되지 않기 때문에 여러모로 번거롭고, Data transfer를 사용하면 근사치가 들어가긴 하지만 완전히 같지는 않다.

옷의 아웃라인까지 완료. 이제야 윤곽선이 정돈되어 깔끔한 느낌이다. 프리오리의 리깅 완료. 벨로 넘어가자.

도레미 모델링

9.3

2차 마일스톤의 마지막 캐릭터다. 얘는 뭐 딱히 디테일을 설정할 게 없다. 바니걸의 복장은 정해져 있는 것이고, 망치는 보이는 그대로의 디자인이라 내부설정할 것이 없고… 그냥 잘 만들어 보자!

9.4

토끼 귀 때문에 키 185cm!

엉덩이처럼 폴리곤이 겹치는 경우엔 절반을 선택하는 도구인 Side of Active가 잘 작동하지 않는다. 이럴 경우엔 그냥 Seam설정이 편하다. 편의 기능에 생각이 매몰되어 기본기를 잊으면 안된다는 교훈.

허리에 주름을 넣자.

심 구조는 이렇다.

9.5

오늘의 깨달음. Checker Deselect는 가장 하단의 선을 잡고 실행하면 편하다.

머리카락을 짤라주고…

그… 모델링할 게 거의 없는데… 일단 색칠해 보자.

색칠할 것도 그닥 없다… 뭔가 심심한데..

봉재선 위치를 바꿔주고 마무리.

그레텔 모델링

8.30

그레텔의 처음 설정은 간호사였다. 그렇다면 주사기를 무기로 사용해야 하는데, 이것이 ‘액션’을 하기엔 너무 작다는 생각이 들었다. 그렇다고 과장된 커다란 주사기를 사용하고 싶지도 않았고,결국 암살자로 방향을 선회했다. 그렇게 간호사 모자를 쓴 이상한 암살자가 디자인됐다.

현재 제작된 알파 버전의 비오는 폐허 배경이 그레텔의 장소이다.

8.31

땋은 머리가 필요하다. 달래의 머리는 로폴기준으로 만들었고, 얘는 덩어리가 커서 실제로 땋은 모델링이 필요한데, 예전에 한 번 커브로 만들어던 적이 있다.

찾았다. 이런 건 만들어두면 두고두고 도움이 된다.

9.1

예전에 만들어 놓은 땋은 머리 레퍼런스가 있다고 해도 쉽지 않았던 머리카락 모델링.

만들다보니 모자가 영 거슬려서 삭제

큰일났다. 안경이 귓구멍에 꽂혀..

결국 만나고야 만 Transparent셰이더. 안하고 싶었지만 어쩔 수 없다.

옷을 만들어보자.

멋있다. 마치 Concord의 캐릭터 같아.

팔 주름 러프 스케치

모양대로 짜르고, 크리즈를 주고

…는 주름이 너무 많고 펑퍼짐하다… 좀 줄이자.

9.2

꽤 어려운 과제였다.

금도끼, 은도끼도 만들어주자.

원본 모델링 완료. 굳히기에 들어가자.

머리카락을 색칠하고,

9.3

조금씩 전진

이 문신은 게임상에서 거의 보일 일은 없을 것 같지만, 설정했으므로 그려두자.

본체는 완성인데, 안경 셰이더를 따로 만들어야 한다.

오랫만에 만드니 기억이 하나도 안나서 더듬더듬…. 영상을 찍고 나니 역시 대각선이 좋아보여 다시 대각선으로 바꾸었다.

이는 나중에 유니티에서 컨버팅해야 할 것이다.

벨 모델링

8.26

벨은 왕위를 장녀가 아닌 자신이 물려받아야 한다는 왕가의 차녀이다. 매사에 기품있고 예의바르게 행동하지만 조금만 수틀려도 쉽게 신경질을 내며 쌍욕을 한다. 즉, 매우 가식적이며 신경질적인 성격. 왕위 계승이 얼마남지 않자 초조해진 이 차녀는 언니에게 독살을 시도하지만 곧 실패하고 도망친다. 하지만 꿈을 굽히지 않고 모든 걸 뒤엎을 수 있는 한 방을 원하기에 배틀퀸이 되려 한다…는 러프한 설정

벨은 모델링 난이도가 꽤 높을 것으로 예상된다. 곱슬머리와 치마의 레이스의 폴리곤 접힘 처리가 관건이다. 차근차근 진행해보자.

8.27

오랫만에 스크립트를 추가했다. 이 코드는 오리진을 x:0으로 옮겨준다. 미러를 정확히 하고 싶을 때 사용하는데, 코드대로라면 y,z는 유지되어야 할 것 같지만, 어쩐지 원점으로 이동한다. 이렇게 되면 사실 3D커서를 원점에 두고 미러하는 것과 같은데…그건 파이메뉴를 2번이나 열어야 하니 그냥 이걸 쓰자. 역시나 chatGPT가 짜주었다.

        obj = bpy.context.active_object
        bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS', center='BOUNDS')
        origin_location = obj.matrix_world.translation
        offset = mathutils.Vector((origin_location.x, 0, 0))
        obj.location -= offset

        obj.data.transform(mathutils.Matrix.Translation(offset))
        bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)   

모델은 아직 러프한 상태

머리카락 심는 중… 정공법으로 돌파하겠다! 컴퓨터가… 이걸 버틸까..?

손님, 머리숱이 많으시네요.

머리카락 12,000개. 예상외로 얼마 안된다

8.28

뭔가 어렵네… 오늘은 모델링이 잘 손에 안붙는 느낌이다.

오리진 x:0코드가 작동이 잘 되지 않아서 손으로 다시 짰다. 매트릭스를 건드는 건 늘 골치가 아프니, 원시적인 방법으로 옮겨주자.

        obj = bpy.context.active_object
        
        set_mode('OBJECT')
        bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS', center='BOUNDS')
        bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)
        
        set_mode('EDIT')
        mesh = bmesh.from_edit_mesh(obj.data)
        
        offset = obj.location.x
        
        for vertex in mesh.verts:
            vertex.co.x += offset
            
        bmesh.update_edit_mesh(obj.data)
        
        set_mode('OBJECT')        
        obj.location.x = 0

set_mode는 모드 변환을 쉽게 사용하려고 만든 커스텀 함수이다.

def set_mode(m):  
    if bpy.context.mode != m:
        bpy.ops.object.mode_set(mode=m, toggle=False)

잘 작동한다. 역시 아날로그가 최고다.

이제 프릴을 만들 차례. 몇 가지 테스트를 해야 한다.

프릴스커트를 만드는 법에 대한 기록

8.29

팬티는 사실 이렇게까지 안해도 되는데, 파고 있다.

레이피어까지 완료. 이제 텍스처링을 해보자.

텍스처링 과정. 삽질 한가득

8.30

끝난 것처럼 보이지만, 손볼 곳이 남아있다.

  • 윗머리 폴리곤을 너무 아껴서 각지게 보이는 문제
  • 가슴골 윗부분의 아웃라인은 좀 더 얇게 처리

배면법을 일률적으로 적용하면 선맛이 살지 않는다. 3D에서 선맛을 찾는 것은 좀 이상하지만, 어쨌거나 실제 그림을 그린다면, 아무도 저렇게 가슴 위쪽까지 투박하게 선을 긋지는 않을 것이다.

이를 위해서 아웃라인 제네레이팅을 할 때 웨이트값을 참고해서 Fatten을 적용하는 기능을 만들었었다. 사실 이 기능은 이전 프로젝트에도 사용되던 기법인데, 뭐 이렇게까지 해야될까…싶어서 만들어 놓고도 작업자들에게 권장하지 않았다. 귀찮기 때문. 하지만 이것은 분명한 쓸모가 있다.

이제 정수리를 정리해 보자.

아휴.. 참 대충도 만들었다. WIP를 따로 저장해두는 이유가 바로 이런 것 때문이다. 한 번에 잘 나오는 결과물은 없으므로 계속 다듬어 주어야 한다.

벨은 타캐릭터보다 머리가 조금 작다. 이게 익스포트가 잘 될까… 잘 되길 바랍니다.

이로서 벨 모델링 완료. 그레텔로 넘어가자.

배틀퀸 v0.26 다운로드

제 예전 블로그엔 아직 프로젝트A의 기록이 남아있습니다.(링크) 옮기기도 번거롭고 지우기도 귀찮아서 그대로 남겨두었더랬죠. 완성은 커녕 제대로 된 대전버전까지도 좀 힘들지 싶었는데, 생각보다 더 많은 분들이 응원해 주신 덕에 여기까지 오게 되었습니다. 응원해 주신 많은 분들께 감사드립니다.

본 버전은 대전 테스트를 위한 알파 버전입니다. 아직 AI개발은 되지 않았기 때문에, 플레이어간 대전만 가능합니다.

배틀퀸 0.26 다운로드 (Download BattleQueen v0.26)

▲ 품질 보증서(https://www.virustotal.com/)

사용키

조이스틱을 지원합니다. 키패드 1,2번을 눌러서 입력장치를 바꿀 수 있습니다.

▲ Joystick / Keyboard

양 쪽 모두 키보드일 경우, 한 쪽만 키보드일 때와 키가 다릅니다. 게임 중 서로의 손이 닿아 좋은 관계로 발전하는 사고를 막기 위한 배려입니다.

  • 양쪽 모두 키보드일 경우 높은 확률로 키 충돌이 일어납니다만, 조이스틱은 없는 경우가 많으니 키 배정을 했습니다.
1P한쪽만 키보드일 때양쪽 모두 키보드일 때
이동방향키숫자패드 방향키
공격ZXCVdelete, end, pageDown,Insert
2P
이동FGHT
공격ASDQ

기술표

캐릭터가 오른쪽을 보고 있는 것을 기준으로 합니다.

  • A – 약펀치
  • B – 강펀치
  • X – 킥
  • Y – 액션

공통 기술

(가까이서) ← or → A or B잡기
→ Y구르기
(방어 시) Y반격

앨리스 (Alice)

→ A or B3연속 베기. 1타 성공 시, A or B를 누르면 연결
↑ A or B대공기. B로 히트할 경우 X로 추가타
← A or B찌르기. 1타까진 슈퍼아머. B로 히트할 경우 B로 추가타
→ X바닥찍기. 하단 공격(버그 있음. 상단방어로 막힘)
↓→ B초필. 강한 베기

닐리 (Nilly)

←(모아서) (이동중립) A or B장풍
↓(모아서) (이동중립) X대공기
↑(모으기)윙가르디움 레비오사
(비행 중) A or B총쏘기
→ A or B불 손으로 할퀴기
←(모으기)→ B초필. 메테오.

달래 (Dalae)

→ A or B장풍, 버튼을 누르고 있을 경우 발사 지연
↑ A or B위로 장풍, 버튼을 누르고 있을 경우 발사 지연
← B잡아서 반대편으로 보내기
→ X발차기
↑ X반격(점프공격/상단) 하단은 안됨
↓→B초필. 난타

오로라 (Aurora)

A or B 연타팔돌리기
→ A or B프리 허그
↑ A or B대공 잡기
→ X미끄러져 발목잡기. 히트 시 X로 추가타
↓→ B초필. 잡기

프리오리 모델링 #2

8.21

캐릭터의 작업 파일은 2개로 나뉜다. 하나는 _WIP(Work In Progress), 하나는 최종파일인 _01이다. 모델링의 모디파이어를 합치기 전의 파일이다. 이들을 합친 후엔 수정이 아주 어려워지기 때문에, 이렇게 원본을 보존한다. 포토샵으로 따지면 레이어를 보존한 버전과 합친 버전을 따로 저장하는 것과 같다.

앤젤링 방향을 맞추는 중

8.23

빌드 준비를 하느라 뭔가 바빠서 작업을 못했다. 배포기념으로 윈도우 포맷을 했는데, 덕분에 블렌더를 강제 업데이트 했다. 그런데 블렌더의 렌더링 시스템이 뭔가 바뀌었다.

뭐야 왜 지저분해졌어…

그림자 처리가 좀 바뀐 것 같다. 아휴.피곤해…

아휴. 못쓰겄다. 롤백. 블룸도 컴포지트탭까지 가야 되고 아주 막.. 와. 애드온이 잘 작동하기만을 바랄 뿐.

8.24

툰렌더의 매핑은 별 게 없다. 그런데 왜 이리 오래걸릴까..

8.25

안일했던 설계가 큰 고통을 불러왔다. 가슴쪽 주름을 넣고 장갑 무늬의 윤곽선을 좀 더 두껍게 하는 ‘별 일 아닌 것 같은 일’도 예정에 없다면 큰 일이 된다. 폴리곤을 굳힌 후의 작업들은 링과 루프를 거치지 못한다면 그냥 포기하는 편이 나을 정도로 작업이 힘들다. 다음부턴 명심해 두자. 으으

8.26

생각보다 복잡했던 발.

1차 모델링 완료. 옷의 두께는 리깅을 한 후에 마무리해야 한다.

달래의 신발이 발레 슈즈 같은데 버선으로 고치는 것이 어떤가?라는 아내의 의견이 있었다. 발의 X매듭은 예쁘긴 하지만 자주 쓰면 안될 것 같기도 하고, 버선의 펑퍼짐한 느낌이 실루엣을 좀 더 재미있게 만들어 줄 것 같아서 수정했다.게임에서 보자

어쩐지 귀여운 느낌. 마무리 하자.

프리오리 모델링 #1

8.19

골조 작업이 아직 끝나지는 않았지만, 테스트가 목요일에 잡혀있다. 시간이 좀 빈다. 그럼 미리 다른 캐릭터를 만들어보도록 하자.

아. 모든 기억이 희미하다… 내가 그림을 그렸던가…타블렛을 쥐는 게 얼마만인지 모르겠다.

프리오리는 몰락한 귀족집안의 하녀라는 설정이 있다. 주인은 마약에 물들어 몰락했고, 프리오리는 주인이 권하는 약을 거절하지 못해 결국 중독되었다. 더 이상 약이 공급되지 않자 죽기 위해 몇 번이나 손목을 그은 그녀를 이 대회(?)의 주동자가 구해준다. 오른팔에 감고 있는 붕대는 자해의 흔적이다… 가 러프한 설정이다.

그런데…음.. 모델링을 못하겠어.. 어떻게 하는 거였더라..키부터 잡았던가..? 티스토리 놈들이 달래 모델링 포스트를 지워놔서 참고를 못하겠네. (아휴, 빡쳐!)

미러 모디파이어에서 클리핑을 켜고 모델링을 하다가 모디파이어를 버리게 되면 여전히 클리핑 상태로 점이 0을 벗어나지 못하는 현상이 있다. 이동옵션에서 Mirror Editing을 끄면 해제가 되긴 한다.

하지만, 이것은 블렌더가 버전업되며 생긴 버그같아 보인다. 미러와 클리핑은 다른데 같은 것처럼 동작한다.

오…하지만 분명하게 좋아진 점은 삼각형 폴리곤에 LoopCut(ctrl+R)기능으로 선 중간에 점을 찍을 수 있다! 어..아닌가? 원래 됐었던가…?

모델링은 항상 흐름 먼저.

팔주름을 그리기 위해 텍스처 페인트를 사용하려는데 스포이드 단축키가 먹지 않았다. 블렌더 4.0부터 Shift+X로 바뀌었다.

옷주름을 만드는 방법을 정립하기까진 많은 삽질을 거쳤다. 하지만 정립된 과정도 그리 편하지는 않아 자주 까먹는다. 기록용으로 남겨두도록 하자.

앗.. 애 하원할 시간.

8.20

머리카락 제작방법을 까먹었을 줄 알아서 기록하기 시작했는데, 다행이 몇 번 하다보니 기억이 났다.휴

일단 머리카락은 완료.

8.21

모델링을 할 때엔 모든 파츠를 조각내어 작업을 한다. 이 때 유용하게 사용되는 뷰포트 옵션이 랜덤컬러인데, 이 색상의 범위가 그리 다채롭지 않아서 간혹 구분이 안될 때가 있다.

이럴 땐 f2를 누르고 해당 오브젝트의 이름을 대충 아무거나 바꾸면 컬러가 바뀐다.

짜잔-

또 하나의 깨달음. 블렌더의 Knife툴은 선을 짜르는 도구다.

여기서 C를 누르면 뒷면까지 짤린다.

맥스의 Slice같은 기능이 있으면 좋겠다. 싶었는데 있었습니다.

장갑과 셔츠 디테일작업

추가스킬의 이펙트 제작

8.15

광복절이다. 대한 독립 만세!

닐리의 이펙트 제작과정. (삽질 포함) 이제 타임랩스 안찍어야지… 아휴. 작업내내 웹툰도 보고 서핑도 하고 그래야되는데, 누가 뭐라하는 것도 아니건만 카메라 켜있으니 뭘 못하겠다.

8.16

닐리 윙샷. 뿅뿅-!

불손이 소환. 2타 알찬 구성

attack_collider_01본은 본디 공격범위를 그리기 위한 용도로 생성되었다. 이 본의 위치와 크기에 따라 판정박스가 정해진다. 하지만 이것이 본래의 목적이외에 이펙트의 생성위치, 발사체의 발사위치를 알려주는 정보성 본을 겸직하다가 이번에 추가로 던지기 후의 상대방 위치를 알려주는 일도 겸하게 되었다.

문제는 이 본의 초기값이 깔끔하지가 않다는 데 있었다. 스크립트로 제어하고 있던 위치를 컨버팅하려면 깨끗한 정보가 필요했는데, 이를 위해 에디트 모드의 본정보를 0,0,0으로 바꿔주게 되면 기존에 잡아놨던 본의 애니메이션이 모두 틀어진다는 문제가 있다. 일이 크다. 어떻게 해야 할까….

ChatGPT는 답을 알고 있다.

import bpy

# 원하는 본의 이름
target_bone_name = 'attack_collider_01'

# X, Y 위치 수정 값
x_offset = -0.511749
y_offset = -0.205907

# 모든 액션을 순회
for action in bpy.data.actions:
    # 각 fcurve를 순회 (액션의 키프레임)
    for fcurve in action.fcurves:
        # fcurve가 위치 데이터인지 확인 ('location'을 포함한 경로인지 확인)
        if fcurve.data_path.endswith('location'):
            # 데이터 경로에서 본 이름 추출
            path_elements = fcurve.data_path.split('"')
            if len(path_elements) > 1:  # 본 이름이 포함된 경로인지 확인
                bone_name = path_elements[1]
                if bone_name == target_bone_name:
                    # x 좌표 또는 y 좌표에 해당하는지 확인
                    if fcurve.array_index == 0:  # x 좌표
                        print(f'Updating X location in action "{action.name}" for bone "{target_bone_name}"')
                        for keyframe in fcurve.keyframe_points:
                            keyframe.co[1] += x_offset
                            keyframe.handle_left[1] += x_offset
                            keyframe.handle_right[1] += x_offset
                    elif fcurve.array_index == 1:  # y 좌표
                        print(f'Updating Y location in action "{action.name}" for bone "{target_bone_name}"')
                        for keyframe in fcurve.keyframe_points:
                            keyframe.co[1] += y_offset
                            keyframe.handle_left[1] += y_offset
                            keyframe.handle_right[1] += y_offset

print("Completed updating keyframes.")

아무래도 블렌더 애니메이터라면, 파이썬 기초정도는 익혀두는 편이 좋겠다. 물론 첫단추를 잘 꿰는 것이 더 중요하겠지만.

8.17

이후의 일은 버그잡이다. 테스트를 하며 자잘한 수정사항들을 노션에 적어두었다. 이런 일들은 마음 같아선 바로 처리해버리고 싶지만, 얼마나 걸릴지 모르기 때문에 일단 적어두고 나중에 처리하는 것이다. 원래 하던 일을 벗어나면 안된다. 하지만 자주 벗어난다. 아휴, 급한 성격 좀 고쳐야 된다.

게임은 막타 보정이 들어가 있다. 만약 막타로 10의 데미지가 들어왔으나, 8정도의 HP가 남아있다면 살려준다. 이 때 HP는 1도트도 안보이게 되는데, 이것이 죽었다는 착각을 일으켜서 아직 살았다는 표시를 해줄 필요가 있었다. 그래서 HP가 30% 아래로 내려가면 깜빡이가 표시된다. 당연한 게 이제야 들어갔다.

끝났다… 야호. 모든 일은 언젠가는 결국 끝난다. You win!