Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Zoom out camera's Field of View slowly?

Discussion in 'Scripting' started by EgoInsanus, Jul 6, 2012.

  1. EgoInsanus

    EgoInsanus

    Joined:
    Jul 6, 2012
    Posts:
    3
    I wanted to know how I could make my camera zoom out slowly (with the field of view) once the player hits a 'trigger' box collider that I set up.

    Code (csharp):
    1.  
    2. function OnTriggerEnter (Collision : Collider)
    3.  
    4. {
    5.     if(Collision.gameObject.tag == "TriggerOut")
    6.     Camera.main.fieldOfView = 100;
    7. }
    8.  
    9.  
    I just need to know how to get to that 100 slowly.
     
  2. Boss

    Boss

    Joined:
    Jun 27, 2012
    Posts:
    133
    Function OnTriggerEnter (Collision : Collider)

    {

    if(Collision.gameObject.tag == "Trigger Out")

    Camera.main.fieldOfView = 25;

    yield(waitforseconds(0.1));

    Camera.main.fieldOfView = 50;

    yield(waitforseconds(0.1));

    Camera.main.fieldOfView = 75;

    yield(waitforseconds(0.1));

    Camera.main.fieldOfView = 100;

    }
    //-----------------------------------------------------

    You can also spread out these lines to slower change by going by 10's or smaller, if you want. Also can change yield time too. This is simple to change script. Hope This Helps!
     
    Last edited: Jul 6, 2012
  3. Tseng

    Tseng

    Joined:
    Nov 29, 2010
    Posts:
    1,217
    Don't post stuff like that, that's the worst kind of noob programming you could ever do and everyone will laugh at you, when reading the code lol.

    @EgoInsanus:
    You can just use Mathf.Lerp to (linearly-)interpolate a value over time.

    Code (csharp):
    1.  
    2. Camera.main.fieldOfView = Mathf.Lerp(Camera.main.fieldOfView, 100, 0.1);
    3.  
    You will probably have to run it in a coroutine, when you are setting it from i.e. OnTrigger/OnColission which are only called once per collision or set a variable and use this variable for the second parameter of Lerp in Update() method
     
    tampaxpons and MaxvH like this.
  4. Boss

    Boss

    Joined:
    Jun 27, 2012
    Posts:
    133
    I was giving him a chance to practice, I changed comment to code.
     
  5. EgoInsanus

    EgoInsanus

    Joined:
    Jul 6, 2012
    Posts:
    3
    How would I go about it with the coroutine option?
     
  6. Tseng

    Tseng

    Joined:
    Nov 29, 2010
    Posts:
    1,217
    You were teaching him the completely wrong things, nothing else.

    Something like
    Code (csharp):
    1.  
    2. function LerpFoV(fov : float) {
    3.     // lerping a value in this way may take quite some time to reach the exact target value, so we will just stop lerping when the difference is small enough, i.e 0.05
    4.     var dif : float = Mathf.Abs(Camera.main.fieldOfView - fov);
    5.  
    6.     while(dif > 0.05) {
    7.         Mathf.Lerp(Camera.main.fieldOfView, fov, 0.1);
    8.         // update the difference
    9.         dif = Mathf.Abs(Camera.main.fieldOfView - fov);
    10.         yield;
    11.     }
    12. }
    13.  
    14. // start the coroutine
    15. StartCoroutine(LerpFoV(100));
    16.  
    alternatively place the lerp code in Update() method, and store the new fov value in a member variable
     
    Jroel and MaxvH like this.
  7. eduardo-pons

    eduardo-pons

    Joined:
    Mar 31, 2009
    Posts:
    176
    Something like this
    Code (csharp):
    1.  
    2.  
    3. public float TargetFOV = 100f;
    4.  
    5. public float Speed = 1f; //Will reach target value in 1sec. 2f will make it achieve in half second (1f/2f)... and so on!
    6.  
    7. void Update()
    8. {
    9.    Camera.main.fieldOfView = Mathf.Lerp(Camera.main.fieldOfView,TargetFOV,Speed * Time.deltaTime);
    10. }
    11.  
    12.  
     
  8. Tseng

    Tseng

    Joined:
    Nov 29, 2010
    Posts:
    1,217
    It should be Time.deltaTime / Speed, to messure it in seconds.
     
  9. JohnnyA

    JohnnyA

    Joined:
    Apr 9, 2010
    Posts:
    5,041
    A little off topic but @Boss... could you stop going around posting poor (or completely unrelated) answers on peoples posts. The only thing worse than no advice is bad advice!
     
  10. eduardo-pons

    eduardo-pons

    Joined:
    Mar 31, 2009
    Posts:
    176
    That's why I called it Speed :) - The greater the faster it reaches

    But if you want a Time attribute it would really be DT / Time
     
  11. EgoInsanus

    EgoInsanus

    Joined:
    Jul 6, 2012
    Posts:
    3
    Thank you guys for you help, you helped me learn a little.

    But I ended up doing something a bit simpler and I made my collider bigger and did this instead


    Code (csharp):
    1. var Speed : float = 1f;
    2.  
    3.  
    4. function OnTriggerStay (Collision : Collider)
    5.  
    6. {
    7.     if(Collision.gameObject.tag == "TriggerOut")
    8.     Camera.main.fieldOfView = Mathf.Lerp(Camera.main.fieldOfView, 100, Time.deltaTime / Speed);
    9. }

    and then I ended up needing to zoom back in so I made another collider for the end of the level and duplicated the same script, but instead changed the collider tag to 'TriggerIn' and changed that on the script I duplicated and I also changed the 100 back to the regular one that it was at (56 btw) and then added that one as well to my player.


    I am also a bit of a beginner on scripting in Unity, I'm trying to learn Javascript by seeing other peoples problems as well as failing and learning on my own since I only know Java atm.
     
  12. Tseng

    Tseng

    Joined:
    Nov 29, 2010
    Posts:
    1,217
    I don't think that OnColliderStay/OnTriggerStay is the best way of doing it.

    Why not just have the desired value in a variable and interpolate it in Update?

    Also if you know Java, then C# may be the more natural choice as Java is more similar to C# than to UnityScript.

    C# as I code in it
    Code (csharp):
    1.  
    2. public class SomeScript : MonoBehaviour {
    3.     private int speed = 1.0f;
    4.     private int newFoV = 0;
    5.  
    6.     public void Start() {
    7.         // save the current FoV
    8.         newFoV = Camera.main.fieldOfView;
    9.     }
    10.  
    11.     void Update() {
    12.         Camera.main.fieldOfView = Mathf.Lerp(Camera.main.fieldOfView, newFoV, 1/speed);
    13.     }
    14.  
    15.     void OnTriggerEnter(Collider other) {
    16.         // it's better to  use other.CompareTag(..) instead of other.tag == "somestring"
    17.         if(other.CompareTag("TriggerOut") {
    18.             newFoV = 100f; // In C# you must add an f to float numbers
    19.         }
    20.     }
    21. }
    22.  
     
    420BlazeIt likes this.
  13. 420BlazeIt

    420BlazeIt

    Joined:
    Aug 14, 2014
    Posts:
    102
    This was helpful for me. Thanks dude!
     
  14. mrck103

    mrck103

    Joined:
    Feb 6, 2016
    Posts:
    1

    Hey, the other peoples code is good but have not worked for me so i made this, only use this if your doing simple zooming such as aiming etc, hope this helps.

    Code (csharp):
    1.  
    2.     IEnumerator LerpFoV(float fov) {
    3.         while(Camera.main.fieldOfView != fov) { // while the feild of view does not equal the desired value
    4.             if (Camera.main.fieldOfView < fov) { // checks if the feild of view is less than fov so it can add up
    5.                 Camera.main.fieldOfView += 1;// change this to 0.5f, 0.2f, 0.1f, depending on how fast you want the zoom
    6.             } else {
    7.                 Camera.main.fieldOfView -= 1; // change this to 0.5f, 0.2f, 0.1f
    8.             }
    9.             yield return new WaitForSeconds (0.0f); // so we don't get errors.
    10.         }
    11.     }
    12.  
    Call the function like
    Code (csharp):
    1.  
    2. StartCoroutine(LerpFoV(40)); // 40 is the fov
    3.  
     
    cafundoestudio likes this.
  15. URGr8

    URGr8

    Joined:
    Sep 10, 2012
    Posts:
    23
    Here is another example for all to use:

    Code (CSharp):
    1.             StartCoroutine(MoveCameraInOut());
    2.  
    Code (CSharp):
    1.     IEnumerator MoveCameraInOut()
    2.     {
    3.         yield return new WaitForSeconds(3.0f);
    4.  
    5.         Camera viewCamera = GameObject.Find("ViewCamera").GetComponent<Camera>();
    6.         if (viewCamera == null)
    7.             yield return null;
    8.         else
    9.         {
    10.            //Zoom the camera in - assumes a perspective camera, if you use orthographic, then use viewCamera.orthographicSize
    11.  
    12.             float startingCameraFOV = viewCamera.fieldOfView; //starting FOV setting
    13.             float endingCameraFOV = 40.0f; // ending FOV setting
    14.             float elapsedTime = 0;
    15.             float waitTime = 3f; // time it should take to zoom, 3 seconds here
    16.             while (elapsedTime < waitTime)
    17.             {
    18.                 viewCamera.fieldOfView = Mathf.Lerp(startingCameraFOV, endingCameraFOV, (elapsedTime / waitTime));
    19.                 elapsedTime += Time.deltaTime;
    20.                 yield return null;
    21.             }
    22.         }
    23.     }
     
    cafundoestudio likes this.