- Home /
How to delete a StateMachineBehaviour via Editor Script?
Hi there, I'm building tools to automate creation of complex Animators and would like to be able to remove StateMachineBehaviours on states via script.
I expected that since there is a AddStateMachineBehaviour, there would be a RemoveStateMachineBehaviour, but this does not exist!
Next I tried to get all of the Behaviours on the Animator and call DestroyImmediate on them individually. GetBehaviours works, but DestroyImmediate doesn't appear to do anything.
CustomStateBehaviour[] customStateBehaviour = myAnimator.GetBehaviours< CustomStateBehaviour>();
for (int s = 0; s < customStateBehaviour.Length; s++){
DestroyImmediate(customStateBehaviour[s]);
}
I also tried putting a Destroy function inside the state machine behaviour and calling that instead of DestroyImmediate.
public void DestroySelf(){
DestroyImmediate(this);
}
This doesn't work either. So how exactly can I destroy many StateMachineBehaviours in an Animator controller via Editor code?
Update: Found that GetBehaviours() will return the component itself (the script file) not the instance of it on an State$$anonymous$$achineBehaviour. So, GetBehaviours() is likely the wrong way to get these states.
Answer by ryanmillerca · Aug 20, 2018 at 07:32 PM
Figured it out! Needed to get states in a different way, and to set allowDestroyingAssets to true on DestroyImmediate.
// get animator controller from animator
UnityEditor.Animations.AnimatorController ac = (UnityEditor.Animations.AnimatorController)myAnimator.runtimeAnimatorController;
UnityEditor.Animations.AnimatorStateMachine sm = ac.layers[0].stateMachine;
// iterate through states inside controller
for (int i = 0; i < sm.states.Length; i++) {
// pull the state out
UnityEditor.Animations.ChildAnimatorState childAnimState = sm.states[i];
// iterate through them
foreach (StateMachineBehaviour stateMachBehs in childAnimState.state.behaviours){
// compare the type with the type we want to destroy
if (stateMachBehs is DestroyThisTypeOfStateBehaviour){
DestroyImmediate(stateMachBehs, true);
}
}
}
// needed to see results
AssetDatabase.Refresh();
This solution gives some odd behaviour (state shows up as invalid/missing until you de-select and re-select the animator and some odd logging stuff), so there may be room for improvement. It's clear that the API isn't interested in accommodating this.
See here https://stackoverflow.com/questions/42789614/unity-how-to-use-editor-script-to-remove-statemachinebehaviour I tried both; I think just reassigning the array is cleaner, as the behaviour refs will be GC'd anyways, and you don't get the inspector trying to display null refs.