Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by oliver-jones · Aug 04, 2011 at 01:42 PM · zoomviewdeltatimewhilefieldofview

Using While Function For Field Of View - Camera

Hello,

I'm adding a zoom function to my rifle, which is basically just lowering the field of view on the main camera. So, when zoom is true:

Camera.main.fieldOfView = 40;

else

Camera.main.fieldOfView = 60;

But I want to make it animated, and I'm guessing I can achieve that by using a 'Time.deltaTime' in a while function:

 function Zoom(){
    if(zoomOn == false){
       zoomOn = true;
       while(Camera.main.fieldOfView > 40){
        Camera.main.fieldOfView -= Time.deltaTime ;
     }
 }

But all this does is jump straight to 40, it doesn't slowly decrease from 60, to 40 ... Any ideas why?

Thanks

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

4 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by GuyTidhar · Aug 04, 2011 at 02:14 PM

Use a coroutine so you only zoom when you need to and avoid update when possible (which in this case is possible):

 public var zoomDuration : float = 0.5;
 private var zooming : boolean = false;

 function Zoom()
 {
    if ( !zooming )
       StartCoroutine("ZoomIn");
 }
 
 private function ZoomIn()
 {
    var deltaT : float = 0;

    zooming = true;
 
    while ( deltaT < zoomDuration  )
    {
       deltaT += Time.deltaTime;
 
       yield;
 
       Camera.main.fieldOfView = Mathf.Lerp(60, 40, deltaT / zoomDuration);
    }
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by benni05 · Aug 04, 2011 at 02:00 PM

Because your while-loop is executed during one single frame.

if the Zoom function is called from an Update function you can just replace the "while" with an "if" like this:

    if(zoomOn == false){
       zoomOn = true;
    } else {
       if (Camera.main.fieldOfView > 40){
          Camera.main.fieldOfView -= Time.deltaTime ;
       }
    }

The built-in Update function already works like a "while" so to speak.

Ben

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image oliver-jones · Aug 04, 2011 at 02:10 PM 0
Share

Okay - but its not called from the update, so what would I do then?

avatar image benni05 · Aug 04, 2011 at 02:18 PM 0
Share

Then the co-routine answer below is the one I would suggest as well.

avatar image
0

Answer by TheDarkVoid · Aug 04, 2011 at 02:44 PM

This is what i used to get it done in my game:

 var wasDown = false;
 void Update()
 
     {
         if(Input.GetMouseButton(1))
 
         {
             if(Camera.main.fieldOfView > 15)
 
                 Camera.main.fieldOfView -= 5;
 
             if(Camera.main.fieldOfView < 15)
 
                 Camera.main.fieldOfView = 15;
 
         }
 
         if(Input.GetMouseButtonUp(1))
 
         {
 
             wasDown = true;
 
         }
 
         if(wasDown)
 
         {
 
             if(Camera.main.fieldOfView <= 50)                    
 
                 Camera.main.fieldOfView += 5;
 
             if(Camera.main.fieldOfView > 50)
 
                 Camera.main.fieldOfView = 50;
 
             if(Camera.main.fieldOfView == 50)
 
             {
 
                 wasDown = false;
             }
         }
        }
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image oliver-jones · Aug 04, 2011 at 03:13 PM 0
Share

This is an okay methord, but if your game is on a slower computer, then the zoom would occur slower as there are less frames per second.

avatar image TheDarkVoid · Aug 04, 2011 at 06:07 PM 0
Share

yea, i will improve upon it but the same layout can be used

avatar image
0

Answer by getluky · Aug 04, 2011 at 07:28 PM

I don't like using coroutines for this type of thing, because a zoom-tap will look all screwed up if you end up with a zoom-in and a zoom-out fighting each other. I prefer setting an active target and using the Update method to lerp towards it with a threshold at which it snaps into place. Apologies for any errors in the below c# snippet:

 float zoomTarget = 60.0f;
 public float zoomSnapThreshold = 0.1f;
 public float zoomSpeed = 1.0f;
 
 public void SetZoomTarget(float to) {
   zoomTarget = to;
 }
 
 void Update() {
   float curFOV = Camera.main.fieldOfView;
   if (Mathf.Abs(zoomTarget - curFOV) > zoomSnapThreshold) {
     Camera.main.fieldOfView = Mathf.Lerp(curFOV, zoomTarget, Time.deltaTime * zoomSpeed);
   } else {
     Camera.main.fieldOfView = zoomTarget;
   }
 }

You could attach this to a C# script and it would move your camera FOV to the target whenever you call SetZoomTarget with a new value. Then you tweak the zoomSpeed value to get a faster zoom, and if it looks jerky at the very end, lower the zoomSnapThreshold keeping it above 0. You could also get fancy if you want to use a different interpolation method, but this should do the trick.

And to answer your original question, a basic rule of thumb might help that Time.deltaTime is only useful inside Update or while loops that yield for a frame (i.e. in coroutines). The way you have it written, it will wind all the way down in the same frame because it never yields for the next frame.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image GuyTidhar · Aug 04, 2011 at 07:54 PM 0
Share

You can still use coroutines and avoid any such screw ups and not use update when you don't have to. Just stop and start the zoom in and zoom out before calling the opposite and make sure you keep setting the same value.

avatar image getluky · Aug 04, 2011 at 10:20 PM 0
Share

$$anonymous$$any ways to skin a cat. There will be slight differences in operation between these two methods, as any Lerp over Time.deltaTime influenced values will appear to ease out without an exact duration, and guyt's will move linearly over an exact duration. From a performance point of view, I wouldn't really say that these two choices are all that different. I'd think that caching the Camera.main reference would have more impact than the overhead of a couple of arithmetic operations in the Update loop for a single GameObject.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

8 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Global 'orbital' map of terrain 0 Answers

Change field of view over time 1 Answer

Script to constantly change FOV? 1 Answer

Sensitivity Help? || Scope Zoom 1 Answer

How to fix(reduce) skewing of objects when changing fieldOfView 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges