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
1
Question by Hurley · Jun 03, 2016 at 06:37 PM · coroutine

OnGUI called after WaitForEndOfFrame on mouseDown events

When running this code:

 public class TestScript : MonoBehaviour {

     // Use this for initialization
     void Start () {
     
     }
     
     // Update is called once per frame
     void Update () {
         Debug.Log("----------------beginning of frame");
         StartCoroutine("EndOfFrame");
     }

     private void OnGUI()
     {
         Debug.Log("------------OnGui" + Event.current.type);
     }

     IEnumerator EndOfFrame()
     {
         yield return new WaitForEndOfFrame();
         Debug.Log("----------------end of frame");
     }
 }

We get this output:

 ----------------beginning of frame
 ------------OnGuiLayout
 ------------OnGuiRepaint
 ----------------end of frame
 ----------------beginning of frame
 ------------OnGuiLayout
 ------------OnGuiRepaint
 ----------------end of frame
 ------------OnGuiLayout
 ------------OnGuimouseDown
 ----------------beginning of frame
 ------------OnGuiLayout
 ------------OnGuiRepaint
 ----------------end of frame

To our knowledge, the "endOfFrame" text should happen after the "OnGuimouseDown" text but before the "beginning of frame" text, but instead it always appears after the "OnGuiRepaint" text. Is there something we are doing wrong with the yield WaitForEndOfFrame coroutine? It happens in a built engine and in the editor.

Comment
Add comment · Show 4
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 ninja_gear · Jun 03, 2016 at 06:52 PM 0
Share

OnGUI is called in a FixedUpdate manner.... meaning several times between frames.

OnGUI is also being depreciated soon. I suggest a Prefab > Instantiate method to avoid problems with your project/updating Unity.

avatar image Bunny83 ninja_gear · Jun 03, 2016 at 09:16 PM 0
Share

OnGUI isn't being deprecated. Why does everybody spread that information? The immediate mode GUI is still used by the Unity editor. The whole interface of the editor is using the immediate mode. Even the new GUI still uses parts of the Event class for keyboard input processing.

avatar image ninja_gear Bunny83 · Jun 03, 2016 at 10:13 PM 0
Share

"I$$anonymous$$GUI is a code-driven GUI system, and is mainly intended as a tool for programmers."

http://docs.unity3d.com/$$anonymous$$anual/GUIScriptingGuide.html

I think by this comment they mean not intended for a UI solution in a project. Prolly a good idea to not tell people to implement for a final solution as a UI in a game.

Show more comments

1 Reply

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

Answer by Bunny83 · Jun 03, 2016 at 09:10 PM

You interpreted the result wrong. It's not called after the end of the current frame, but at the beginning of the next frame. The input processing happens before Update. Try printing Time.frameCount with each of your Debug.Logs to see to which frame the log belongs. See the event order. The diagram isn't complete but it should give a better overview. Note that the point "GUI rendering" really only includes the actual repaint event, not the input processing which is done at the beginning of the frame.

There is no reliable callback that is always called at the very beginning of a frame. The best option is to do frame initialization things at the very end of your "WaitForEndOfFrame" coroutine.

An alternative is to do initialization in a seperate method which you call before anything else in any of your functions. The method only executes it's body if the current frame count is greater than the last saved frame count.

 int lastFrame = -1;
 
 void Init()
 {
     if (Time.frameCount > lastFrame)
     {
         lastFrame = Time.frameCount;
         // Do your frame initialization here.
     }
 }

You can savely call Init as often as you want before you do anything else. This method will only execute once per frame due to the frame count check.

Comment
Add comment · Show 1 · 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 Hurley · Jun 06, 2016 at 02:30 PM 0
Share

This is a great answer, thanks for the insight! Indeed the frame count increases just before those last two GuiLayout and Gui$$anonymous$$ouseDown events. It looks like the documentation is incorrect like you said, in that OnGui input events are handled before the Update function is called, rather than in the Gui Rendering area (which makes sense from a standard game loop perspective).

I'll try out your Init() function idea. Thanks!

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

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Increment variable over time 4 Answers

Blinking & resource consumption 1 Answer

StartCoroutine gets the arglist type wrong 1 Answer

Invoke isn't working for a function with yield? 2 Answers

Yielding in a loop only as needed? 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