Skip to content

Instantly share code, notes, and snippets.

@esnya
Last active March 23, 2023 21:17
Show Gist options
  • Save esnya/eed64d3e192aa3c4158c7ad2855e04df to your computer and use it in GitHub Desktop.
Save esnya/eed64d3e192aa3c4158c7ad2855e04df to your computer and use it in GitHub Desktop.
AnimatorControllerLayerをコピーするやつ。Editorフォルダの下に入れること。
#if UNITY_EDITOR
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
using UnityEditor.Animations;
namespace EsnyaFactory {
public class AnimatorUtilities : EditorWindow
{
[MenuItem("EsnyaFactory/AnimatorTools")]
static void Init()
{
AnimatorUtilities window = (AnimatorUtilities)EditorWindow.GetWindow(typeof(AnimatorUtilities));
window.Show();
}
public enum OverrideBehavior {
DoNothing,
Override,
Add,
}
AnimatorController sourceAnimator;
AnimatorOverrideController sourceAnimatorOverrideController;
AnimatorController destinationAnimator;
Dictionary<int, bool> copyLayer = new Dictionary<int, bool>();
Dictionary<int, bool> copyParameter = new Dictionary<int, bool>();
OverrideBehavior overrideBehavior;
void OnGUI()
{
sourceAnimator = (AnimatorController)EditorGUILayout.ObjectField("Source (Animator)", (Object)sourceAnimator, typeof(AnimatorController), false);
sourceAnimatorOverrideController = (AnimatorOverrideController)EditorGUILayout.ObjectField("Source (Animator Override Controller)", (Object)sourceAnimator, typeof(AnimatorController), false);
destinationAnimator = (AnimatorController)EditorGUILayout.ObjectField("Destination", (Object)destinationAnimator, typeof(AnimatorController), false);
sourceAnimatorOverrideController.ApplyOverride();
EditorGUILayout.BeginVertical(GUI.skin.box);
EditorGUILayout.LabelField("Copy Layer(s)");
if (sourceAnimator) {
for (int i = 0; i < sourceAnimator.layers.Length; i++ ) {
copyLayer[i] = EditorGUILayout.Toggle(sourceAnimator.layers[i].name, copyLayer.ContainsKey(i) ? copyLayer[i] : false);
}
}
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(GUI.skin.box);
EditorGUILayout.LabelField("Copy Parameter(s)");
if (sourceAnimator) {
for (int i = 0; i < sourceAnimator.parameters.Length; i++ ) {
copyParameter[i] = EditorGUILayout.Toggle(sourceAnimator.parameters[i].name, copyParameter.ContainsKey(i) ? copyParameter[i] : false);
}
}
EditorGUILayout.EndVertical();
overrideBehavior = (OverrideBehavior)EditorGUILayout.EnumPopup(overrideBehavior);
EditorGUI.BeginDisabledGroup(sourceAnimator == null || destinationAnimator == null);
if (GUILayout.Button("Copy")) {
ExecuteCopy(overrideBehavior);
}
EditorGUI.EndDisabledGroup();
}
IEnumerable<T> CopyList<T>(
IEnumerable<T> dst,
IEnumerable<T> src,
System.Func<T, T, bool> predicate,
System.Action<T, T> copy,
OverrideBehavior overrideBehavior
) {
var overrided = dst.Select(oldItem => {
if (overrideBehavior == OverrideBehavior.Override) {
var item = src.FirstOrDefault(a => predicate(a, oldItem));
if (item != null) {
copy(oldItem, item);
}
}
return oldItem;
});
var added = src.Where(item => {
if (overrideBehavior == OverrideBehavior.Add) {
return true;
}
if (overrideBehavior == OverrideBehavior.DoNothing) {
return false;
}
return dst.FirstOrDefault(oldItem => predicate(item, oldItem)) == null;
});
return overrided.Concat(added);
}
void ExecuteCopy(OverrideBehavior overrideBehavior)
{
var parameters = sourceAnimator.parameters.Where((parameter, i) => copyParameter.ContainsKey(i) && copyParameter[i]);
var layers = sourceAnimator.layers.Where((layer, i) => copyLayer.ContainsKey(i) && copyLayer[i]);
destinationAnimator.parameters = CopyList(
destinationAnimator.parameters,
parameters,
(a, b) => a.name == b.name,
(dst, src) => {
dst.type = src.type;
dst.type = src.type;
dst.defaultBool = src.defaultBool;
dst.defaultFloat = src.defaultFloat;
dst.defaultInt = src.defaultInt;
},
overrideBehavior
).ToArray();
destinationAnimator.layers = CopyList(
destinationAnimator.layers,
layers,
(a, b) => a.name == b.name,
(dst, src) => {
dst.avatarMask = src.avatarMask;
dst.blendingMode = src.blendingMode;
dst.defaultWeight = src.defaultWeight;
dst.iKPass = src.iKPass;
dst.stateMachine = src.stateMachine;
dst.syncedLayerAffectsTiming = src.syncedLayerAffectsTiming;
dst.syncedLayerIndex = src.syncedLayerIndex;
},
overrideBehavior
).ToArray();
}
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment