Skip to content

Instantly share code, notes, and snippets.

@muzudho
Last active January 23, 2017 07:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save muzudho/a98843a7b64491ff55762afb6f90436c to your computer and use it in GitHub Desktop.
Save muzudho/a98843a7b64491ff55762afb6f90436c to your computer and use it in GitHub Desktop.
UnityEditorを使って2D格闘(2D Fighting game)作るときのモーション遷移図作成の半自動化に挑戦しよう<その2> ref: http://qiita.com/muzudho1/items/8455c0c7a26d5788b541
// アニメーター・コントローラーの取得例。
// AnimatorController ac = (AnimatorController)AssetDatabase.LoadAssetAtPath<AnimatorController>("Assets/Resources/AnimatorControllers/AniCon@Char3.controller");
void ScanRecursive(List<AnimatorStateMachine> aStateMachineList, AnimatorStateMachine aStateMachine)
{
aStateMachineList.Add(aStateMachine);
foreach (ChildAnimatorStateMachine caStateMachine in aStateMachine.stateMachines)
{
ScanRecursive(aStateMachineList, caStateMachine.stateMachine);
}
}
void ScanAnimatorController(AnimatorController ac, out string resultMessage)
{
Debug.Log("States Scanning...☆(^~^)");
layersTabel.Clear();
statesTabel.Clear();
transitionsTabel.Clear();
conditionsTabel.Clear();
positionsTabel.Clear();
foreach (AnimatorControllerLayer layer in ac.layers)//レイヤー
{
LayerRecord layerRecord = new LayerRecord(layersTabel.Count, layer);
layersTabel.Add(layerRecord);
// ステート・マシン
List<AnimatorStateMachine> stateMachineList = new List<AnimatorStateMachine>();
ScanRecursive(stateMachineList, layer.stateMachine);
foreach (AnimatorStateMachine stateMachine in stateMachineList)
{
MachineStateRecord stateMachineRecord = new MachineStateRecord(layersTabel.Count, stateMachinesTabel.Count, stateMachine, positionsTabel);
stateMachinesTabel.Add(stateMachineRecord);
foreach (ChildAnimatorState caState in stateMachine.states)
{
StateRecord stateRecord = new StateRecord(layersTabel.Count, stateMachinesTabel.Count, statesTabel.Count, caState, positionsTabel);
statesTabel.Add(stateRecord);
foreach (AnimatorStateTransition transition in caState.state.transitions)
{
TransitionRecord transitionRecord = new TransitionRecord(layersTabel.Count, stateMachinesTabel.Count, statesTabel.Count, transitionsTabel.Count, transition);
transitionsTabel.Add(transitionRecord);
foreach (AnimatorCondition aniCondition in transition.conditions)
{
ConditionRecord conditionRecord = new ConditionRecord(layersTabel.Count, stateMachinesTabel.Count, statesTabel.Count, transitionsTabel.Count, conditionsTabel.Count, aniCondition);
conditionsTabel.Add(conditionRecord);
} // コンディション
}//トランジション
}//ステート
}
}//レイヤー
resultMessage = "Scanned☆(^▽^)";
Debug.Log(resultMessage);
}
AnimatorState state = AinmationControllerOperation.LookupState(ac, 0, "Base Layer", "SMove");
state.tag = "tamesi(^q^)";
AnimatorState state = AinmationControllerOperation.LookupState(ac, "0/Base Layer/SMove");
state.tag = "tamesi(^q^)";
AnimatorState[] states = AinmationControllerOperation.LookupState(ac, "0/*/JMove1");
foreach( AnimatorState state in states )
{
state.tag = "tamesi(^q^)";
}
using UnityEditor.Animations;
using UnityEngine;
public abstract class AinmatorControllerOperation
{
[MenuItem("(^_^)Menu/Set Tag13")]
static void SetTag()
{
// アニメーター・コントローラーを取得。
AnimatorController ac = (AnimatorController)AssetDatabase.LoadAssetAtPath<AnimatorController>("Assets/Resources/AnimatorControllers/AniCon@Char3.controller");
AnimatorState state = AinmatorControllerOperation.LookupState(ac, "Base Layer.JMove.JMove0");
state.tag = "tamesi(^q^)5";
}
/// <summary>
/// ノードの最初の1つは レイヤー番号
/// </summary>
public const int ROOT_NODE_IS_LAYER = 1;
/// <summary>
/// ノードの最後の1つは ステート名
/// </summary>
public const int LEAF_NODE_IS_STATE = -1;
/// <summary>
/// パスを指定すると ステートを返す。
/// </summary>
/// <param name="path">"Base Layer.JMove.JMove0" といった文字列。</param>
public static AnimatorState LookupState(AnimatorController ac, string path)
{
string[] nodes = path.Split('.');
// [0~length-2] ステートマシン名
// [length-1] ステート名
if ( nodes.Length < 2){ throw new UnityException("ノード数が2つ未満だったぜ☆(^~^) レイヤー番号か、ステート名は無いのかだぜ☆?"); }
// 最初の名前[0]は、レイヤーを検索する。
AnimatorStateMachine currentMachine = null;
foreach (AnimatorControllerLayer layer in ac.layers)
{
if (nodes[0] == layer.name) { currentMachine = layer.stateMachine; break; }
}
if (null == currentMachine) { throw new UnityException("見つからないぜ☆(^~^)nodes=[" + string.Join("][", nodes) + "]"); }
if (2<nodes.Length) // ステートマシンが途中にある場合、最後のステートマシンまで降りていく。
{
currentMachine = GetLeafMachine(currentMachine, nodes);
if (null == currentMachine) { throw new UnityException("無いノードが指定されたぜ☆(^~^)9 currentMachine.name=[" + currentMachine.name + "] nodes=[" + string.Join("][", nodes)+"]"); }
}
return GetChildState(currentMachine, nodes[nodes.Length - 1]); // レイヤーと葉だけの場合
}
/// <summary>
/// 分かりづらいが、ノードの[1]~[length-1]を辿って、最後のステートマシンを返す。
/// </summary>
private static AnimatorStateMachine GetLeafMachine(AnimatorStateMachine currentMachine, string[] nodes)
{
for (int i = ROOT_NODE_IS_LAYER; i < nodes.Length + LEAF_NODE_IS_STATE; i++)
{
currentMachine = GetChildMachine(currentMachine, nodes[i]);
if (null == currentMachine) { throw new UnityException("無いノードが指定されたぜ☆(^~^)10 i=[" + i + "] node=[" + nodes[i] + "]"); }
}
return currentMachine;
}
private static AnimatorStateMachine GetChildMachine(AnimatorStateMachine machine, string childName)
{
foreach (ChildAnimatorStateMachine wrapper in machine.stateMachines)
{
if (wrapper.stateMachine.name == childName) { return wrapper.stateMachine; }
}
return null;
}
private static AnimatorState GetChildState(AnimatorStateMachine machine, string stateName)
{
foreach (ChildAnimatorState wrapper in machine.states)
{
if (wrapper.state.name == stateName) { return wrapper.state; }
}
return null;
}
}
[MenuItem("(^_^)Menu/Add Transition 1")]
static void AddTransition()
{
// アニメーター・コントローラーを取得。
AnimatorController ac = (AnimatorController)AssetDatabase.LoadAssetAtPath<AnimatorController>("Assets/Resources/AnimatorControllers/AniCon@Char3.controller");
AinmatorControllerOperation.AddTransition(ac, "Base Layer.JMove.Tamesi1 0", "Base Layer.JMove.Tamesi1");
}
#region トランジション
/// <summary>
/// パスを指定すると トランジションを返す。
/// </summary>
/// <param name="path">"Base Layer.JMove.JMove0" といった文字列。</param>
public static AnimatorStateTransition LookupTransition(AnimatorController ac, string path_src, string path_dst )
{
AnimatorState state_src = LookupState(ac, path_src);
AnimatorState state_dst = LookupState(ac, path_dst);
foreach (AnimatorStateTransition transition in state_src.transitions)
{
if(transition.destinationState.name == state_dst.name)
{
return transition;
}
}
return null;
}
/// <summary>
/// パスを指定すると トランジションを返す。
/// </summary>
/// <param name="path">"Base Layer.JMove.JMove0" といった文字列。</param>
public static void AddTransition(AnimatorController ac, string path_src, string path_dst)
{
AnimatorState state_src = LookupState(ac, path_src);
AnimatorState state_dst = LookupState(ac, path_dst);
state_src.AddTransition(state_dst);
}
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment