Assignment to ChildAnimatorState.position has no effect
Hi there!
I have a very simple script that is supposed to change the positions of the state nodes in my Animator graph, for example the "New Animation" state in this graph:
I can access the state position as shown in the "GenerateAnimatorGraph" function in the code below. But although the position property is a get/set, I cannot alter the position value -> the Debug.Log gives me an unaltered position:
Is this a bug or how is this supposed to work?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Animations;
{
[ExecuteInEditMode]
public class AnimationManager : MonoBehaviour {
public AnimatorController animatorController;
// Update is called once per frame
void Update () {
if(animatorController == null)
{
return;
}
GenerateAnimatorGraph();
}
void GenerateAnimatorGraph()
{
// Attempt to change the states position
animatorController.layers[0].stateMachine.states[0].position = new Vector3(120, 240, 0);
// Get state position -> is unaltered!!!
Debug.Log(animatorController.layers[0].stateMachine.states[0].position.ToString());
}
}
}
Answer by Linka · Aug 24, 2018 at 06:34 AM
//ChildAnimatorState is ValueType, set position like this
var animator = Selection.activeObject as AnimatorController;
if (animator != null)
{
var baseLayer = animator.layers[0];
baseLayer.stateMachine.entryPosition = new Vector3(132, 324);
baseLayer.stateMachine.anyStatePosition = new Vector3(-60, 24);
var childStates = baseLayer.stateMachine.states;
for (var i = 0; i < childStates.Length; i++)
{
var childState = childStates[i];
Debug.Log(childState.state.name);
childState.position = new Vector3(123,321,0);
childStates[i] = childState;
}
baseLayer.stateMachine.states = childStates;
EditorUtility.SetDirty(animator);
}
AssetDatabase.Refresh();
Answer by BuoyantOtter · Feb 27, 2018 at 10:51 AM
Seems like a bug to me. You can set the position of a ChildAnimatorState if you do it during initialization like so: var state = StateMachine.AddState("state1", new Vector3(400, 100, 0));
Answer by JasonTodd · Jun 25, 2019 at 05:26 AM
Try this...
UnityEngine.Object[] selectedAsset = Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.DeepAssets);
foreach (UnityEngine.Object obj in selectedAsset)
{
if (obj.GetType() != typeof(AnimatorController))
{
continue;
}
AnimatorController controller = obj as AnimatorController;
AnimatorControllerLayer controllerLayer = controller.layers[0];
AnimatorStateMachine stateMachine = controllerLayer.stateMachine;
// 1. Create an array in order to hold all childStates.
ChildAnimatorState[] childStates = new ChildAnimatorState[stateMachine.states.Length];
for (int i = 0; i < stateMachine.states.Length; i++)
{
// 2. Assign origin state. ChildAnimatorState is a Struct so each 'childState' is a new one.
childStates[i] = stateMachine.states[i];
// 3. Change new childState's position.
childStates[i].position = new Vector3(100, 0, 0); // Set your positions.
}
// 4. ChildAnimatorState is Struct so we need to assign 'childStates' back to stateMachine.states.
stateMachine.states = childStates;
EditorUtility.SetDirty(controller);
}
AssetDatabase.Refresh();
AssetDatabase.SaveAssets();
Your answer
Follow this Question
Related Questions
Why am I getting this strange behaviour? 1 Answer
How to properly import mesh C# Editor 1 Answer
Pre-populated UnityEvent style list from GetComponents on GameObject 0 Answers
UnityEvent.Invoke() causing ArgumentOutOfRangeException 0 Answers
Can't find Animator State/Invalid Layer Index in child object inside prefab 0 Answers