Search Unity

  1. Check out our Unite Austin 2017 YouTube playlist to catch up on what you missed. More videos coming soon.
    Dismiss Notice
  2. Unity 2017.2 is now released.
    Dismiss Notice
  3. The Unity Gear Store is here to help you look great at your next meetup, user group or conference. With all new Unity apparel, stickers and more!
    Dismiss Notice
  4. Introducing the Unity Essentials Packs! Find out more.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice
  6. Unity 2017.3 beta is now available for download.
    Dismiss Notice

OnGUI() problem - firing twice a time! [SOLVED]

Discussion in 'Scripting' started by Kokumo, Jul 25, 2010.

  1. Kokumo


    Jul 23, 2010
    Hello guys!
    First of all, excuse me for my english; i'm a spanish native speaker.

    I'm learning how to develop games in Unity 3D by myself, so i decided to make a FPS to play with my friends (the best motivation i found to achieve my goal).
    I wrote my weapon's manager (SC_ManagerArmas.cs) which listen through OnGUI method (it doesn't listen really... well, i think you may understand what i'm trying to say) what kind of key is pressed by the gamer, and then changes the character weapon: 1 for granade launcher, 2 for shuriken launcher, and 3 for a pistol.

    The problem - firing weapons:
    If i put the code that allow firing the current weapon into Update() method, everything go well; however, if i put the code into OnGUI() method, the weapon shots twices a time.

    Anyone can help me with this issue?

    Thaks a lot!

    ps: you will see an interface's method call; i like more implement an interface rather than use a broadcasting.

    Code (csharp):
    2. using UnityEngine;
    3. using System.Collections;
    5. public class SC_ManagerArmas : MonoBehaviour {
    7.    private Camera vision;
    8.    private RaycastHit rayResultado;
    9.    private Ray rayoVision;
    10.    private IArmas armaActual;
    12.    //i'm setting the vision for my raycast and first weapon
    13.    private void Awake () {
    14.       vision =;
    15.       elegirArma(0);
    16.    }
    18.    //firing a weapon!... here it shots once a time
    19.    private void Update() {
    20.       if (Input.GetButtonDown("Fire1")) {
    21.       rayoVision = vision.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0));
    23.       if (!Physics.Raycast(rayoVision, out rayResultado))rayResultado.point =;
    25.       armaActual.Disparar(rayResultado);
    26.       }
    27.     }
    29.    private void OnGUI() {
    30.         if (Input.GetKeyDown("1")) {
    31.             elegirArma(0);
    32.         } else if (Input.GetKeyDown("2")) {
    33.             elegirArma(1);
    34.         } else if (Input.GetKeyDown("3")) {
    35.             elegirArma(2);
    36.     }
    37. /* SHOTS TWICE!
    38.         else if (Input.GetButtonDown("Fire1")) {
    39.            rayoVision = vision.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0));
    40.            if (!Physics.Raycast(rayoVision, out rayResultado))rayResultado.point =;
    41.             armaActual.Disparar(rayResultado);
    42.     }*/
    43.     }
    45.    private void elegirArma(int indice) {
    46.       GameObject goTemp;
    47.       for (int i=0; i< gameObject.transform.childCount; i++) {     
    48.          goTemp = transform.GetChild(i).gameObject;
    49.          if (i == indice) {
    50.             goTemp.SetActiveRecursively(true);
    51.             armaActual = (IArmas) goTemp.GetComponentInChildren(typeof(IArmas));
    52.           } else goTemp.SetActiveRecursively(false);
    54.       }
    56.    }
    58. }
  2. AkilaeTribe


    Jul 4, 2010
    Why would you set irrelevant code in the OnGUI function instead of the Update ?

    Who told you to put this code in OnGUI, if Update works ?
  3. Eric5h5


    Volunteer Moderator Moderator

    Jul 19, 2006
    OnGUI runs at least twice per frame, by design. Don't use it for anything except GUI code.

  4. Kokumo


    Jul 23, 2010
    AkilaeTribe, Eric5h5, thanks for your answers.

    As you said Eric5h5, i just realize OnGUI it's called several times per frame; i have to recognize that i could check this out at Unity Script Reference before post my doubt here... a friend of mine told me that there wasn't any explanation in the web. Next time, i will take a look.

    AkilaeTribe, i wrote the code OnGUI because i thought was the right place where to put it; i'm a newbie and i'm giving my best, but looks like i have a long road to go... sorry :(

    Perhaps this post will serve to someone who, like me, make this mistake.

    Thanks people!
  5. Robert G

    Robert G

    Nov 17, 2009
    Don't be so hard on yourself Kokumo, you actually did the right thing.
    Asking questions to find out that you did it the wrong way.
    That is how we learn things!

    All the best, Robert
  6. dxchen


    Sep 17, 2009
    I did some test about this topic. And I have some conclusions. If there is anything wrong , please tell me.

    First, we know that unity will call Update() function per frame, and will call OnGUI() per Event.
    When one frame is updated , Unity will receive more than one Event, and need to initiate that event before call OnGUI. and the initiate will also send one event to OnGUI, that is EventType.Layout.
    Except EventType.Layout, Unity will send EventType.Layout before all Events are send to OnGUI.
    So we know every frame updated, OnGUI will called at least two times. The first one is EventType.Layout , the second one isEventType.Repaint.

    Before receiving EventType.Repaint,OnGUI will be called by all other Events. ex: EventType.MouseMove, after that, called by EventType.Repaint.
    Of course, before EventType.MouseMove and EventType.Repaint , there are also EventType.Layout.

    So you can do the test, if you move the mouse , than, your OnGUI will be called my four Events during one frame is updated. Those four events are:

    Here is my test code:
    Code (csharp):
    1. function Update () {
    2.    print("Update Event.current = "+Event.current + "     Time.time " + Time.time + "     Time.realtimeSinceStartup " + Time.realtimeSinceStartup);
    3. }
    4. function OnGUI ()
    5. {
    6.    print("OnGUI Event.current = "+Event.current + "     Time.time "+ Time.time + "     Time.realtimeSinceStartup " + Time.realtimeSinceStartup);
    7. }
    It refer by those data below:

    Here are some import hints:
    1.For each event OnGUI is called in the scripts;
    EventType.Layout is sent prior to anything else - this is a chance to perform any initialization. It is used by the automatic layout system.
    All other events are processed first, then the repaint event is sent.
    4.Event Execution Order
  7. dxchen


    Sep 17, 2009
    There is another topic, I want to discuss.

    if I use function Update() to receive the iPhoneTouch event

    we have example in the document just like this:
    Code (csharp):
    1. function Update () {
    2.     if (iPhoneInput.touchCount > 0 )
    3.     {
    4.         if(iPhoneInput.GetTouch(0).phase == iPhoneTouchPhase.Ended)
    5.         {
    6.             //...
    7.         }
    8.     }
    9. }
    But I notice there is a special situation happened.
    that is iPhoneTouchPhase.Ended Event happened but iPhoneInput.touchCount = 0 in the function Update.
    Is there anyone have this problem?