Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
4
Question by Paulius-Liekis · Dec 20, 2010 at 09:30 AM · animationvariablebind

How to rebind animated variable?

Let's say I animate a variable of my script in Unity animation editor. Then if I rename that variable in my script - I loose all animation curves related to that variable. Is there a way to "rebind" those animation curves to renamed variable?

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image DanielSevelt · Mar 30, 2015 at 08:53 PM 0
Share

Thank you to those who contributed in the evolution towards this final and handy script. I had this exact issue and this saved me hours and hours of work.

5 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Paulius-Liekis · Apr 18, 2012 at 09:12 AM

The only way is to write a script which finds that specific curve and adds a new curve with new variable name.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Datael · May 24, 2012 at 08:36 AM 0
Share

Are you aware of a source for said script and/or are you willing to share, perchance? Thanks!

avatar image Paulius-Liekis · May 29, 2012 at 08:50 AM 0
Share

@Datael: no, I don't have that script. But it's possible by writing editor script. You need to use AnimationUtils which gives you access to individual curves of AnimationClip.

avatar image Datael · May 29, 2012 at 08:59 AM 1
Share

I actually wrote my own script doing what I needed for me a few hours after I replied. Thanks for the information!

Just in case anyone else wants it, it's a really simple window, it's probably buggy etc, so use with caution, but it could be a decent base for a more real tool to do this:

 using UnityEngine;
 using UnityEditor;
 using System.Collections;
 using System.Collections.Generic;
 
 public class AnimationTargetRenamer : EditorWindow {
     
     [$$anonymous$$enuItem("Window/Animation Target Renamer")]
     public static void OpenWindow() {
         GetWindow<AnimationTargetRenamer>("Animation Target Renamer");
     }
     
     void Update() {
         Repaint();
     }
     
     void OnGUI() {
         
         GameObject go = Selection.activeGameObject;
         
         if (go != null && go.animation != null) {
             Animation ani = go.animation;
             AnimationClipCurveData[] curveDatas = AnimationUtility.GetAllCurves(ani.clip, true);
             
             List<string> targetObjectPaths = new List<string>();
             foreach (var curveData in curveDatas) {
                 if (!targetObjectPaths.Contains(curveData.path)) {
                     targetObjectPaths.Add(curveData.path);
                 }
             }
             
             Dictionary<string, string> newNames = new Dictionary<string, string>();
             foreach (var target in targetObjectPaths) {
                 string newName = GUILayout.TextField(target);
                 if (newName != target) {
                     newNames.Add(target, newName);
                 }
             }
             
             foreach (var pair in newNames) {
                 string oldName = pair.$$anonymous$$ey;
                 string newName = pair.Value;
                 
                 foreach (var curveData in curveDatas) {
                     if (curveData.path == oldName) {
                         curveData.path = newName;
                     }
                 }
             }
             
             if (newNames.Count > 0) {
                 ani.clip.ClearCurves();
                 foreach (var curveData in curveDatas) {
                     ani.clip.SetCurve(curveData.path, curveData.type, curveData.propertyName, curveData.curve);
                 }
             }
             
         } else {
             GUILayout.Label("Please select an object with an animation.");
         }
         
     }
     
 }
avatar image
7

Answer by cymatist · Oct 18, 2013 at 03:14 PM

