Motion
업데이트: 2024/11/28
개요
Motion을 사용하면 Unity의 Mecanim에서 스테이트 머신을 구성하지 않고 스크립트에서 애니메이션을 재생할 수 있습니다.
Motion을 사용하려면 CubismFadeController 컴포넌트와 Unity Animator가 필요합니다.
Animator 컴포넌트에 AnimatorController를 설정하면 Motion이 재생되지 않고 AnimatorController의 애니메이션이 재생됩니다.
해당 튜토리얼 기사는 스크립트에서 모션 재생 을 참조하세요.
Motion은 다음 처리를 수행합니다.
- PlayableGraph 생성
- CubismMotionLayer 생성
- 애니메이션 재생
- 애니메이션 정지
PlayableGraph 생성
PlayableGraph는 애니메이션 등을 출력하기 위한 것입니다.
이에 대한 자세한 내용은 Unity 공식 문서를 참조하십시오.
// Animator 측의 PlayableGraph 비활성화
var graph = animator.playableGraph;
if(graph.IsValid())
{
graph.GetOutput(0).SetWeight(0);
}
// PlayableGraph 생성
_playableGraph = PlayableGraph.Create("Playable Graph : " + this.FindCubismModel().name);
_playableGraph.SetTimeUpdateMode(DirectorUpdateMode.GameTime);
// 결과 출력용 Playable 생성
_playableOutput = AnimationPlayableOutput.Create(_playableGraph, "Animation", animator);
_playableOutput.SetWeight(1);
// 레이어를 합성하는 Playable 생성
_layerMixer = AnimationLayerMixerPlayable.Create(_playableGraph, LayerCount);
// 디폴트 출력 대상 설정
_playableOutput.SetSourcePlayable(_layerMixer);
이 처리는 CubismMotionController.OnEnable()로 실시하고 있습니다.
CubismMotionLayer 생성
CubismMotionLayer를 사용하면 여러 모션을 병렬로 재생할 수 있습니다.
// Create cubism motion layers.
_motionLayers = new CubismMotionLayer[LayerCount];
for(var i = 0; i < LayerCount; ++i)
{
_motionLayers[i] = CubismMotionLayer.CreateCubismMotionLayer(_playableGrap, _cubismFadeMotionList);
_motionLayers[i].AnimationEndHandler += OnAnimationEnd;
_layerMixer.ConnectInput(i, _motionLayers[i].PlayableOutput, 0);
_layerMixer.SetInputWeight(i, 1.0f);
}
이 처리는 CubismMotionController.OnEnable()로 실시하고 있습니다.
여러 레이어에서 모션을 동시에 재생시켰을 때 이들이 동일한 CubismParameter.Value를 조작하면 나중에 설정된 값으로 덮어쓰기됩니다.
덮어쓰는 가중치는 CubismMotionLayer.SetLayerWeight(float weight)로 설정할 수 있습니다.
CubismMotionLayer에 가중치를 설정할 경우 AnimationLayerMixerPlayable에도 동시에 가중치를 설정해야 합니다.
AnimationLayerMixerPlayable에 대한 자세한 내용은 Unity 공식 문서를 참조하십시오.
_motionLayers[layerIndex].SetLayerWeight(weight); _layerMixer.SetInputWeight(layerIndex, weight);
애니메이션 재생
CubismMotionController.PlayAnimation(AnimationClip clip, int layerIndex = 0, int priority = CubismMotionPriority.PriorityNormal, bool isLoop = true, float speed = 1.0f)을 사용하여 애니메이션을 재생할 수 있습니다.
- AnimationClip clip: 재생할 애니메이션 클립.
- int layerIndex: 애니메이션 재생 레이어의 인덱스.
- int priority: 재생할 애니메이션의 우선순위. 현재 재생되고 있는 애니메이션에 끼워 재생시키는 경우 그 애니메이션에 설정된 priority보다 큰 값으로 한다.
- bool isLoop: 애니메이션의 루프 재생 여부. 디폴트는 루프 재생.
- float speed: 애니메이션의 재생 속도. 범위는 0 이상, 디폴트는 1(정상 재생 속도).
애니메이션 정지
지정 인덱스의 애니메이션을 정지하는 경우는 CubismMotionController.StopAnimation(int animationIndex, int layerIndex = 0)을 사용합니다.
- int animationIndex: 중지할 애니메이션의 인덱스.
- int layerIndex: 중지할 애니메이션의 레이어 인덱스.
모든 애니메이션을 중지하려면 CubismMotionController.StopAllAnimation()을 사용합니다.
애니메이션 재생 및 정지 시 콜백
Cubism SDK for Unity에서는 애니메이션 재생 시와 애니메이션 정지 시에 콜백으로 이벤트를 취득할 수 있습니다.
애니메이션 재생 시 콜백
애니메이션 재생 시 콜백을 수신하는 샘플 코드는 아래와 같습니다. 모델은 미리 가져온 상태라고 가정합니다.
private CubismMotionController _motionController;
private CubismFadeMotionList _cubismFadeMotionList;
// Start is called before the first frame update
private void Start()
{
_motionController = GetComponent<CubismMotionController>();
_cubismFadeMotionList = GetComponent<CubismFadeController>().CubismFadeMotionList;
_motionController.AnimationBeginHandler += OnAnimationBegin;
}
private void OnAnimationBegin(int instanceId)
{
if (! _cubismFadeMotionList)
{
return;
}
for (int i = 0; i < _cubismFadeMotionList.MotionInstanceIds.Length; i++)
{
if (_cubismFadeMotionList.MotionInstanceIds[i] ! = instanceId)
{
continue;
}
Debug.Log("StartedMotion: " + _cubismFadeMotionList.CubismFadeMotionObjects[i].MotionName);
break;
}
}
이 코드에서는 CubismMotionController.AnimationBeginHandler에 직접 생성한 OnAnimationBegin() 함수를 등록합니다.
Tips
아래 상태에서는 재생 시 콜백이 동작하지 않습니다.
- 콜백에 null이 등록되었을 때
애니메이션 종료 시 콜백
애니메이션 종료 시 콜백을 수신하는 샘플 코드는 아래와 같습니다.
private CubismMotionController _motionController;
private CubismFadeMotionList _cubismFadeMotionList;
// Start is called before the first frame update
void Start()
{
_motionController = GetComponent<CubismMotionController>();
_cubismFadeMotionList = GetComponent<CubismFadeController>().CubismFadeMotionList;
_motionController.AnimationEndHandler += OnAnimationEnd;
}
void OnAnimationEnd(int instanceId)
{
if (! _cubismFadeMotionList)
{
return;
}
for (int i = 0; i < _cubismFadeMotionList.MotionInstanceIds.Length; i++)
{
if (_cubismFadeMotionList.MotionInstanceIds[i] ! = instanceId)
{
continue;
}
Debug.Log("EndedMotion: " + _cubismFadeMotionList.CubismFadeMotionObjects[i].MotionName);
break;
}
}
이 코드에서는 CubismMotionController.AnimationEndHandler에 직접 생성한 OnAnimationEnd() 함수를 등록합니다.
애니메이션의 재생 종료 또는 정지 시에 이 콜백이 호출됩니다.
Tips
아래 상태에서는 종료 시 콜백을 호출할 수 없으므로 주의해 주십시오.
- 재생 중인 모션이 「루프」로 설정된 경우
- 콜백에 null이 등록되었을 때