
How do you make the blend tree “separate”?
When a I create a blend tree in an animation controller nothing shows up in the assets.

How do you make the blend tree “separate”?
When a I create a blend tree in an animation controller nothing shows up in the assets.
I believe that a blend tree is embedded in the animation controller and can’t be created on his own as an asset.
You might want to take a look at animation controller override asset instead.
Hmm, that doesn’t seem to be it, I need the BlendTree to be an asset so it can be referenced by another script’s public BlendTree tree property. I managed to create one by just copying the asset data, but I couldn’t find a way to create one through the editor.
Well accessing the BlendTree through a script and having it as an asset are two different things.
Here’s a thread that talks about that:
What are you trying to do with that blend tree?
I’m following Unity.Animation samples along and this is the pattern they seem to follow.
public class AnimationAuthor : MonoBehaviour, IConvertGameObjectToEntity, IDeclareReferencedPrefabs
{
public BlendTree BlendTree;
public GameObject RigPrefab;
public void Convert(Entity entity, EntityManager manager, GameObjectConversionSystem converter)
{
...
var blendTreeIndex = BlendTreeConversion.Convert(BlendTree, rigEntity, manager, bakeOptions);
manager.AddComponentData(rigEntity, new BlendTreeIndex { Value = blendTreeIndex });
}
}
It seems to be how they get UnityEngine animations into the ECS world
From there the inputs to the blend tree are generated by a data flow graph (I think)
I’m honestly not sure about all that. The only thing I know is that you can create a blend tree in an asset in advance and override the animations using the “animation controller override” asset. That’s what I do.
[MenuItem("Assets/Create/Blend Tree")]
private static void CreateBlendTree()
{
var asset = new BlendTree();
MethodInfo _tryGetActiveFolderPath = typeof(ProjectWindowUtil).GetMethod("TryGetActiveFolderPath", BindingFlags.Static | BindingFlags.NonPublic);
object[] args = new object[] { null };
bool found = (bool)_tryGetActiveFolderPath.Invoke(null, args);
string path = (string)args[0];
if (found)
{
path += "/" + $"{ObjectNames.GetUniqueName(new[] { "NewBlendTree" }, "NewBlendTree")}.asset";
AssetDatabase.CreateAsset(asset, path);
}
}
The post above no longer works as of 2022.3.62 - here’s an updated version:
using System.Reflection;
using System.Linq;
using System.IO;
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine;
namespace Assets
{
public static class MenuItems
{
[MenuItem("Assets/Create/Blend Tree")]
private static void CreateBlendTree()
{
var asset = new BlendTree();
MethodInfo _tryGetActiveFolderPath = typeof(ProjectWindowUtil).GetMethod("TryGetActiveFolderPath", BindingFlags.Static | BindingFlags.NonPublic);
object[] args = new object[] { null };
bool found = (bool)_tryGetActiveFolderPath.Invoke(null, args);
string path = (string)args[0];
if (found)
{
path += "/" + $"{ObjectNames.GetUniqueName(new[] { "NewBlendTree" }, "NewBlendTree")}.asset";
AssetDatabase.CreateAsset(asset, path);
}
}
[MenuItem("Assets/Extract Blend Trees")]
private static void ExtractBlendTrees()
{
Selection.objects
.Cast<Object>()
.Where(EditorUtility.IsPersistent)
.Select(AssetDatabase.GetAssetPath)
.SelectMany(AssetDatabase.LoadAllAssetsAtPath)
.Where(a => a is BlendTree)
.ToList()
.ForEach(a =>
{
string path = AssetDatabase.GetAssetPath(a);
var newAsset = Object.Instantiate(a);
path = ObjectNames.GetUniqueName(new[] { path }, path);
path = Path.ChangeExtension(path, "asset");
AssetDatabase.CreateAsset(newAsset, path);
});
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}
}