Thank you! Here is a further development of your code, debugged, cleaned up, and this time for C#.

 using UnityEngine;
 using UnityEditor;
 using System;
 using System.Collections;
 using System.Collections.Generic;
 
 /// <summary>
 /// Animation target renamer.
 /// This script allows animation curves to be moved from one target to another.
 /// 
 /// Usage:
 ///     1) Select the gameobject whose curves you wish to move.
 ///     2) Ensure that the animation to be modified is the default animation on the game object.
 ///     3) Open the Animation Target Renamer from the Window menu in the Unity UI.
 ///     4) Change the names in the textboxes on the right side of the window to the names of the objects you wish to move the animations to.
 ///         NOTE: if the objects do not exist, the original objects will be duplicated and renamed.     
 ///     5) Select whether or not the old object should be deleted.
 ///     6) Press Apply.
 /// </summary>
 public class AnimationTargetRenamer : EditorWindow
 {
     /// <summary>
     /// The animation whose curves to change.
     /// </summary>
     private static Animation ani;
     
     /// <summary>
     /// The curve data for the animation.
     /// </summary>
     private static AnimationClipCurveData[] curveDatas;
 
     /// <summary>
     /// The new animation clip.
     /// </summary>
     private static AnimationClip newClip;
     
     /// <summary>
     /// Whether or not the curve data is currently initialized.
     /// </summary>
     private static bool initialized = false;
     
     /// <summary>
     /// Whether or not to delete the old names of objects.
     /// </summary>
     private static bool deleteOldObjects = false;
     
     /// <summary>
     /// The names of the original GameObjects.
     /// </summary>
     private static List<string> origObjectPaths;
     
     
     /// <summary>
     /// The names of the target GameObjects.
     /// </summary>
     private static List<string> targetObjectPaths;
     
     [MenuItem("Window/Animation Target Renamer")]
     public static void OpenWindow ()
     {
         AnimationTargetRenamer window = (AnimationTargetRenamer)GetWindow<AnimationTargetRenamer> ("Animation Target Renamer");
         initialized = false;
     }
     
     void OnGUI ()
     {
          // find the game object we're working on.
         GameObject go = Selection.activeGameObject;
         
         if (!initialized) {
             
             // If the object isn't set or doesn't have an animation,
             /// we can't initialize the cuve data, so do nothing.
             if (go != null && go.animation != null) {
             
                 // if we haven't looked at the curve data, do so now, 
                 // and initialize the list of original object paths.
                 ani = go.animation;
             
                 curveDatas = AnimationUtility.GetAllCurves (ani.clip, true);
                 
                 origObjectPaths = new List<string> ();
                 foreach (AnimationClipCurveData curveData in curveDatas) {
                     if (!origObjectPaths.Contains (curveData.path)) {
                         origObjectPaths.Add (curveData.path);
                     }
                 }
                 initialized = true;
             }
             
         } 
         
         if (go != null && go.animation != null) {
             // if we got here, we have all the data we need to work with,
             // so we should be able to build the UI.
             
             targetObjectPaths = new List<string> ();
             
             foreach (AnimationClipCurveData curveData in curveDatas) {
                 if (!targetObjectPaths.Contains (curveData.path)) {
                     // if we haven't already added a target, add it to the list.
                     targetObjectPaths.Add (curveData.path);
                 }
             }
             
             
             // build the list of textboxes for renaming.
             Dictionary<string, string> newNames = new Dictionary<string, string> ();
                         
             for (int t=0; t<targetObjectPaths.Count; t++) {
                 string newName = EditorGUILayout.TextField (origObjectPaths [t], targetObjectPaths [t]);
                 
                 if (newName != targetObjectPaths [t]) {
                     newNames.Add (targetObjectPaths [t], newName);
                 }
                 
             }
             
             // set the curve data to the new values.    
             foreach (KeyValuePair<string,string> pair in newNames) {
                 string oldName = pair.Key;
                 string newName = pair.Value;
                 
                 foreach (var curveData in curveDatas) {
                     if (curveData.path == oldName) {
                         curveData.path = newName;
                     }
                 }
             }
             
             // display the check box with the option to delete old objects.
             deleteOldObjects = EditorGUILayout.Toggle("Delete old objects", deleteOldObjects);
              
         } else {
             GUILayout.Label ("Please select an object with an animation.");
             initialized = false;
         }        
         
         
         if (GUILayout.Button ("Apply")) {
             
             // get the actual gameobjects we're working on.
             List<GameObject> originalObjects = new List<GameObject>();
             List<GameObject> targetObjects = new List<GameObject>();
             
             for(int i =0; i < origObjectPaths.Count; i++) {
                 originalObjects.Add(GameObject.Find(origObjectPaths[i]));
                 
                 GameObject target = GameObject.Find(targetObjectPaths[i]);
                 if(target == null) 
                 {
                     // If the target object doesn't exist, duplicate the source object,
                     // and rename it.
                     target = GameObject.Instantiate(originalObjects[i]) as GameObject;    
                     target.name = targetObjectPaths[i];
                     target.transform.parent = originalObjects[i].transform.parent;
                 }
                 targetObjects.Add(target);
             
             }
             
             // set up the curves based on the new names.
             ani.clip.ClearCurves ();
             foreach (var curveData in curveDatas) {
                 ani.clip.SetCurve (curveData.path, curveData.type, curveData.propertyName, curveData.curve);
             }
             origObjectPaths.Clear ();
             foreach (AnimationClipCurveData curveData in curveDatas) {
                 if (!origObjectPaths.Contains (curveData.path)) {
                     origObjectPaths.Add (curveData.path);
                 }
                 
             }
             
             // if necessary, delete the old objects.
             if(deleteOldObjects) {
                 for(int i = 0; i < originalObjects.Count; i++) {
                     if(originalObjects[i] != targetObjects[i]) {
                         DestroyImmediate(originalObjects[i]);    
                     }
                 }
             }
         }
     }
      
 }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Ben-BearFish · Aug 25, 2014 at 10:20 PM 0
