Search Unity

Smooth transition between camera field of view (FOV) values

Discussion in 'Scripting' started by Obscurity, Mar 28, 2008.

  1. Obscurity

    Obscurity

    Joined:
    Nov 13, 2007
    Posts:
    203
    Hi guys, it's been a little bit since I've asked a stupid question so here's one to make up for it.

    This is for a simple racing game. The current default field of view for the follow camera is 85. I have a script set up for the camera so that when the space bar is pressed for a speed boost, the camera's FOV widens to 95, which gives a great impression of acceleration if you haven't tried it. The problem is that I can't seem to get it to smoothly transition between those two values. I've tried several nearly successful methods, for example using Mathf.Lerp and Mathf.SmoothDamp, but they haven't worked as I'd like. I'd post my code but I don't have my computer with me. It may be better if someone could just throw me a fresh snippet of code anyway since I seem to be over thinking it.

    Thanks for any assistance.
     
  2. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    Use a bool to flag which FOV value the camera is moving towards. Then check in Update if the FOV is where it is supposed to be - otherwise increase/decrease the FOV value of the camera by a factor of Time.deltaTime.
     
  3. Obscurity

    Obscurity

    Joined:
    Nov 13, 2007
    Posts:
    203
    Wow, quick response. An indicator of the question's newb-level I'm sure. Thanks, AngryAnt. Do you think you could show it in more of a psuedo-code fashion? Either way, I'll try it later and see if I can get it working.
     
  4. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    Another way to tackle this is to store the car's velocity at the end of the frame update. Then, at the start of the next frame, you can calculate the acceleration by subtracting the stored velocity from the current:-

    Code (csharp):
    1. Vector3 previousVelocity;
    2. public float defaultFOV = 60f;
    3.  
    4. public float zoomFactor; /* Tweak to suit your needs */
    5.  
    6. void FixedUpdate() {
    7.     float acceleration = (rigidbody.velocity - previousVelocity).magnitude;
    8.  
    9.     /* Other code */
    10.  
    11.     previousVelocity = rigidbody.velocity;
    12. }
    You can then just make the FOV change proportional to the acceleration:-

    Code (csharp):
    1. camera.fieldOfView = defaultFOV + acceleration * zoomFactor;
    You can clamp the FOV value if you don't want to zoom in when the car brakes, although you might find that it is quite a nice effect.
     
  5. Obscurity

    Obscurity

    Joined:
    Nov 13, 2007
    Posts:
    203
    Ah, very cool andeeee. And much more procedural. I like it. I'll try that as well. Thanks.
     
  6. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    If you want transitions to be smooth, I suggest using velocity rather than acceleration to calculate your FOV. Velocity is continuous (except for crashes), whereas acceleration changes whenever the player gives (or stops giving) gas.
     
  7. drJones

    drJones

    Joined:
    Oct 19, 2005
    Posts:
    1,351
    interesting method andee - will check that out.

    i'm currently using something like this which seems to work ok:


    Code (csharp):
    1.  
    2. var minFOV = 85.0;
    3. var maxFOV = 95.0;
    4. var changeIncrement = 0.3;
    5.  
    6. function Update ()
    7. {
    8.     if (Input.GetButton ("Jump"))
    9.     {
    10.         if (Camera.main.fieldOfView < maxFOV)
    11.         {
    12.             Camera.main.fieldOfView += changeIncrement;
    13.         }
    14.     }
    15. }
    16.  
     
  8. Obscurity

    Obscurity

    Joined:
    Nov 13, 2007
    Posts:
    203
    Well, I played around with it during lunch and it works very nicely now. I'll be sharing the build on the forums this weekend sometime so you can play the results. I went simple like drJones.

    Code (csharp):
    1.  
    2.  
    3.     if(Input.GetKey ("space"))
    4.     {
    5.  
    6.     //Actual acceleration code goes here
    7.  
    8.     if(Camera.main.fieldOfView < 102)
    9.       {
    10.       Camera.main.fieldOfView += (15 * Time.deltaTime);
    11.       }
    12.     }
    13.    
    14.     else
    15.     {
    16.         if(Camera.main.fieldOfView > 86)
    17.         {
    18.         Camera.main.fieldOfView += (-10 * Time.deltaTime);
    19.         }
    20.     }  
    21.  
    22.  
     
  9. Daniel G

    Daniel G

    Joined:
    Mar 5, 2013
    Posts:
    25
    @andeeeee Do you have a Javascript example of this? This could be very helpful for my Rally Drift game :D
    Thanks for sharing!
    Cheers,
    Daniel
     
  10. kangyeye

    kangyeye

    Joined:
    Jun 29, 2020
    Posts:
    2
    well I know this is old but can't you just change that if statement with



    Code (csharp):
    1.  
    2. if (Input.GetButton ("Jump") && Camera.main.fieldOfView < maxFov)
    3.             Camera.main.fieldOfView += changeIncrements;
    4.