- Home /
How can I reassign animation curves to play on a child object (instead of through parent)?
I currently have an imported FBX with an animation that controls its children. I have a selection script so that if I click on any part of the model and drag the mouse, the animation will play. In this instance, it's a model of a throttle with two levers as children. I want to make it so that if I click on a lever, it will only move that specific lever instead of both. So far, I have a script that attaches a new animation to each child that originally had curves on it, and also attaches an animation clip with curves. The problem is, these curves aren't correct and I'm not sure where they're coming from. Here's what I have:
var curvePaths : List.<String> = new List.<String>();
var curveTypes : List.<System.Type> = new List.<System.Type>();
var curvePropertyNames : List.<String> = new List.<String>();
var curves : AnimationClipCurveData[];
var testClip : AnimationClip;
var sceneObjects : GameObject[] = FindObjectsOfType(GameObject) as GameObject[];
for (var sceneObject in sceneObjects) {
if (sceneObject.animation != null) {
if (sceneObject.animation.clip != null) {
var i = 0;
testClip = sceneObject.animation.GetClip("Take 001");
curves = AnimationUtility.GetAllCurves(sceneObject.animation.clip);
for (var curve in curves) {
curvePaths.Add(curve.path);
curveTypes.Add(curve.type);
curvePropertyNames.Add(curve.propertyName);
for (var curvePath in curvePaths) {
var newAnimation : Animation;
var newClip : AnimationClip = new AnimationClip();
var realObject = GameObject.Find(curvePath);
if (realObject.animation == null) {
newAnimation = realObject.AddComponent(Animation);
}
newClip.SetCurve("", curveTypes[i], curvePropertyNames[i], curve.curve);
realObject.animation.AddClip(newClip, "Take 001");
}
i++;
}
DestroyImmediate(sceneObject.animation);
}
}
}
Answer by Ben Blaut · Apr 26, 2013 at 05:58 PM
I solved this problem by creating new animations for each unique child that was animated and re-assigning the curves to its respective animation. I then attached these clips to the parent object.
var curveDataArray : AnimationClipCurveData[];
var uniquePaths : ArrayList = new ArrayList();
var parentObject : GameObject;
// If there is an animation on the object with a clip
if (obj.animation != null) {
if (obj.animation.clip != null) {
// Get all the curves in the clip
curveDataArray = AnimationUtility.GetAllCurves(obj.animation.clip);
// For each curve
for (var curveData : AnimationClipCurveData in curveDataArray) {
// Check if the object the curve applies to has already been seen
if (!uniquePaths.Contains(curveData.path)) {
var newClip : AnimationClip = new AnimationClip();
var assetPath : String;
// If not, add it to an array to denote that it has been seen
uniquePaths.Add(curveData.path);
// Add the created clip to the asset database
assetPath = "Assets/" + curveData.path + ".anim";
AssetDatabase.CreateAsset(newClip, assetPath);
AssetDatabase.SaveAssets();
// Put the clip on the object
obj.animation.AddClip(newClip, curveData.path);
}
}
}
}
// For each curve
for (var curveData : AnimationClipCurveData in curveDataArray) {
// Only do this for each unique curve object
if (uniquePaths.Contains(curveData.path)) {
var curveClip : AnimationClip;
// Get the empty clip that was added to the object
curveClip = obj.animation.GetClip(curveData.path);
// Set the curves in that clip
AnimationUtility.SetEditorCurve(curveClip, curveData.path, curveData.type, curveData.propertyName, curveData.curve);
}
}