Share

Any chance there is a way to do this with the Animator component?

avatar image
6

Answer by secondbreakfast · Sep 12, 2014 at 10:39 PM

I took the script that cymatist wrote, cleaned it up and made it work directly on an Animation Clip (and it doesn't do the game object modifications as such). The result is that you can edit Animation Clips for both Animation and Animators.

 using UnityEngine;
 using UnityEditor;
 using System;
 using System.Collections;
 using System.Collections.Generic;
 
 /// <summary>
 /// Animation clip target renamer.
 /// This script allows animation curves to be moved from one target to another.
 /// 
 /// Usage:
 ///     1) Open the Animation Clip Target Renamer from the Window menu in the Unity UI.
 ///     2) Select the animation clip whose curves you wish to move.
 ///     3) Change the names in the textboxes on the right side of the window to the names of the objects you wish to move the animations to.
 ///     4) Press Apply.
 /// </summary>
 public class AnimationClipTargetRenamer : EditorWindow
 {
     
     public AnimationClip selectedClip;
 
     
     /// <summary>
     /// The curve data for the animation.
     /// </summary>
     private AnimationClipCurveData[] curveDatas;
     
     /// <summary>
     /// The names of the original GameObjects.
     /// </summary>
     private List<string> origObjectPaths;
     
     
     /// <summary>
     /// The names of the target GameObjects.
     /// </summary>
     private List<string> targetObjectPaths;
 
     private bool initialized;
     
     [MenuItem("Window/Animation Clip Target Renamer")]
     public static void OpenWindow ()
     {
         AnimationClipTargetRenamer renamer = GetWindow<AnimationClipTargetRenamer> ("Animation Clip Target Renamer");
         renamer.Clear();
     }
 
     private void Initialize() {
 
         curveDatas = AnimationUtility.GetAllCurves(selectedClip, true);
         
         origObjectPaths = new List<string>();
         targetObjectPaths = new List<string>();
         foreach (AnimationClipCurveData curveData in curveDatas) {
             if (curveData.path != "" && !origObjectPaths.Contains(curveData.path)) {
                 origObjectPaths.Add(curveData.path);
                 targetObjectPaths.Add(curveData.path);
             }
         }
         initialized = true;
     }
 
     private void Clear() {
         curveDatas = null;
         origObjectPaths = null;
         targetObjectPaths = null;
         initialized = false;
     }
 
     private void RenameTargets() {
         // set the curve data to the new values. 
         for (int i=0; i < targetObjectPaths.Count; i++) {
             string oldName = origObjectPaths[i];
             string newName = targetObjectPaths[i];
             
             if (oldName != newName) {
                 foreach (var curveData in curveDatas) {
                     if (curveData.path == oldName) {
                         curveData.path = newName;
                     }
                 }
             }
         }
         
         // set up the curves based on the new names.
         selectedClip.ClearCurves();
         foreach (var curveData in curveDatas) {
             selectedClip.SetCurve(curveData.path, curveData.type, curveData.propertyName, curveData.curve);
         }
         Clear();
         Initialize();
     }
 
     void OnGUIShowTargetsList() {
         // if we got here, we have all the data we need to work with,
         // so we should be able to build the UI.
         
         // build the list of textboxes for renaming.
         if (targetObjectPaths != null) {
             EditorGUILayout.Space();
             EditorGUIUtility.labelWidth = 250;
 
             for (int i=0; i < targetObjectPaths.Count; i++) {
                 string newName = EditorGUILayout.TextField(origObjectPaths[i], targetObjectPaths[i]);
                 
                 if (targetObjectPaths[i] != newName) {
                     targetObjectPaths[i] = newName;
                 }
             }
         }
     }
     
     void OnGUI() {
         AnimationClip previous = selectedClip;
         selectedClip = EditorGUILayout.ObjectField("Animation Clip", selectedClip, typeof(AnimationClip), true) as AnimationClip;
 
         if (selectedClip != previous) {
             Clear();
         }
 
         if (selectedClip != null) {
             if (!initialized) {
                 Initialize();
             }
 
             EditorGUILayout.BeginHorizontal();
             GUILayout.FlexibleSpace();
             if (GUILayout.Button("Refresh")) {
                 Clear();
                 Initialize();
             }
             EditorGUILayout.EndHorizontal();
 
             OnGUIShowTargetsList();
             
             EditorGUILayout.BeginHorizontal();
             GUILayout.FlexibleSpace();
             if (GUILayout.Button("Apply")) {
                 RenameTargets();
             }
             EditorGUILayout.EndHorizontal();
         }
     }
     
 }
Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image brain56 · Feb 22, 2015 at 07:19 AM 0
Share

Dear @secondbreakfast,

You have saved my life from eternal damnation. I owe you my soul. You will forever be remembered.

Yours truly, brain56

P.S. Is your username supposed to be an LOTR reference?

avatar image secondbreakfast · Feb 22, 2015 at 03:26 PM 1
Share

I'm glad it helped. It really should be built into Unity to reattach broken links. Yes it is a reference from LOTR, how observant of you.

avatar image slake_it · Oct 30, 2016 at 02:50 PM 0
Share

Hi there, thanks for the script, however, I can't find any text boxes on the right side , I assign the animation hit refresh & apply but nothing happens, any ideas on what is the issue ?

avatar image
1

Answer by joao-cabral · Apr 08, 2017 at 11:03 PM

Thank you so much CrazyPanda.

I changed your script so that it allows for multi-clip editing. I also added the feature of removing from the start of the path:

 using UnityEngine;
 using UnityEditor;
 using System;
 using System.Collections;
 using System.Collections.Generic;
 
 public class AnimationPathRenamer : EditorWindow
 {
     private string prependPath;
     private int removeLeft = 0;
     private Vector2 scrollPosition = new Vector2();
     public List<AnimationClip> selectedClips = new List<AnimationClip>();
     public List<List<RemapperCurveData>> CurveDatasList = new List<List<RemapperCurveData>>();
 
     public AnimationClip selectedClip;
     public List<RemapperCurveData> CurveDatas;
     private bool initialized;
 
     [MenuItem("Window/Animation Clip Target Renamer")]
     public static void OpenWindow()
     {
         AnimationPathRenamer renamer = GetWindow<AnimationPathRenamer>("Animation Clip Target Renamer");
         renamer.Clear();
     }
 
     private void Initialize()
     {
         foreach (AnimationClip clip in selectedClips)
         {
             CurveDatas = new List<RemapperCurveData>();
             var curveBindings = AnimationUtility.GetCurveBindings(clip);
 
             foreach (EditorCurveBinding curveBinding in curveBindings)
             {
                 RemapperCurveData cd = new RemapperCurveData();
                 cd.Binding = curveBinding;
                 cd.OldPath = curveBinding.path + "";
                 cd.NewPath = curveBinding.path + "";
                 cd.Curve = new AnimationCurve(AnimationUtility.GetEditorCurve(clip, curveBinding).keys);
                 CurveDatas.Add(cd);
             }
 
             CurveDatasList.Add(CurveDatas);
         }
 
 
         initialized = true;
     }
 
     private void Clear()
     {
         foreach (List<RemapperCurveData> oneCurveData in CurveDatasList)
         {
             oneCurveData.Clear();
         }
         CurveDatasList.Clear();
 
         CurveDatas = null;
         initialized = false;
     }
 
     void OnGUIShowTargetsList()
     {
 
         if (CurveDatasList.Count == 0)
             Initialize();
 
         foreach (List<RemapperCurveData> oneCurveData in CurveDatasList)
         {
             List<string> unique = new List<string>();
             List<RemapperCurveData> uniqueCurveDatas = new List<RemapperCurveData>();
             foreach (RemapperCurveData remap in oneCurveData)
             {
                 if (!unique.Contains(remap.Binding.path))
                 {
                     unique.Add(remap.Binding.path);
                     uniqueCurveDatas.Add(remap);
                 }
             }
 
             if (uniqueCurveDatas != null && uniqueCurveDatas.Count > 0)
             {
                 EditorGUILayout.Space();
                 EditorGUIUtility.labelWidth = 250;
 
                 for (int i = 0; i < uniqueCurveDatas.Count; i++)
                 {
                     string newName = EditorGUILayout.TextField(uniqueCurveDatas[i].OldPath, uniqueCurveDatas[i].NewPath);
 
                     if (uniqueCurveDatas[i].OldPath != newName)
                     {
                         var j = i;
                         oneCurveData.ForEach(x =>
                         {
                             if (x.OldPath == uniqueCurveDatas[j].OldPath)
                             {
                                 x.NewPath = newName;
                             }
                         });
                     }
                 }
             }
         }
 
 
     }
 
     private void RenameTargets()
     {
         for (int i = 0; i < selectedClips.Count; i++)
         {
             CurveDatasList[i].ForEach(x =>
             {
                 if (x.Binding.path != "" && x.OldPath != x.NewPath)
                 {
                     x.Binding.path = x.NewPath;
                     x.OldPath = x.NewPath;
                 }
             });
 
             selectedClips[i].ClearCurves();
 
             foreach (var curveData in CurveDatasList[i])
             {
                 selectedClips[i].SetCurve(curveData.Binding.path, curveData.Binding.type, curveData.Binding.propertyName, curveData.Curve);
             }
         }
 
 
 
 
         Clear();
         Initialize();
     }
 
     public class RemapperCurveData
     {
         public EditorCurveBinding Binding;
         public AnimationCurve Curve;
         public string OldPath;
         public string NewPath;
     }
 
 
 
     void Add()
     {
         foreach (List<RemapperCurveData> oneCurveData in CurveDatasList)
         {
             foreach (RemapperCurveData remCurveData in oneCurveData)
             {
                 string newName = EditorGUILayout.TextField(remCurveData.OldPath, remCurveData.NewPath);
                 remCurveData.NewPath = prependPath + newName;
             }
         }
     }
 
 
     void Remove()
     {
         foreach (List<RemapperCurveData> oneCurveData in CurveDatasList)
         {
             foreach (RemapperCurveData remCurveData in oneCurveData)
             {
                 string newName = remCurveData.NewPath.Substring(removeLeft);
                 remCurveData.NewPath = newName;
             }
         }
     }
 
 
     void OnGUI()
     {
         scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition,
             GUILayout.Width(position.width), GUILayout.Height(position.height)); // Scroll //
 
         int beforeCount = selectedClips.Count;
         DropGUIArea();
         int afterCount = selectedClips.Count;
         if (beforeCount != afterCount)
         {
             EditorGUILayout.EndScrollView();
             return;
         }
         for (int i = 0; i < selectedClips.Count; i++)
         {
             GUILayout.BeginHorizontal();
 
             AnimationClip previous = selectedClips[i];
             selectedClips[i] = EditorGUILayout.ObjectField("Animation Clip", selectedClips[i], typeof(AnimationClip), true) as AnimationClip;
 
             if (selectedClips[i] != previous)
             {
                 Clear();
             }
 
             if (selectedClips[i] != null)
             {
                 if (!initialized)
                 {
                     Initialize();
                 }
             }
 
             else
             {
                 return;
             }
 
             if (GUILayout.Button("Remove", GUILayout.ExpandWidth(false)))
             {
                 selectedClips.RemoveAt(i);
                 Initialize();
             }
 
             GUILayout.EndHorizontal();
         }
 
         EditorGUILayout.Space();
 
         prependPath = EditorGUILayout.TextField("Prepend Path", prependPath);
         if (GUILayout.Button("Add"))
         {
             Clear();
             Initialize();
             Add();
             prependPath = "";
         }
 
         removeLeft = EditorGUILayout.IntField("Remove at Start", removeLeft);
         if (GUILayout.Button("Remove"))
         {
             Clear();
             Initialize();
             Remove();
             removeLeft = 0;
         }
 
 
         EditorGUILayout.BeginHorizontal();
         GUILayout.FlexibleSpace();
         if (GUILayout.Button("Refresh"))
         {
             Clear();
             Initialize();
         }
         EditorGUILayout.EndHorizontal();
 
         OnGUIShowTargetsList();
 
         EditorGUILayout.BeginHorizontal();
         GUILayout.FlexibleSpace();
         if (GUILayout.Button("Apply"))
         {
             RenameTargets();
         }
         EditorGUILayout.EndHorizontal();
 
 
         EditorGUILayout.EndScrollView();
 
 
 
     }
 
 
     void DropGUIArea()
     {
         /// Drag Here //
         Event evt = Event.current;
 
         EditorGUILayout.Space();
 
         Rect drop_area = GUILayoutUtility.GetRect(0.0f, 20.0f, GUILayout.ExpandWidth(true));
         drop_area.x += 15;
         drop_area.width -= (15 + 18);
         GUIStyle estilo = new GUIStyle(GUI.skin.box);
         estilo.normal.textColor = Color.black;
         GUI.Box(drop_area, "Drag Here", estilo);
 
         EditorGUILayout.Space();
 
         switch (evt.type)
         {
             case EventType.DragUpdated:
             case EventType.DragPerform:
                 if (!drop_area.Contains(evt.mousePosition))
                     return;
 
                 DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
 
                 if (evt.type == EventType.DragPerform)
                 {
                     DragAndDrop.AcceptDrag();
 
                     foreach (UnityEngine.Object dragged_object in DragAndDrop.objectReferences)
                     {
                         AnimationClip draggedAnimation = (AnimationClip)dragged_object;
                         selectedClips.Add(draggedAnimation);
                     }
 
                     Initialize();
                 }
                 break;
         }
     }
 }

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by CrazyPanda · Feb 16, 2016 at 01:15 PM

