I’m trying to make my project’s animation jump to different frames in the root timeline as the user presses keys to the right or left. Pressing keys increases or decreases a number variable, and I want the player head to jump to that number.
I have created a reference to my root animation:
private var pHeadHands: GameObject;
pHeadHands = GameObject.Find("HeadAndHands");
When I do this, it works fine:
pHeadHands.animation.Play();
but, it I try this:
pHeadHands.animation.time = 72;
I get an error:
Assets/RotCamH.js(75,30): BCE0019: ‘time’ is not a member of ‘UnityEngine.Animation’.
I also tried various other ways like:
pHeadHands.animation["HeadAndHands"].time = 72;
And have errors.
I can’t do this with clips because Unity crashes when I try to split my animation and reimport, and because that wouldn’t work anyway with what I’m doing.
I also tried creating clips through scripting, with no luck.
You can create an Editor script to split you animation quite easily. We were having issues having to redo the animation clip list every time something was added, so we made a quick script that created the splits on import. Then when a new clip was added, you only had to add the clip to the file in one place.
This is a brief js example of the script we used.
class AnimationsImporter extends AssetPostprocessor
{
function OnPreprocessModel()
{
//Do some code to determine if the model is right, usually by checking the file name
// Get the model importer, setup the values
var modelImporter : ModelImporter = assetImporter;
modelImporter.splitAnimations = true;
modelImporter.generateAnimations = ModelImporterGenerateAnimations.InRoot;
var clipAnimationArray : Array = new Array();
if(weHaveTheRightModel)
{
clipAnimationArray.Add(SetClipAnimation("idle", 0, 46, true));
clipAnimationArray.Add(SetClipAnimation("walk", 48, 72, true));
// Add new animation splits here when required
}
modelImporter.clipAnimations = clipAnimationArray.ToBuiltin(ModelImporterClipAnimation);
}
private function SetClipAnimation(_name : String, _firstFrame : int, _lastFrame : int, _loop : boolean) : ModelImporterClipAnimation
{
var newClipAnimation : ModelImporterClipAnimation = new ModelImporterClipAnimation();
newClipAnimation.name = _name;
newClipAnimation.firstFrame = _firstFrame;
newClipAnimation.lastFrame = _lastFrame;
newClipAnimation.loop = _loop;
return newClipAnimation;
}
}
Then as new animations were added to the model, we just added another line to the splits, and re-imported the model. Made life much easier.
While I know this doesn’t exactly answer the above question, it should allow you to split your animations properly, which means you shouldn’t have to jump around a long timeline in script.
The reason you couldn’t access the time variable is because it isn’t part of the Animation class, but part of the AnimationState class. When you reference the animations like an array, you are grabbing an animation state, but those splits need to be in place first before you can reference them.
I ended up just adding something to my main “brain” game object.
function createHandClips(){
//lens retracted frames (1 second to 7 seconds at 24 fps)
for (var i=24; i<168; i++){
var nme = "frm" + (i-23);
pHandsRotX.animation.AddClip(pHandsRotX.animation.clip, nme, i, i+1, false);
};
}
Then, I can jump to frm1, frm2, etc with:
var frm = "frm" + Mathf.Round (pRotH/4.2);
pHandsRotX.animation.Play(frm);
This is actually working somewhat. The problem is, I just want it to jump to one frame in the animation and stop, but I must define all my clips as being at least 1 frame long. So, it jumps to say, frm30 clip, plays 1 frame and stops. The results is a giggly motion as I the camera rotates around the head.