Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
8
Question by runevision · Nov 23, 2009 at 01:37 PM · animationeditor-scriptinganimationcurveanimationevent

How to add new curves or animation events to an imported animation?

The new Animation View in Unity 2.6 can be used to add Animation Curves to material or script properties or to add Animation Events. However, Animation Clips that are imported (from e.g. 3ds Max or Maya) are read-only.

I know it is possible to make a duplicate of an imported clip, and then add extra curves or animation events to that one in the Animation View. Just select the AnimationClip (not the whole imported model, but just the actual clip) and copy and paste it, or select Duplicate from the edit menu.

However then I don't get the updates in the duplicated clip any longer if I modify the original animation in my external animation software like Maya or 3ds Max.

How can I use the duplicate clip to add extra curves but still get the changes I make in the original clip?

Comment
Add comment
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

7 Replies

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

Answer by runevision · Nov 23, 2009 at 01:47 PM

You can use an editor script that copies over the curves from the original imported Animation Clip into the duplicated Animation Clip.

Here is such an editor script.

  • Place it in a folder called Editor, located somewhere inside the Assets folder.
  • The script assumes that you have already made a duplicate of the imported clip and called it the same name but with a *copy postfix. For example, if you have an imported clip called MyAnimation, it will search for MyAnimation_copy.
  • Select the original imported Animation Clip in the Project View.
  • You can now use the menu Assets -> Transfer Clip Curves to Copy

And the script:

using UnityEditor; using UnityEngine; using System.Collections;

public class CurvesTransferer {

 const string duplicatePostfix = "_copy";

 [MenuItem ("Assets/Transfer Clip Curves to Copy")]
 static void CopyCurvesToDuplicate () {
     // Get selected AnimationClip
     AnimationClip imported = Selection.activeObject as AnimationClip;
     if (imported == null) {
         Debug.Log("Selected object is not an AnimationClip");
         return;
     }

     // Find path of copy
     string importedPath = AssetDatabase.GetAssetPath(imported);
     string copyPath = importedPath.Substring(0, importedPath.LastIndexOf("/"));
     copyPath += "/" + imported.name + duplicatePostfix + ".anim";

     // Get copy AnimationClip
     AnimationClip copy = AssetDatabase.LoadAssetAtPath(copyPath, typeof(AnimationClip)) as AnimationClip;
     if (copy == null) {
         Debug.Log("No copy found at "+copyPath);
         return;
     }

     // Copy curves from imported to copy
     AnimationClipCurveData[] curveDatas = AnimationUtility.GetAllCurves(imported, true);
     for (int i=0; i<curveDatas.Length; i++) {
         AnimationUtility.SetEditorCurve(
             copy,
             curveDatas[i].path,
             curveDatas[i].type,
             curveDatas[i].propertyName,
             curveDatas[i].curve
         );
     }

     Debug.Log("Copying curves into "+copy.name+" is done");
 }

}

Comment
Add comment · Show 5 · 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 3Duaun · Mar 10, 2011 at 03:56 AM 0
Share

Thanks Rune!! this is VERY useful

avatar image demize2010 · Apr 17, 2011 at 04:34 PM 0
Share

Nice one! Extremely handy... can't believe this isn't in Unity already.

avatar image UniRad · Oct 12, 2011 at 08:19 AM 0
Share

These scripts give me several errors of this type: Assets/Editor/Editor.js(1,6): UCE0001: ';' expected. Insert a semicolon at the end. Any ideas? Thanks

avatar image temo_koki · Nov 28, 2012 at 02:17 AM 0
Share

Is it possible to use such logic (get curves/keyframes information) for mecanim animation system?

avatar image infinitypbr · Feb 16, 2014 at 06:33 PM 0
Share

Awesome! This just opened up a brand new world for me.

avatar image
7

Answer by neodrop · Jan 29, 2010 at 06:02 PM

There is more simple variant. This script creates a new animation file itself and makes all copying operations.

using UnityEditor; using UnityEngine;

