Live2D Cubism
Live2D Cubism은 비주얼 노벨의 캐릭터 스프라이트 같은 2D 이미지에 애니메이션을 적용하는 시스템입니다. 이미지는 여러 레이어로 나누어 그립니다. 예를 들어 눈동자와 홍채, 흰자, 눈썹 등을 각각 별도 레이어에 둡니다.
Live2D 소프트웨어에서는 각 레이어에 메시를 연결하고 매개변수 조정에 따라 메시의 형태가 어떻게 변하는지 지정할 수 있습니다. 시간에 따라 매개변수가 바뀌는 방식을 정하는 모션 파일과 표정을 정하는 표정 파일도 만들 수 있습니다.
Ren'Py의 Live2D 연동은 Live2D가 만든 파일을 가져와 Ren'Py에서 표시할 수 있는 애니메이션으로 정의하는 방식입니다. Ren'Py는 모션과 표정을 처리하여 매개변수 값을 구하고 Cubism SDK for Native에 전달합니다. SDK가 표시할 메시 목록을 반환하면 Ren'Py가 이를 렌더링하여 화면에 Live2D 캐릭터가 나타납니다.
Ren'Py는 Cubism 3, 4, 5 형식의 Live2D 애니메이션을 지원하며 표정과 모션을 재생할 수 있습니다.
경고
iOS에서 Live2D를 설치하려면 정적 라이브러리를 iOS 프로젝트에 직접 복사해야 합니다.
Live2D 설치
Live2D를 사용하려면 먼저 Live2D 웹사이트에서 Cubism SDK for Native를 다운로드하여 설치해야 합니다. 사업의 연간 수익이 일정 금액을 넘으면 Live2D 사용 라이선스를 구매해야 할 수 있습니다.
다운로드한 뒤 Ren'Py 런처에서 설치할 수 있습니다. 환경설정(preferences)으로 이동하여 라이브러리 설치(Install libraries)를 클릭합니다. CubismSdkForNative-5-r.1.zip 파일을 Ren'Py SDK 디렉터리에 넣습니다. 이 디렉터리는 라이브러리 설치 화면 오른쪽 아래의 버튼으로 열 수 있습니다. 이어서 Install Live2D Cubism SDK for Native를 클릭하면 잠시 후 설치됩니다.
애니메이션 정의
Live2D 디스플레이어블과 image 문으로 Live2D 애니메이션을 정의합니다.
- Live2D(filename, zoom=None, top=0.0, base=1.0, height=1.0, alias={}, loop=False, fade=None, seamless=None, attribute_function=None, attribute_filter=None, update_function=None, old_beziers=None, **properties)
Live2D 애니메이션을 표시하는 디스플레이어블입니다.
- filename
Live2D 애니메이션을 정의하는 model3.json 파일 또는 해당 애니메이션을 담은 디렉터리입니다. 디렉터리이면 마지막 경로 요소에 .model3.json을 붙여 파일을 찾습니다.
예를 들어 "Resources/Hiyori"와 "Resources/Hiyori/Hiyori.model3.json"은 같습니다.
- zoom
None이 아니면 적용할 확대·축소 배율입니다. top과 base보다 우선합니다.
- top
크기 계산에 사용할 이미지의 위쪽 지점입니다. 이미지 크기에 대한 비율이며 0.0은 맨 위, 1.0은 맨 아래입니다.
- base
크기 계산에 사용할 이미지의 아래쪽 지점입니다. 이미지 크기에 대한 비율이며 0.0은 맨 위, 1.0은 맨 아래입니다. yanchor의 기본값도 됩니다.
- height
이미지 크기를 조절할 목표 높이입니다. 화면의 가상 높이에 대한 비율입니다.
- loop
마지막 모션을 반복하려면 True, 아니면 False입니다.
- alias
별칭을 해당 모션이나 표정에 매핑하는 딕셔너리입니다.
- fade
모션 페이드를 켜려면 True, 끄려면 False,
_live2d_fade값을 사용하려면 None입니다.- nonexclusive
None이 아니면 비배타적 표정 이름의 리스트여야 합니다. 표정은 기본적으로 배타적이어서 한 번에 하나만 표시합니다. 이 목록의 비배타적 표정은 배타적 표정 하나와 함께 원하는 수만큼 표시할 수 있습니다.
- seamless
끊김 없는 반복 사용 여부를 결정합니다. 이 기능은 같은 모션을 반복할 때 반복 사이의 페이드를 생략합니다. 항상 켜려면 True, 항상 끄려면 False, 특정 모션에만 적용하려면 해당 모션 집합을 지정합니다.
- default_fade
모션이나 표정으로 페이드인하거나 페이드아웃하는 기본 시간입니다. Live2D에 따라 기본값은 1.0이므로 예상하지 않은 페이드가 발생할 수 있습니다. 명시적으로 요청한 경우에만 페이드하도록 하려면 0.0으로 설정합니다.
- attribute_function
None이 아니면 속성 튜플을 받아 다른 속성 튜플을 반환하는 함수입니다. 표시할 때만 속성을 바꾸는 데 사용할 수 있으며 반환한 속성은 이미지 표시 명령의 속성으로 사용하지 않습니다. 표정에 해당하는 속성은 최대 하나만 반환하도록 해야 합니다.
- attribute_filter
None이 아니면 속성 튜플을 받아 다른 속성 튜플을 반환하는 함수입니다. 주로 서로 충돌하는 비배타적 속성을 걸러내는 데 사용합니다. 최근에 요청한 속성이 앞에 오도록 정렬되므로 충돌 시 첫 번째 속성을 우선해야 합니다.
- update_function
None이 아니면 현재 모션과 표정으로 매개변수를 갱신한 뒤 애니메이션을 렌더링할 때 호출하는 함수입니다. 다음 두 인수로 호출합니다.
Live2D 객체.
초 단위의 표시 시간 기준.
전달된 Live2D 객체의 blend_parameter 메서드로 매개변수를 동적으로 바꾸는 데 사용하는 함수입니다. 다시 호출할 때까지의 지연 시간을 초 단위로 반환해야 하며, None이면 다음 상호작용 시작 시 다시 호출합니다. 디스플레이어블을 다시 렌더링할 때도 호출합니다.
- old_beziers
True이면 이징을 사용하는 이전 베지어 곡선 동작을 사용합니다. False이면 Cardano 방식으로 베지어를 해석합니다. None이면
config.live2d_old_beziers값을 사용합니다.
attribute_function은 주로 속성 치환을 계산하는 데 사용합니다. 두 속성이 있으면 세 번째 속성으로 바꾸는 경우가 이에 해당합니다. 반면 attribute_filter는 여러 속성 중 하나만 유효해야 하는 그룹처럼 속성 간 충돌을 해결하는 데 사용합니다.
filename만 위치 인수로 지정하고 나머지는 모두 키워드 인수로 지정해야 합니다.
alias, fade, nonexclusive, seamless, default_fade, attribute_function, attribute_filter, update_function 값은 같은 filename을 사용하는 모든 Live2D 객체가 공유합니다. 따라서 해당 filename을 사용하는 첫 Live2D 객체에만 한 번 지정하면 됩니다.
- blend_parameter(name, blend, value, weight=1.0)
매개변수의 현재 값에 value를 혼합합니다. update_function 밖에서는 효과가 없습니다.
- name
바꿀 매개변수의 이름을 나타내는 문자열입니다.
- blend
사용할 혼합 방식으로 "Add", "Multiply", "Overwrite" 중 하나입니다.
- value
혼합할 값을 나타내는 float입니다.
- weight
새 값이 현재 값을 바꾸는 정도인 가중치입니다. 0.0에서 1.0 사이의 float입니다.
- blend_opacity(name, blend, value, weight=1.0)
파트의 현재 불투명도에 value를 혼합합니다. update_function 밖에서는 효과가 없습니다.
- name
모델에 정의된 매개변수 중 바꿀 매개변수의 이름입니다.
- blend
사용할 혼합 방식으로 "Add", "Multiply", "Overwrite" 중 하나입니다.
- value
혼합할 불투명도 값을 나타내는 float입니다.
- weight
새 값이 현재 값을 바꾸는 정도인 가중치입니다. 0.0에서 1.0 사이의 float입니다.
- define config.live2d_old_beziers = False
True이면 Live2D가 기본적으로 이징을 사용하는 이전 베지어 곡선 동작을 사용합니다. False이면 Cardano 방식으로 베지어를 해석합니다.
.model3.json 파일에서 로드된 모션과 표정을 디버깅할 때 유용한 설정 변수가 있습니다.
- define config.log_live2d_loading = False
True이면 시작 시 로드한 경로와 사용한 모션 및 표정을 log.txt에 기록합니다.
Live2D 디스플레이어블은 image 문에 할당해야 합니다.
image hiyori = Live2D("Resources/Hiyori", base=.6)
속성을 정의할 수도 있습니다. 서로 다른 확대·축소 배율을 정의할 때 매우 유용합니다.
image hiyori close = Live2D("Resources/Hiyori", base=.6)
image hiyori far = Live2D("Resources/Hiyori", base=.9)
사용자의 하드웨어에서 Live2D를 초기화하지 못할 수 있다는 점에 유의하세요. 이 경우 Live2D()를 한 번만 호출해도 프로젝트 전체가 로드되지 않습니다. 웹 버전으로 배포한 게임도 마찬가지입니다. Live2D 없이도 게임이 작동해야 한다면 다음과 같은 래퍼나 우회 방법을 사용할 수 있습니다.
init python:
def MyLive2D(*args, fallback=Placeholder(text="Live2D 없음"), **kwargs):
if renpy.has_live2d():
return Live2D(*args, **kwargs)
else:
return fallback
image kobayashi = MyLive2D(...)
image eileen moving = MyLive2D(..., fallback="eileen happy")
애니메이션 사용
Live2D 이미지는 일반적으로 show 문으로 표시합니다. image 문에 추가한 속성 외에도 표정과 모션의 이름을 사용할 수 있습니다.
예를 들면 다음과 같습니다.
show natori exp_00 mtn_01
show hiyori m10
show hiyori m10 m01
이 예제는 Cubism SDK 샘플의 기본 이름을 사용합니다. 모션과 표정의 이름은 Live2D 파일에서 가져와 소문자로 바꿉니다. 이름이 디렉터리와 확장자를 뺀 model3.json 파일명 뒤에 밑줄이 붙는 형식으로 시작하면 해당 접두사를 제거합니다. 예를 들어 "Hiyori_Motion01"은 motion01이 됩니다.
배타적 표정은 최대 하나만 사용할 수 있지만 비배타적 표정과 모션은 원하는 수만큼 지정할 수 있습니다. 모션을 여러 개 지정하면 순서대로 재생하고 loop가 True이면 마지막 모션을 반복합니다. 따라서 특정 모션 뒤에 대기 애니메이션을 재생할 수 있습니다. 같은 모션의 별칭을 여러 개 만들지 않는 한 각 모션은 한 번만 지정할 수 있습니다.
특수 속성은 null과 still 두 가지입니다. null은 배타적 표정 파일을 적용하지 않고 캐릭터의 기본 표정을 사용한다는 뜻입니다. still 모션은 모든 움직임을 멈춥니다.
비배타적 표정은 속성 부정 구문으로 제거할 때까지 유지됩니다.
show hiyori -wave
크기 조절
많은 Live2D 모델은 적어도 내부 좌표계에서는 높은 해상도로 정의되어 있습니다. Ren'Py는 이를 보정하기 위해 Live2D 모델을 축소하는 두 방법을 제공합니다.
첫째는 모델의 배율을 직접 설정하는 zoom 인수입니다. zoom을 사용하면 다른 크기 조절 매개변수는 무시합니다.
그 밖의 경우 top, base, height를 사용합니다. 처음 두 인수는 이미지의 위와 아래를 기준으로 두 선을 지정합니다. Ren'Py의 다른 곳처럼 0.0은 맨 위, 1.0은 맨 아래입니다. 이 인수들을 사용하면 다음 두 작업이 이루어집니다.
top과 base 사이의 영역이 height를 차지하도록 이미지 크기를 조절합니다. height는 화면 크기에 대한 비율입니다.
base가 화면 아래쪽에 놓이도록 앵커를 조정합니다.
Live2D 애니메이션의 크기를 맞출 때는 먼저 base를 조정하여 원하는 부분이 화면 아래쪽에 맞도록 합니다. 그런 다음:
이미지가 너무 크면 적절한 크기가 될 때까지 height를 줄입니다.
이미지가 너무 작으면 top을 늘려 애니메이션 위의 빈 공간을 줄입니다.
모션 페이드
Ren'Py의 Live2D 지원에는 모션 페이드가 포함됩니다. 일반적으로 Ren'Py에서 애니메이션을 바꾸면 이전 애니메이션을 멈추고 새 애니메이션을 시작하므로 변화가 갑작스럽습니다. 화면 전환을 적용하면 두 애니메이션을 동시에 재생합니다.
Live2D는 매개변수를 보간하여 이전 애니메이션에서 새 애니메이션으로 부드럽게 이어지는 다른 방식을 지원합니다. 한 자세에서 다른 자세로 디졸브하는 대신 캐릭터가 팔을 직접 움직여 자세를 바꾸는 것과 같습니다.
모션 페이드는 fade 인수로 제어합니다. 참이면 사용하고 거짓이면 갑작스럽게 바뀝니다. None이면 _live2d_fade 변수가 제어합니다.
- _live2d_fade = True
참이면 Live2D 애니메이션에 모션 페이드를 사용합니다. False이면 애니메이션이 갑작스럽게 바뀝니다.
별칭
alias 매개변수로 자동 정의되는 모션에 원하는 이름을 지정할 수 있습니다. 예를 들어 다음과 같이 작성하면:
image hiyori = Live2D("Resources/Hiyori", base=.6, aliases={"idle" : "m01"})
다음과 같이 사용할 수 있습니다.
show hiyori idle
다음 형식 대신 사용합니다.
show hiyori m01
반복과 이미지 예측 로딩
Ren'Py의 Live2D 기능은 loop가 True이면 마지막 애니메이션을 반복할 수 있습니다. 반복할 때는 비용이 큰 이미지 예측 로딩을 Ren'Py가 수행할 수 있도록 .2초보다 긴 대기 시간을 추가하는 것이 중요합니다. 다른 시점에 이미지를 예측하고 로드할 수 있다면 필요하지 않을 수 있습니다.
함수
- renpy.has_live2d()
현재 플랫폼에서 Live2D를 지원하면 True, 아니면 False를 반환합니다.