Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved Creating Animator Controller Asset in Code

Discussion in 'Scripting' started by magique, Aug 6, 2022.

  1. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    I'm using the following method to create a new Animator Controller asset in the project.

    AnimatorController.CreateAnimatorControllerAtPath(fullFileName);

    After creating the asset, I add states, blend trees, and all the motions and transitions. The controller looks fine and the character model animates and performs as expected. However, as soon as I close the project and re-load it, all the blend trees and motions are wiped out and I have just the top level states and transitions. Any idea why this won't remain persistent?

    I've tried all of the following things, but nothing allows the blend trees and motions to remain after closing the project:

    Saving the Project

    EditorUtility.SetDirty(animator.runtimeAnimatorController);
    AssetDatabase.SaveAssetIfDirty(animator.runtimeAnimatorController);

    AssetDatabase.SaveAssets();
    AssetDatabase.Refresh();

    Is this by design that these things can't be saved permanently?
     
  2. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    Some more information. If I do the following on the new controller:

    Code (CSharp):
    1.   var stateMachineA = rootStateMachine.AddStateMachine("Idle");
    2.             var state = stateMachineA.AddState("Idle");
    3.             state.motion = idleAnimations[0].clip;

    This successfully creates a state machine with a substate that has an idle animation. This is actually persisted. when I close and reload the project. So, I'm thinking it must have to do with the way I'm creating the other stuff.

    Here's an example of how the other stuff is added that doesn't persist:

    Code (CSharp):
    1.                 AnimatorState idleState = rootStateMachine.AddState("Idle");
    2.                 var blendTree = new BlendTree();
    3.                 blendTree.name = "Idle States";
    4.                 blendTree.blendParameter = "IdleNum";
    5.                 blendTree.useAutomaticThresholds = false;
    6.                 blendTree.minThreshold = 0f;
    7.                 blendTree.maxThreshold = idleAnimations.Count;
    8.                 int i = 0;
    9.                 foreach (var anim in idleAnimations)
    10.                 {
    11.                     blendTree.AddChild(anim.clip, i++);
    12.                 } // foreach
    13.  
    14.                 idleState.motion = blendTree;
    The one that works is a state machine while the one that doesn't is just a state.
     
    Last edited: Aug 6, 2022
  3. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    OK, so I figured this out. For anyone who has a similar issue, here is the modified code that actually works:

    Code (CSharp):
    1.                 BlendTree blendTree;
    2.                 AnimatorState idleState = idleState = _controller.CreateBlendTreeInController("Idle States", out blendTree);
    3.                 blendTree.name = "Idle States";
    4.                 blendTree.blendParameter = "IdleNum";
    5.                 blendTree.useAutomaticThresholds = false;
    6.                 blendTree.minThreshold = 0f;
    7.                 blendTree.maxThreshold = idleAnimations.Count;
    8.                 int i = 0;
    9.                 foreach (var anim in idleAnimations)
    10.                 {
    11.                     blendTree.AddChild(anim.clip, i++);
    12.                 } // foreach
     
    Last edited: Aug 6, 2022
    ebfash and adamgolden like this.
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    magique likes this.