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?

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*));*

_ GameObject target = GameObject.Find(targetObjectPaths*);_
_
if(target == null)_
_
{_
_
// If the target object doesn’t exist, duplicate the source object,_
_
// and rename it._
_ target = GameObject.Instantiate(originalObjects) as GameObject;
target.name = targetObjectPaths;
target.transform.parent = originalObjects.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 != targetObjects*) {*
_ DestroyImmediate(originalObjects*);
}
}
}
}
}*_

}

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*;*

_ string newName = targetObjectPaths*;*_

* 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_, targetObjectPaths*);*_

_ if (targetObjectPaths != newName) {
targetObjectPaths = 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();*
* }*
* }*

}

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

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_.OldPath, uniqueCurveDatas*.NewPath);*_

if (uniqueCurveDatas*.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*.ForEach(x =>*
{
if (x.Binding.path != “” && x.OldPath != x.NewPath)
{
x.Binding.path = x.NewPath;
x.OldPath = x.NewPath;
}
});

selectedClips*.ClearCurves();*

foreach (var curveData in CurveDatasList*)*
{
selectedClips*.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 oneCurveData in CurveDatasList)
{
foreach (RemapperCurveData remCurveData in oneCurveData)
{
string newName = EditorGUILayout.TextField(remCurveData.OldPath, remCurveData.NewPath);
remCurveData.NewPath = prependPath + newName;
}
}
}

void Remove()
{
foreach (List 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*;*
selectedClips = EditorGUILayout.ObjectField(“Animation Clip”, selectedClips*, typeof(AnimationClip), true) as AnimationClip;*

if (selectedClips != previous)
{
Clear();
}

if (selectedClips != 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;
}
}
}

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_.OldPath, uniqueCurveDatas*.NewPath);*_

if (uniqueCurveDatas*.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;
}
}