Updated script using LINQ for Unity 5.3 using UnityEngine; using UnityEditor; using System.Collections.Generic; using System.Linq; using PrefabEvolution;

 /// <summary>
 /// Animation clip target remapper.
 /// This script allows animation curves to be moved from one target to another.
 /// 
 /// Usage:
 ///     1) Open the Animation Clip Target Renamer from the Window menu in the Unity UI.
 ///     2) Select the animation clip whose curves you wish to move.
 ///     3) Change the names in the textboxes on the right side of the window to the names of the objects you wish to move the animations to.
 ///     4) Press Apply.
 /// </summary>
 public class AnimationClipTargetRemapper : EditorWindow
 {
 
     public AnimationClip selectedClip;
     public List<RemapperCurveData> CurveDatas;
     private bool initialized;
 
     [MenuItem("Window/Animation Clip Target Renamer")]
     public static void OpenWindow()
     {
         AnimationClipTargetRemapper renamer = GetWindow<AnimationClipTargetRemapper>("Animation Clip Target Renamer");
         renamer.Clear();
     }
 
     private void Initialize()
     {
         CurveDatas = new List<RemapperCurveData>();
         var curveBindings = AnimationUtility.GetCurveBindings(selectedClip);
 
         foreach (EditorCurveBinding curveBinding in curveBindings)
         {
             RemapperCurveData cd = new RemapperCurveData();
             cd.Binding = curveBinding; 
             cd.OldPath = curveBinding.path+"";
             cd.NewPath = curveBinding.path + "";
             cd.Curve = new AnimationCurve(AnimationUtility.GetEditorCurve(selectedClip, curveBinding).keys);
             CurveDatas.Add(cd);
         }
         initialized = true;
     }
 
     private void Clear()
     {
         CurveDatas = null;
         initialized = false;
     }
 
     void OnGUIShowTargetsList()
     {
 
         if (CurveDatas == null) Initialize();
 
         var uniqueCurveDatas = CurveDatas.Where(x=>x.Binding.path!="").GroupBy(g => g.Binding.path).Select(g => g.First()).ToList();
 
         if (uniqueCurveDatas != null && uniqueCurveDatas.Count > 0)
         {
             EditorGUILayout.Space();
             EditorGUIUtility.labelWidth = 250;
 
             for (int i = 0; i < uniqueCurveDatas.Count; i++)
             {
                 string newName = EditorGUILayout.TextField(uniqueCurveDatas[i].OldPath, uniqueCurveDatas[i].NewPath);
 
                 if (uniqueCurveDatas[i].OldPath != newName)
                 {
                     var j = i;
                     CurveDatas.Foreach(x =>
                     {
                         if (x.OldPath == uniqueCurveDatas[j].OldPath)
                         {
                             x.NewPath = newName;
                         }
                     });
                 }
             }
         }
 
 
     }
 
     private void RenameTargets()
     {
         CurveDatas.Foreach(x =>
          {
              if (x.Binding.path != "" && x.OldPath != x.NewPath)
              {
                  x.Binding.path = x.NewPath;
                  x.OldPath = x.NewPath;
              }
          });
 
         selectedClip.ClearCurves();
 
         foreach (var curveData in CurveDatas)
         {
             selectedClip.SetCurve(curveData.Binding.path, curveData.Binding.type, curveData.Binding.propertyName, curveData.Curve);
         }
 
         Clear();
         Initialize();
     }
 
 
     void OnGUI()
     {
         AnimationClip previous = selectedClip;
         selectedClip = EditorGUILayout.ObjectField("Animation Clip", selectedClip, typeof(AnimationClip), true) as AnimationClip;
 
         if (selectedClip != previous)
         {
             Clear();
         }
 
         if (selectedClip != null)
         {
             if (!initialized)
             {
                 Initialize();
             }
 
             EditorGUILayout.BeginHorizontal();
             GUILayout.FlexibleSpace();
             if (GUILayout.Button("Refresh"))
             {
                 Clear();
                 Initialize();
             }
             EditorGUILayout.EndHorizontal();
 
             OnGUIShowTargetsList();
 
             EditorGUILayout.BeginHorizontal();
             GUILayout.FlexibleSpace();
             if (GUILayout.Button("Apply"))
             {
                 RenameTargets();
             }
             EditorGUILayout.EndHorizontal();
         }
     }
 
     public class RemapperCurveData
     {
         public EditorCurveBinding Binding;
         public AnimationCurve Curve;
         public string OldPath;
         public string NewPath;
     }
 }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image markotusan · Mar 07, 2017 at 04:27 PM 0
Share

Thanks Panda! Your script helped me a lot. Didn't compile initially, had to get rid of using PrefabEvolution; and change Foreach to ForEach. Then it compiled and worked. Also, when using it it seemed to have saved my changes to animations even when I did not hit Apply. It is a bit annoying when ctrl-z is not supported.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

8 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to change a variable in the same script? 3 Answers

Is it possible to create a script dinamic like animation>size controling the Elements variables? 1 Answer

Putting animations variables and run? 1 Answer

How do i make a character accelerate and play an animation when the click left-shift 1 Answer

Float var to control animation speed? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges