2015年8月26日 星期三

UNITY3D - 用程式更改animation關鍵影格 change animation clip property value by script

有時候我們會需要物件的移動數值是可調整的,但可能因為架構上大量使用mecanim(animator)導致難以改用程式去控制物件移動。
這時候我們可以用程式更改animator所讀取的animation clip,將裡面的關鍵影格資訊改成所需要的數值。
善加利用state machine加上可變動的animation,mecanim的使用彈性就更高了。

所用到的function : AnimatorOverrideControllerAnimationClip.SetCurveAnimationClip.AddEvent

AnimationClip.SetCurve只會新增或蓋掉原本clip中有設定的property,要刪除某個property則在第四個參數(AnimationCurve)傳入null即可。

※注意,AnimationClip.SetCurve只在Editor上有效!

Runtime會更改專案中animation clip的寫法
//Change transform.localPosition.x move 0~100
//Change sprite.color.a 1~0
//Add event call Ready and pass parameter on 1sec
//gameObject structure:  gameObject:transform
//                           |
//                           --- child:SpriteRenderer
void ChangeAnimCurve () {
    Animator _animator = GetComponent();
    AnimatorOverrideController myOverrideController = new AnimatorOverrideController();
    myOverrideController.runtimeAnimatorController = _animator.runtimeAnimatorController;
    AnimationClip clip = myOverrideController["clipname"];
    clip.SetCurve("", typeof(Transform), "localPosition.x", new AnimationCurve(new Keyframe(0f, 0f), new Keyframe(1f, 100f)));
    clip.SetCurve("child", typeof(SpriteRenderer), "m_Color.a", new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0f)));
    AnimationEvent evt = new AnimationEvent ();
    evt.functionName = "Ready";
    evt.intParameter = 1;
    evt.time = 1f; //make sure there got a keyframe
    clip.AddEvent (evt); //events added with AddEvent will only persist until play mode is exited of player is quit.
    _animator.runtimeAnimatorController = myOverrideController;
}




不更改專案中animation clip的寫法
//Change transform.localPosition.x move 0~100
//Change sprite.color.a 1~0
//Add event call Ready and pass parameter on 1sec
//gameObject structure:  gameObject:transform
//                           |
//                           --- child:SpriteRenderer
void ChangeAnimCurve () {
    Animator _animator = GetComponent();
    AnimatorOverrideController myOverrideController = new AnimatorOverrideController();
    myOverrideController.runtimeAnimatorController = _animator.runtimeAnimatorController;
    AnimationClip clip = new AnimationClip();
    clip.SetCurve("", typeof(Transform), "localPosition.x", new AnimationCurve(new Keyframe(0f, 0f), new Keyframe(1f, 100f)));
    clip.SetCurve("child", typeof(SpriteRenderer), "m_Color.a", new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0f)));
    AnimationEvent evt = new AnimationEvent ();
    evt.functionName = "Ready";
    evt.intParameter = 1;
    evt.time = 1f; //make sure there got a keyframe
    clip.AddEvent (evt); //events added with AddEvent will only persist until play mode is exited of player is quit.
    myOverrideController["clipname"] = clip;
    _animator.runtimeAnimatorController = myOverrideController;
}