public class CurvesTransferer { const string duplicatePostfix = "_copy";

static void CopyClip(string importedPath, string copyPath) { AnimationClip src = AssetDatabase.LoadAssetAtPath(importedPath, typeof(AnimationClip)) as AnimationClip; AnimationClip newClip = new AnimationClip(); newClip.name = src.name + duplicatePostfix; AssetDatabase.CreateAsset(newClip, copyPath); AssetDatabase.Refresh(); }

[MenuItem("Assets/Transfer Clip Curves to Copy")] static void CopyCurvesToDuplicate() { // Get selected AnimationClip AnimationClip imported = Selection.activeObject as AnimationClip; if (imported == null) { Debug.Log("Selected object is not an AnimationClip"); return; }

 // Find path of copy
 string importedPath = AssetDatabase.GetAssetPath(imported);
 string copyPath = importedPath.Substring(0, importedPath.LastIndexOf("/"));
 copyPath += "/" + imported.name + duplicatePostfix + ".anim";

 CopyClip(importedPath, copyPath);

 AnimationClip copy = AssetDatabase.LoadAssetAtPath(copyPath, typeof(AnimationClip)) as AnimationClip;
 if (copy == null)
 {
     Debug.Log("No copy found at " + copyPath);
     return;
 }
 // Copy curves from imported to copy
 AnimationClipCurveData[] curveDatas = AnimationUtility.GetAllCurves(imported, true);
 for (int i = 0; i < curveDatas.Length; i++)
 {
     AnimationUtility.SetEditorCurve(
         copy,
         curveDatas[i].path,
         curveDatas[i].type,
         curveDatas[i].propertyName,
         curveDatas[i].curve
     );
 }

 Debug.Log("Copying curves into " + copy.name + " is done");

}

}

Comment
Add comment · Show 2 · 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 3Duaun · Mar 10, 2011 at 03:52 AM 0
Share

@NeoDrop, thanks for the refining there. I'm a fan of all things Antares, nice work!

avatar image PatHightree · Mar 28, 2012 at 08:44 PM 0
Share

Thanks for the great script. I'm totally amazed you can't just add animation events on imported animations. Very strange for such a workflow-oriented tool as Unity.

avatar image
0

Answer by MaDDoX · Jul 22, 2010 at 11:07 AM

Guys, thanks a lot for the help, very useful, but allow me to say that it's really annoying when you see an apparently cool chunk of code, tries to use it and get a "parsing error". There's a missing semicolon near the top and a missing closing bracket in the end, here goes the fixed version:

using UnityEditor; using UnityEngine; using System.Collections;

public class CurvesTransferer { const string duplicatePostfix = "_copy";

static void CopyClip(string importedPath, string copyPath) { AnimationClip src = AssetDatabase.LoadAssetAtPath(importedPath, typeof(AnimationClip)) as AnimationClip; AnimationClip newClip = new AnimationClip(); newClip.name = src.name + duplicatePostfix; AssetDatabase.CreateAsset(newClip, copyPath); AssetDatabase.Refresh(); }

 [MenuItem("Assets/Transfer Clip Curves to Copy")]
 static void CopyCurvesToDuplicate()
 {
     // Get selected AnimationClip
     AnimationClip imported = Selection.activeObject as AnimationClip;
     if (imported == null)
     {
         Debug.Log("Selected object is not an AnimationClip");
         return;
     }

     // Find path of copy
     string importedPath = AssetDatabase.GetAssetPath(imported);
     string copyPath = importedPath.Substring(0, importedPath.LastIndexOf("/"));
     copyPath += "/" + imported.name + duplicatePostfix + ".anim";

     CopyClip(importedPath, copyPath);

     AnimationClip copy = AssetDatabase.LoadAssetAtPath(copyPath, typeof(AnimationClip)) as AnimationClip;
     if (copy == null)
     {
         Debug.Log("No copy found at " + copyPath);
         return;
     }
     // Copy curves from imported to copy
     AnimationClipCurveData[] curveDatas = AnimationUtility.GetAllCurves(imported, true);
     for (int i = 0; i &lt; curveDatas.Length; i++)
     {
         AnimationUtility.SetEditorCurve(
             copy,
             curveDatas[i].path,
             curveDatas[i].type,
             curveDatas[i].propertyName,
             curveDatas[i].curve
         );
     }

     Debug.Log("Copying curves into " + copy.name + " is done");
 }

}

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 UniRad · Oct 12, 2011 at 08:34 AM

The scripts give me several errors of this type: Assets/Editor/Editor.js(1,6): UCE0001: ';' expected. Insert a semicolon at the end. Any ideas? Thanks

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 PatHightree · Mar 28, 2012 at 08:44 PM 0
Share

Its a C# script, not a javascript.

