애니메이션 적용

Spine은 애니메이션을 적용하는 데 두 가지의 API를 제공합니다.

AnimationState API

AnimationState는 시간 경과에 따른 애니메이션 적용, 나중에 재생할 수 있도록 애니메이션 큐잉, 애니메이션 간 믹싱(크로스 페이딩) 및 다층식 여러 애니메이션 적용(레이어링)을 지원합니다.

AnimationState는 상태 저장입니다. 애니메이션 적용을 위한 애니메이션 시간 및 기타 매개 변수를 저장합니다. 하나의 AnimationState에서 여러 개의 스켈레톤이 포즈를 취할 수 있지만 정확히 동일한 포즈로 여러 개의 스켈레톤을 필요로 하는 것은 다소 드뭅니다. 일반적으로 하나의 AnimationState 인스턴스가 각 스켈레톤 인스턴스에 사용됩니다.

AnimationState는 타임라인 API 위에 구축되며 뒤로 재생을 제외한 대부분의 애니메이션 재생 요구 사항을 처리할 수 있습니다. 역방향 재생이 필요한 경우 타임라인 API를 직접 사용하거나 박스 선택 스케일링을 사용하여 Spine에서 애니메이션을 복제하고 되감을 수 있습니다.

AnimationState의 update 메서드는 마지막으로 호출된 이후로 경과된 시간이 소요되며 내부 상태를 업데이트합니다. apply 메서드는 스켈레톤을 선택해서 적절한 애니메이션을 적용합니다.

AnimationState state = ...
...
// Every frame:
state.update(delta);
state.apply(skeleton);

믹스 시간

AnimationState 인스턴스를 생성하려면 AnimationStateData를 제공해야 합니다. AnimationState가 현재 애니메이션을 변경하면 AnimationStateData에 정의된 믹스 지속 시간을 사용하여 애니메이션 간에 자동으로 믹스(크로스페이드)되어 애니메이션이 부드럽게 전환됩니다.

AnimationStateData stateData = new AnimationStateData(skeletonData);
stateData.setDefaultMix(0.1);
stateData.setMix("walk", "jump", 0.2);
stateData.setMix("jump", "walk", 0.4);
stateData.setMix("jump", "run", 0.25);
stateData.setMix("walk", "shoot", 0);
AnimationState state = new AnimationState(stateData);

모든 애니메이션 페어링에 대해 믹스 지속 시간을 수동으로 지정하는 대신 기본 믹스 지속 시간을 설정할 수 있습니다. 또한 믹스 지속 시간을 TrackEntry mixDuration 속성을 사용하여 사례별로 설정할 수 있습니다:

TrackEntry entry = state.setAnimation(0, "walk", true, 0);
entry.mixDuration = 0.6;

"Data" 접미사로 표시된 바와 같이, AnimationStateData는 상태 비저장입니다. 동일한 AnimationStateData 인스턴스를 여러 AnimationStates와 함께 사용할 수 있습니다.

트랙

트랙을 사용하면 레이어에서 애니메이션을 적용할 수 있습니다. 각 트랙에는 애니메이션 및 재생 매개 변수가 저장됩니다. 트랙에는 0부터 시작하여 번호가 점차적으로 매겨집니다(트랙 인덱스는 내부적으로 배열 인덱스입니다). AnimationState가 스켈레톤에 적용되면, 트랙 애니메이션은 가장 낮은 트랙 번호부터 순서대로 적용됩니다.

트랙에는 여러 용도가 있습니다. 예를 들면 모든 키가 없는 애니메이션은 높은 트랙에서 재생할 수 있으며 키가 있는 부분에 대해서만 낮은 트랙을 덮어씁니다. 트랙 0에는 걷기, 달리기, 수영 또는 기타 애니메이션을 가질 수 있으며, 트랙 1에는 팔과 총을 발사하는 키만 있는 발사 애니메이션을 가질 수 있습니다. 또한 높은 트랙에 대해 TrackEntry 알파를 설정하면 높은 트랙 아래의 트랙과 믹스할 수 있습니다. 예를 들면, 트랙 0에는 걷기 애니메이션을, 트랙 1에는 절뚝거리는 애니메이션을 가질 수 있습니다. 플레이어가 부상을 입으면 트랙 1의 알파가 증가되므로 점점 더 절뚝거리게 됩니다.

재생

트랙의 애니메이션 설정은 setAnimation을 호출하여 이루어집니다. 그러면 현재 애니메이션과 해당 트랙의 대기 중인 애니메이션이 지정된 애니메이션으로 바꿉니다. 이전 애니메이션과 현재 애니메이션 간에 믹스 지속 시간이 정의되어 있으면 현재 애니메이션이 믹스 지속 기간에 걸쳐 믹스되어 애니메이션 간의 전환이 원활하게 이루어집니다.

