- Home /
Can I create a script that makes an animation advance 1 frame for each keystroke?
I have 86 views of my model that I need to be able to cycle through easily. So my camera has an animation that covers 86 keyframes, where each keyframe is a new view. Ideally, I could just press spacebar or something like that to advance one frame further, but so far it seems like all I can do is trigger the animation in its entirety. Any help would be much appreciated! Thanks.
Answer by pravusjif · Dec 29, 2013 at 01:02 AM
OK guys sorry for making a new Answer, but i wanted to post this clearly and not hidden in a comment, i managed to make this work and it seems to work as the opener guy wanted ( and the same functionality i was needing ) Here is the updated, working code, in my case this goes on a Sun that rises and hides, by holding the DOWN key i'm advancing in the animation.
using UnityEngine;
using UnityEditor;
using System.Collections;
public class Sun : MonoBehaviour {
public float animationSpeed = 1;
private int currentKeyFrame = 0;
private AnimationState animationState;
void Start() {
animationState = animation["sun_track"];
}
void Update() {
// this stops the animation
animationState.enabled = false;
animationState.weight = 0;
if(Input.GetKey(KeyCode.DownArrow))
{
nextKeyFrame();
}
}
void nextKeyFrame()
{
animationState = animation["sun_track"];
AnimationClipCurveData[] accd = AnimationUtility.GetAllCurves(animationState.clip, true);
Debug.Log("keyframe: " + currentKeyFrame + " length: " + accd.Length);
// this allows the animation to advance
animationState.enabled = true;
animationState.weight = 1;
animationState.time += animationSpeed * Time.deltaTime;
}
}
Answer by jacksmash2012 · Nov 27, 2013 at 06:51 PM
Although I haven't tested it myself, I don't see why you couldn't do this. There are other posts out there that are related to this problem. For example, see here:
or here:
So what I'd suggest is that you calculate how much TIME you want to pass (on key-down) rather than how many keyframes. Then you can simply loop through an animation from the beginning of the time chunk to the end of the time chunk that is represented by a key press.
Answer by Spinnernicholas · Nov 27, 2013 at 06:56 PM
You need to use AnimationState and AnimationCurve
int currentKeyFrame = 0;
void NextKeyFrame()
{
animationState.time = animationCurve.keys[currentKeyFrame++].time;
}
Things get a little more complicated if you have multiple curves on a single animation.
You would have to figure out what the next keyframe is by searching through all of the curves to see which one is closest to the current time.
Answer by ibrews · Nov 27, 2013 at 08:14 PM
Thanks guys! Forgive me-- I'm still very new to Unity but have some Java experience. Here's the code I'm trying to run, and I'm getting the 'expected ;' error. Thanks.
function Update () {
if (Input.GetKey(KeyCode.PageDown))
int currentKeyFrame = 0;
void NextKeyFrame()
{
animationState.time = animationCurve.keys[currentKeyFrame++].time;
}
};
you need a ; here:
int current$$anonymous$$eyFrame = 0";"
no that's not it. I don't think it's actually a semicolon problem, as I've tried nearly ever variation of adding and subtracting semicolons and it's still giving me that error. any other thoughts? thanks.
The exact error says this: Assets/PlayCam.js(3,12): UCE0001: ';' expected. Insert a semicolon at the end.
Now beware, this is a complicated piece of the Unity Framework and I am working off the Unity Docs, which seem to have some missing information for animations. So, I doubt this code will run. This is basically what you have to do.
And this is C#, I'll let you deal with translating.
//Change <className> to your class name
Class <className> : $$anonymous$$onoBehavior
{
//This is a member variable.
int current$$anonymous$$eyFrame = 0;
void Update()
{
if(Input.Get$$anonymous$$ey($$anonymous$$eyCode.PageDown))
{
next$$anonymous$$eyFrame();
}
}
void next$$anonymous$$eyFrame()
{
//Retrieve AnimationState and AnimationCurve
//Replace animation_name with the name of your animation
AnimationState animationState = animation["animation_name"];
//this should retrieve the first curve of the AnimationClip
AnimationCurve animationCurve = animationState.clip[0];
animationState.time = animationCurve.keys[current$$anonymous$$eyFrame++].time;
}
}
This is all very helpful, but unfortunately I can't run it since I'm still getting weird Unity errors. Now it's:
Assets/PlayCam.js(2,6): UCE0001: ';' expected. Insert a semicolon at the end.
Assets/PlayCam.js(2,7): BCE0044: expecting EOF, found 'PlayCam'.
Here's the code:
//Change to your class name Class PlayCam : $$anonymous$$onoBehavior { //This is a member variable. int current$$anonymous$$eyFrame = 0;
void Update() { if(Input.Get$$anonymous$$ey($$anonymous$$eyCode.PageDown)) { next$$anonymous$$eyFrame(); } }
void next$$anonymous$$eyFrame() { //Retrieve AnimationState and AnimationCurve //Replace animation_name with the name of your animation AnimationState animationState = animation["camera$$anonymous$$ove"]; //this should retrieve the first curve of the AnimationClip AnimationCurve animationCurve = animationState.clip[0]; animationState.time = animationCurve.keys[current$$anonymous$$eyFrame++].time; } }