Set animation end position as new position

I have a camera and when I press a button the camera plays an animation. After that the player can push again on a button and the camera should play another animation but from where the camera is located at that point. And not from where it was before the first animation.

So what I though I could do is:

1. Play the animation
2. wait till the end
3. Get the position and rotation
4. Stop Animation
5. Rewind animation to start frame
6. Set new position and rotation

If I Rewind and Stop that animation stays at its last frame instead of going back. And if I wait for next fixed update the camera is at the first frame of the animation. And if I then put the camera to its previous rotation and position, it works but you see it go back to the first frame and then back to new position. So you see the screen change twice.

Here is what I had:

	protected override IEnumerator CameraAnim()
	{
		Camera.main.animation.Play(CameraAnimation.name);

		yield return new WaitForSeconds(CameraAnimation.length);

		Vector3 pos = Camera.main.transform.localPosition;
		Quaternion rot = Camera.main.transform.rotation;

		Debug.Log(pos);

		Camera.main.animation.Rewind(CameraAnimation.name);    
		Camera.main.animation.Stop(CameraAnimation.name);

		Camera.main.transform.localPosition = pos;
		Camera.main.transform.rotation = rot;

		Debug.Log(pos);

		IsActive = true;
	}

There are multiple ways to do it, but here are some pointers:

  • Set animation wrapModel to Clamp, this way you’ll be sure that your animation doesn’t jump back to the start when it’s over. Then simply do Rewind as you do now.
  • Calling Rewind, Stop, changing time on AnimationState, doesn’t change transforms immediately. Most people use MonoBehaviour.Update to Stop/Play/etc animation and then get position of transforms in MonoBehaviour.LateUpdate, because that’s where animation animation is sample with latest state. Anyway, you can get it working with coroutines, read on…
  • If you want to get transfroms to be update on the same frame, then simply call Animation.Sample and it will force-sample the animation.
  • Also calling Rewing and Stop resets animation to start and stops playing it, so your AnimationState.time is 0, but it doesn’t get resampled because you called Stop and this way stopped playback of the animation. Soliution: call: Rewind; Sample; Stop. This way it will rewind animation, resample it and then stop it.

If you want to have better undestanding about Unity-update-loop, read this: Unity - Manual: Order of execution for event functions (especially: “So in conclusion, this is the execution order for any given script:” part)