Hello Guest

Author Topic: Achieving a smooth, lerped zoom effect  (Read 9296 times)

Doghelmer

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 20
    • View Profile
Achieving a smooth, lerped zoom effect
« on: September 26, 2014, 06:53:12 pm »
I've been attempting to get a smooth camera zoom effect using the tk2dcamera.  Here's what my code looks like (in FixedUpdate):

myCamera.ZoomFactor = Mathf.Lerp(myCamera.ZoomFactor, newZoomFactor, zoomSpeed);

..where zoomSpeed is set to 0.1.

The code works as expected, except for one problem: The camera's zoom motion can become very choppy.  It's especially noticeable toward the end of a camera motion-- it looks like the camera's visual zoom level is not being updated every frame. I can see the ZoomFactor value going up or down in the Inspector, but it seems like maybe the camera is only updated at certain numerical thresholds?

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Achieving a smooth, lerped zoom effect
« Reply #1 on: September 26, 2014, 09:22:55 pm »
Don't call it in fixed update, that can get called any number of times in a frame. Call it in LateUpdate, and make sure to factor in Time.deltaTime.

Doghelmer

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Achieving a smooth, lerped zoom effect
« Reply #2 on: September 27, 2014, 10:29:12 pm »
Unfortunately, it doesn't seem like that had any effect.  Here's what I'm doing now:

   void LateUpdate () {
      myCamera.ZoomFactor = Mathf.Lerp(myCamera.ZoomFactor, newZoomFactor, zoomSpeed*Time.deltaTime*60);
   }

This is producing exactly the same result as I was seeing previously.

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Achieving a smooth, lerped zoom effect
« Reply #3 on: September 28, 2014, 01:09:11 pm »
You're still not REALLY factoring in deltaTime by doing that. Your lerp isn't exactly linear...
Look at tk2dTileMapDemoCam, it does a smooth zoom which looks pretty smooth. Its in fixed update because its following a rigidbody, not the ideal case, but it looks fine.

Doghelmer

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Achieving a smooth, lerped zoom effect
« Reply #4 on: September 29, 2014, 06:13:51 am »
Upon closer inspection, it looks like the problem is what I originally thought it was-- the camera doesn't appear to recognize small changes in ZoomFactor.

To give an example of what I'm talking about-- if I set the ZoomFactor to 1 and run this code:

   void Update () {
      if (Input.GetMouseButtonDown (0)) {
         myCamera.ZoomFactor += 0.001f;
      }
   }

.. Clicking the mouse once produces no visible change to the camera.  However, if I click the mouse 6 times so that ZoomFactor is 1.006, a very obvious visual change occurs on that 6th click.  This would explain why the small changes toward the end of my Lerp don't always register in the camera.

Is this just a limitation of how ZoomFactor functions?  If so I can work around it, but it seems like there may not be a way to get the exact effect I'm looking for.

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Achieving a smooth, lerped zoom effect
« Reply #5 on: September 29, 2014, 11:08:20 am »
Hi,
Adding 0.001 to zoom factor means adding 0.1% per click. You're limited by the number of pixels you have, it only going to zoom and snap to the closest pixel, it isn't going to smooth stuff out between pixels.

If it isn't doing that please post a repro case.

Doghelmer

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Achieving a smooth, lerped zoom effect
« Reply #6 on: September 29, 2014, 11:20:40 pm »
I've uploaded a couple of files for a quick repro.  Just drop these into a new project that has 2D Toolkit imported with the demos.

https://www.dropbox.com/s/5h5q7u6t1uhvyln/Zoomer.cs?dl=0
https://www.dropbox.com/s/4bmk9v9z882bcw8/testScene.unity?dl=0

In this project, all I've really done is created a tk2dcamera with pixels per meter is set to 1 and resolution set to 1920x1080, added a sprite, and added my a script to increase ZoomFactor by 0.001 on every click.

If you click a bunch of times, you'll see the sprite begin to change position on the screen-- but it's a "jump", rather than being a completely smooth change.  Ideally, the sprite would change position by a tiny amount on every click, instead of "jumping" every 5-6 clicks.

If this is indeed working as intended (and I suspect it may be), apologies for wasting your time.  I should mention that this whole thing becomes a non-issue if I increase my pixels per meter to 20, like in the demo.  I'd rather not do something like that as I'd prefer to keep everything 1:1.  However, it seems like that may be the ideal solution.

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Achieving a smooth, lerped zoom effect
« Reply #7 on: September 30, 2014, 10:47:03 am »
It seems to be doing the same thing with 1 ppm and 100 ppm as far as I can tell... The further away from the center the more obvious the jump seems to be but thats to be expected...

Try 100 ppm and see how that works for you - at 100 ppm, you just divide everything by 100, to snap to a pixel = 0.01 instead of 1.

Doghelmer

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Achieving a smooth, lerped zoom effect
« Reply #8 on: January 14, 2015, 10:55:30 pm »
Older thread, but I'd been kind of avoiding this issue until now..

You recommended to "just divide everything by 100, to snap to a pixel = 0.01 instead of 1".  I'm a bit confused-- Is there a relatively easy way to accomplish this?  All of the objects in my game are built around the camera being at 1 pixel per meter.  Would I need to somehow reduce the size and position of all objects in my game by 100?

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Achieving a smooth, lerped zoom effect
« Reply #9 on: January 15, 2015, 10:33:40 am »
Quote
Would I need to somehow reduce the size and position of all objects in my game by 100?
Only the positions, the sizes will be handled automatically if you change sprite collection size to match. You can write an editor script to do this.


Doghelmer

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Achieving a smooth, lerped zoom effect
« Reply #10 on: January 15, 2015, 07:57:31 pm »
"You can write an editor script to do this."
I'm not clear, are you referring to changing the positions of objects?  If so, can you please provide a bit more information on how I might get started on this?  Apologies if it's out of your jurisdiction, I might take this to Unity's Answers section.

Unfortunately, changing the sprite collection size probably wouldn't be the best option-- I'd need to change the scale so that the colliders attached to my objects would be affected as well.

I imagine other aspects of the game would be affected as well, like physics-based movements-- I'd have objects appearing to move 100 times faster than intended.  Also, my tilemap sizes would need to be changed.  This is probably just the tip of the iceberg.  Unless I am missing something here (quite possible?), it seems like there would be very far-reaching effects in attempting to reduce the size of everything.  Do you believe that there is an all-encompassing method of changing the scale of everything that wouldn't leave a trail of bugs and inconsistencies in its wake?

Doghelmer

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Achieving a smooth, lerped zoom effect
« Reply #11 on: January 27, 2015, 11:22:13 pm »
I would really appreciate a response elaborating on this a bit, or pointing me in the right direction, as I can't think of a solution that wouldn't require very large changes to my game.  It seems to be implied in your previous responses that there is a relatively straightforward solution here, but it's not clear to me what that is.

I think it might be beneficial to others to make mention of Zoom's limitations within the tutorials-- Currently the tutorials recommend using a pixels-per-meter of 1, which has caused me this issue down the road.