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이 등록되었을 때