avatar image
0

Answer by TLoch14 · Feb 28, 2012 at 07:03 PM

Guys, I loved this script so much, I went ahead and added a couple of features.

Here is a modified version of MaDDoX's edit that includes logic for automatically placing the animations into folders.

It first uses an animations folder to contain them all and then if the animation came from an FBX file, it will use the FBX's name to create a subfolder for those animations. Hopefully, this helps y'all keep things organized.


 using UnityEditor;
 using UnityEngine;
 
 using System.IO;
 using System.Collections;
 
 public class MultipleCurvesTransferer {
 const string duplicatePostfix = "Edit";
 const string animationFolder = "Animations";
 
 static void CopyClip(string importedPath, string copyPath) {
     AnimationClip src = AssetDatabase.LoadAssetAtPath(importedPath, typeof(AnimationClip)) as AnimationClip;
     AnimationClip newClip = new AnimationClip();
     newClip.name = src.name + duplicatePostfix;
     AssetDatabase.CreateAsset(newClip, copyPath);
     AssetDatabase.Refresh();
 }
 
     [MenuItem("Assets/Transfer Multiple Clips Curves to Copy")]
     static void CopyCurvesToDuplicate()
     {
         // Get selected AnimationClip
         Object[] imported = Selection.GetFiltered(typeof(AnimationClip), SelectionMode.Unfiltered);
         if (imported.Length == 0)
         {
             Debug.LogWarning("Either no objects were selected or the objects selected were not AnimationClips.");
             return;
         }
         
         //If necessary, create the animations folder.
         if (Directory.Exists("Assets/" + animationFolder) == false) {
             AssetDatabase.CreateFolder("Assets", animationFolder);
         }
     
         foreach (AnimationClip clip in imported) {
             
             
             
             string importedPath = AssetDatabase.GetAssetPath(clip);
             
             //If the animation came from an FBX, then use the FBX name as a subfolder to contain the animations.
             string copyPath;
             if (importedPath.Contains(".fbx")) {
                 //With subfolder.
                 string folder = importedPath.Substring(importedPath.LastIndexOf("/") + 1, importedPath.LastIndexOf(".") - importedPath.LastIndexOf("/") - 1);
                 if (!Directory.Exists("Assets/Animations/" + folder)) {
                     AssetDatabase.CreateFolder("Assets/Animations", folder);
                 }
                 copyPath = "Assets/Animations/" + folder + "/" + clip.name + duplicatePostfix + ".anim";
             } else {
                 //No Subfolder
                 copyPath = "Assets/Animations/" + clip.name + duplicatePostfix + ".anim";
             }
             
             Debug.Log("CopyPath: " + copyPath);
             
             CopyClip(importedPath, copyPath);
     
             AnimationClip copy = AssetDatabase.LoadAssetAtPath(copyPath, typeof(AnimationClip)) as AnimationClip;
             if (copy == null)
             {
                 Debug.Log("No copy found at " + copyPath);
                 return;
             }
             // Copy curves from imported to copy
             AnimationClipCurveData[] curveDatas = AnimationUtility.GetAllCurves(clip, true);
             for (int i = 0; i < curveDatas.Length; i++)
             {
                 AnimationUtility.SetEditorCurve(
                     copy,
                     curveDatas[i].path,
                     curveDatas[i].type,
                     curveDatas[i].propertyName,
                     curveDatas[i].curve
                 );
             }
     
             Debug.Log("Copying curves into " + copy.name + " is done");
         }
     }
 }



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 hike1 · Nov 01, 2013 at 02:29 AM 0
Share

I ran the last version successfully, but there's no model associated with the animations, the original package is here, how do I get the readable anims on it. When I ctrl-D they are not under the model prefab.

https://dl.dropboxusercontent.com/u/102638093/ninja_psionic.unitypackage

Exported from milkshape 3d

  1. mb This model is facing 180 backwards on the z axis, why I want to fix it. psionic3d.co.uk free model has a milkshape and characterfx version, can't decide which I'd rather mess with less.

  • 1
  • 2
  • ›

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

7 People are following this question.

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

Related Questions

Animation Events and Mecanim 2 Answers

AnimationCurve for ScriptableObject 0 Answers

EDITOR: How to Change Animation Curve Colors 0 Answers

"getcurve" from a gameobject 0 Answers

Can I make animations snap to a frame? 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