setAnimation은 여러 가지 방법으로 재생을 사용자 지정하는 데 사용할 수 있는 [TrackEntry] (# TrackEntry)를 반환합니다.

기본적으로 애니메이션은 다른 애니메이션이 재생되거나 트랙이 지워질 때까지 계속 적용됩니다. 지정된 시간 후에 애니메이션을 정지시키려면 TrackEntry trackEnd 시간을 설정할 수 있습니다.

큐잉

나중에 재생할 애니메이션을 대기열에 넣으려면 addAnimation을 호출하십시오. 이 옵션은 트랙의 현재 또는 마지막으로 대기 중인 애니메이션 이후에 재생할 애니메이션을 예약합니다. 트랙이 비어 있을 경우 setAnimation을 호출하는 것과 같습니다.

addAnimation은 재생을 사용자 지정하는 데 사용할 수 있는 TrackEntry를 반환합니다.

빈 애니메이션

빈 트랙에 애니메이션을 설정하면 바로 재생이 시작됩니다. 마찬가지로 트랙이 지워지면 애니메이션이 적용되지 않습니다. 믹스인 또는 아웃할 애니메이션을 만들려면 타임 라인이 없는 빈 애니메이션을 지정할 수 있습니다. 빈 애니메이션은 플레이스홀더로 사용되므로 믹스 지속 시간을 설정할 수 있습니다. 편의상 setEmptyAnimationaddEmptyAnimation 메서드는 빈 애니메이션을 설정하거나 대기열에 넣기 위해 제공됩니다.

설정 포즈에서 애니메이션을 믹스하려면 빈 애니메이션을 설정하고 믹스인할 애니메이션을 추가한 다음 믹스 지속 시간을 설정하십시오.

state.setEmptyAnimation(track, 0);
TrackEntry entry = state.addAnimation(track, "run", true, 0);
entry.mixDuration = 1.5;

애니메이션을 설정 포즈에 믹스하려면 믹스 지속 시간을 지정하는 빈 애니메이션을 설정하거나 대기열에 넣으십시오.

state.setAnimation(track, "run", true, 0);
state.addEmptyAnimation(track, 1.5, 0);

애니메이션이 TrackEntry trackEnd 시간에 도달하면, 애니메이션 키가 있는 속성은 설정 포즈로 설정되고 트랙은 지워집니다. 스켈레톤을 설정 포즈에 다시 믹스하려면 설정 포즈를 즉시 발생시키는 것보다 setEmptyAnimation 또는 addEmptyAnimation을 사용하는 것이 바람직할 수 있습니다.

TrackEntry

애니메이션을 설정하거나 대기열에 넣는 메서드는 재생에 대해 추가로 사용자 지정하는 데 사용할 수 있는 TrackEntry를 반환합니다. 사용 가능한 여러 설정을 보려면 TrackEntry API reference를 참조하십시오.

참조

예를 들어 시간 경과에 따라 'alpha' 또는 'timeScale' 속성을 조정하기 위해 TrackEntry에 대한 참조를 보관할 수 있습니다. 하지만 dispose 리스너 이벤트가 발생할 때 과거 참조를 보유하지 않도록 주의해야 합니다.

리스너

응용 프로그램에서 TrackEntry 라이프 사이클 이벤트를 알릴 콜백을 등록할 수 있습니다. AnimationState의 addListener는 모든 TrackEntry 이벤트에 대한 리스너를 등록합니다. 해당 항목의 이벤트만 수신하도록 리스너를 특정 TrackEntry에 설정할 수도 있습니다.

가능한 이벤트는 AnimationStateListener에 나열되며 지정된 순서대로 발생됩니다. 이벤트는 AnimationState의 update 또는 apply 메서드에 의해 수행된 내부 프로세싱 동안 대기열에 넣어진 후 메서드가 반환되기 직전에 리스너는 알림을 받습니다. 따라서 리스너에서 AnimationState를 조작하는 것이 안전합니다(예: 애니메이션 설정 또는 트랙 지우기). 하지만 이미 대기열에 넣어진 모든 이벤트는 clearListenerNotifications이 사용되지 않는 한 계속 실행됩니다.

리스너의 AnimationState에 대한 변경 사항(예:새 애니메이션 설정 등)은 다음에 AnimationState apply가 호출될 때까지 스켈레톤에 적용되지 않습니다. 리스너에서 이 작업을 수행할 수 있지만 update를 처음 호출할 때는 주의해야 합니다.

// Inside a listener:
state.setAnimation(0, "jump", false);
state.update(0); // Advance internal state.
state.apply(skeleton);

apply 메서드는 하나의 AnimationState를 여러 스켈레톤에 적용할 수 있도록 내부 상태를 변경하지 않습니다. update를 호출하면 AnimationState가 모든 적용이 완료되었음을 알 수 있고, 이후의 apply 호출은 다음 프레임을 위한 것입니다. update가 호출되지 않으면,apply는 동일한 리스너 알림을 트리거하여 무한 루프와 스택 오버플로를 유발할 수 있습니다.

타임라인 API

타임라인 API는 애니메이션을 적용하기 위한 가장 낮은 수준의 API이며 애니메이션타임라인 클래스로 구성됩니다. 이러한 클래스는 상태 비저장이므로 애니메이션을 적용하는 데 필요한 시간과 기타 매개 변수를 외부에서 저장하고 조작해야 합니다. 이 API는 애니메이션 재생을 가장 잘 제어하지만, 직접 재생 상태를 관리하기 위해 더 많은 작업이 필요합니다. 대부분의 사용자는 AnimationState API를 사용하는 것을 선호합니다.

애니메이션은 매우 간단하며 이름과 타임라인 목록이 있습니다. 각 타임라인은 시간 경과에 따라 특정 스켈레톤 속성을 수정하는 방법을 알고 있습니다. 스켈레톤에 애니메이션을 적용하려면 애니메이션의 각 타임라인에 대해 apply를 호출하여 수행됩니다. 애니메이션에는 각 타임라인에서 단순히 apply를 호출하여 이 작업을 수행하는 편리한 메서드인 apply를 가지고 있습니다.

다음: 런타임 스켈레톤 이전: 스켈레톤 데이터 로딩