Hello,
I am working on an editor script to automatically setup an animation controller in a specific way for myself. I have it all working correctly except for when I reload the project, the states and the transitions are gone (The layers are still there though). Below are images of what happens before and after I reload the editor.
Some help on troubleshooting this would be greatly appreciated. I’m sure it has something to so with my modifying a copy without setting it to the original or something, just can’t seem to fond it.
Thank you!
Before:
After reload:
Code:
private void ApplyToAnimator()
{
foreach (var toggle in Toggles)
{
// Check if the parameter or layer already exists. If not, add parameter
bool existParam = doesNameExistParam(toggle.toggleName + "Toggle", controller.parameters);
if (existParam == false)
{
controller.AddParameter(toggle.toggleName + "Toggle", AnimatorControllerParameterType.Bool);
}
//Check if a layer already Exists with that name. If so, remove and add new one.
bool existLayer = doesNameExistLayer(toggle.toggleName, controller.layers);
if (existLayer)
{
controller.RemoveLayer(controller.layers.Length-1);
}
controller.AddLayer(toggle.toggleName);
//Creating On and Off states
AnimatorState stateOn = new AnimatorState
{
name = "ON",
motion = (Motion)AssetDatabase.LoadAssetAtPath(saveDir + "ToggleAnimations" + $"/On{toggle.toggleName}.anim", typeof(Motion)),
writeDefaultValues = false
};
AnimatorState stateOff = new AnimatorState
{
name = "OFF",
motion = (Motion)AssetDatabase.LoadAssetAtPath(saveDir + "ToggleAnimations" + $"/Off{toggle.toggleName}.anim", typeof(Motion)),
writeDefaultValues = false
};
AnimatorState stateIdle = new AnimatorState
{
name = "Idle",
motion = (Motion)AssetDatabase.LoadAssetAtPath(saveDir + "ToggleAnimations" + $"/Idle{toggle.toggleName}.anim", typeof(Motion)),
writeDefaultValues = true
};
AnimatorController animatorController = controller;
var sm = animatorController.layers[controller.layers.Length - 1].stateMachine;
// Adding created states to controller layer
controller.layers[controller.layers.Length - 1].stateMachine.AddState(stateIdle, new Vector3(300, 0, 0));
controller.layers[controller.layers.Length - 1].stateMachine.AddState(stateOff, new Vector3(100, -110, 0));
controller.layers[controller.layers.Length - 1].stateMachine.AddState(stateOn, new Vector3(300, -220, 0));
// If True, go to ON state.
sm.states[2].state.AddTransition(sm.states[1].state);
sm.states[2].state.transitions[0].AddCondition(AnimatorConditionMode.IfNot, 0, toggle.toggleName + "Toggle");
sm.states[2].state.transitions[0].duration = 0.1f;
// If False, go to Off state.
sm.states[0].state.AddTransition(sm.states[2].state);
sm.states[0].state.transitions[0].AddCondition(AnimatorConditionMode.If, 0, toggle.toggleName + "Toggle");
sm.states[0].state.transitions[0].duration = 0.1f;
// Go to Idle after Off state immediately.
sm.states[1].state.AddTransition(sm.states[0].state);
sm.states[1].state.transitions[0].duration = 0.1f;
sm.states[1].state.transitions[0].hasExitTime = true;
AssetDatabase.AddObjectToAsset(stateOn, AssetDatabase.GetAssetPath(controller));
AssetDatabase.AddObjectToAsset(stateOff, AssetDatabase.GetAssetPath(controller));
AssetDatabase.AddObjectToAsset(stateIdle, AssetDatabase.GetAssetPath(controller));
//Set Layer Weight
AnimatorControllerLayer[] layers = controller.layers;
layers[controller.layers.Length - 1].defaultWeight = 1;
controller.layers = layers;
}
AssetDatabase.SaveAssets();
}
private void Postprocessing() // Ran at end
{
AssetDatabase.Refresh();
EditorUtility.SetDirty(controller);
AssetDatabase.SaveAssets();
}
Update:
I managed to keep the states on reload by adding this following code:
AssetDatabase.AddObjectToAsset(stateOn, AssetDatabase.GetAssetPath(controller));
AssetDatabase.AddObjectToAsset(stateOff, AssetDatabase.GetAssetPath(controller));
AssetDatabase.AddObjectToAsset(stateIdle, AssetDatabase.GetAssetPath(controller));