やりたいこと
ここを参考 -> https://docs.unity3d.com/ScriptReference/Animations.AnimatorController.html
- 32パターンの同じ構造をもつstateを用意
- それぞれにBlendTreeをもつ
- Transitionに関しては双方向
- 自分自身に関してもTransitionをもつ
できたもの
スクリプト
CreateAnimationController.cs
using UnityEngine;
using UnityEditor;
using UnityEditor.Animations;
using System.Collections;
using System.Collections.Generic;
public class CreateAnimationController : MonoBehaviour
{
[MenuItem("Window/Create Controller")]
// Start is called before the first frame update
//Referenced from empathetic dialogue
static void CreateController()
{
List<string> _emotion_list = new List<string>{
"surprised",
"excited",
"angry",
"proud",
"sad",
"annoyed",
"grateful",
"lonely",
"afraid",
"terrified",
"guilty",
"impressed",
"disgusted",
"hopeful",
"confident",
"furious",
"anxious",
"anticipating",
"joyful",
"nostalgic",
"disappointed",
"prepared",
"jealous",
"content",
"devastated",
"embarrassed",
"caring",
"sentimental",
"trusting",
"ashamed",
"apprehensive",
"faithful",
};
var controller = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath("Assets/Resources/AnimationCreationController.controller");
foreach(var emotion in _emotion_list){
controller.AddParameter(emotion, AnimatorControllerParameterType.Float);
}
var rootStatemachine = controller.layers[0].stateMachine;
var waitingState = rootStatemachine.AddState("waiting");
rootStatemachine.defaultState = waitingState;
waitingState.motion = Resources.Load( "wait") as AnimationClip;
List<UnityEditor.Animations.AnimatorState> _states = new List<UnityEditor.Animations.AnimatorState>();
for(int i = 0; i < _emotion_list.Count; i++ ){
var _blendTree = new UnityEditor.Animations.BlendTree();
_blendTree.blendType = BlendTreeType.Simple1D;
_blendTree.blendParameter = _emotion_list[i];
_blendTree.name = _emotion_list[i];
var _watingClip = Resources.Load("wait") as AnimationClip;
var _emotionClip = Resources.Load(_emotion_list[i]) as AnimationClip;
_blendTree.AddChild(_watingClip);
_blendTree.AddChild(_emotionClip);
var _state = rootStatemachine.AddState(_emotion_list[i]);
_state.motion = _blendTree;
_states.Add(_state);
}
for(int i = 0; i < _emotion_list.Count; i++ ){
var wait2emotion = new UnityEditor.Animations.AnimatorStateTransition();
wait2emotion.destinationState = _states[i];
wait2emotion.hasExitTime = false;
wait2emotion.AddCondition(AnimatorConditionMode.Greater, 0.2f, _emotion_list[i]);
var emotion2wait = new UnityEditor.Animations.AnimatorStateTransition();
emotion2wait.destinationState = waitingState;
emotion2wait.hasExitTime = false;
emotion2wait.AddCondition(AnimatorConditionMode.Less, 0.2f, _emotion_list[i]);
_states[i].AddTransition(emotion2wait);
var emotion2emotion = new UnityEditor.Animations.AnimatorStateTransition();
emotion2emotion.hasExitTime = false;
emotion2emotion.destinationState = _states[i];
emotion2emotion.duration = 0.5f;
emotion2emotion.AddCondition(AnimatorConditionMode.Greater, 0.1f, _emotion_list[i]);
waitingState.AddTransition(wait2emotion);
}
}
}
コメント
ステイトはいつもクリップを落とすとできるやつ.
ステイトマシンは階層をもつレイヤー付きのステイトみたいなもの.
BlendTreeはモーション. つまり、アニメーションクリップと同じ扱い.
その他
デモ
ループアニメーションの作成
1 . 大体、端と端のキーをそろえる
2 . Very AnimationのEnsure Quaternion Continuityをかける
3 . 自分のループに対して、 Transition Duraionをかける.
#追記
BlendTreeを使わない版
CreateAnimaitonController.cs
using UnityEngine;
using UnityEditor;
using UnityEditor.Animations;
using System.Collections;
using System.Collections.Generic;
public class CreateAnimationController : MonoBehaviour
{
[MenuItem("Window/Create Controller")]
// Start is called before the first frame update
static void CreateController()
{
List<string> _emotion_list = new List<string>{
"surprised",
"excited",
"angry",
};
var controller = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath("Assets/Resources/AnimationCreationController.controller");
foreach(var emotion in _emotion_list){
controller.AddParameter(emotion, AnimatorControllerParameterType.Float);
}
var rootStatemachine = controller.layers[0].stateMachine;
var waitingState = rootStatemachine.AddState("waiting");
rootStatemachine.defaultState = waitingState;
waitingState.motion = Resources.Load( "wait") as AnimationClip;
List<UnityEditor.Animations.AnimatorState> _states = new List<UnityEditor.Animations.AnimatorState>();
for(int i = 0; i < _emotion_list.Count; i++ ){
var _watingClip = Resources.Load(""wait") as AnimationClip;
var _emotionClip = Resources.Load(_emotion_list[i]) as AnimationClip;
var _state = rootStatemachine.AddState(_emotion_list[i]);
_state.motion = _emotionClip;
_states.Add(_state);
}
for(int i = 0; i < _emotion_list.Count; i++ ){
var wait2emotion = new UnityEditor.Animations.AnimatorStateTransition();
wait2emotion.destinationState = _states[i];
wait2emotion.hasExitTime = false;
wait2emotion.AddCondition(AnimatorConditionMode.Greater, 0.8f, _emotion_list[i]);
var emotion2wait = new UnityEditor.Animations.AnimatorStateTransition();
emotion2wait.destinationState = waitingState;
emotion2wait.hasExitTime = false;
emotion2wait.AddCondition(AnimatorConditionMode.Less, 0.8f, _emotion_list[i]);
_states[i].AddTransition(emotion2wait);
var emotion2emotion = new UnityEditor.Animations.AnimatorStateTransition();
emotion2emotion.hasExitTime = false;
emotion2emotion.destinationState = _states[i];
emotion2emotion.duration = 0.5f;
emotion2emotion.AddCondition(AnimatorConditionMode.Greater, 0.1f, _emotion_list[i]);
_states[i].AddTransition(emotion2emotion);
waitingState.AddTransition(wait2emotion);
}
}
}