Нежелательное выполнение функции 2 раза

Общие вопросы о Unity3D

Нежелательное выполнение функции 2 раза

Сообщение dvoikik 04 май 2013, 20:14

Доброго времени суток, уважаемые форумчане. Вчера, при написании скрипта GUI, столкнулся с одной проблемой. Ума не приложу, в чем может быть проблема, по уровню моих знаний я перепроверил все, что мог. Привожу описание проблемы:
GUI я разделил на несколько составляющих, каждый из которых может выводиться только в случае, если в этот момент не выводится другая.
Соответственно, в OnGUI запускаютя функции, которые выводят все это дело.
Проблема в том, что в одной из функций есть код (привожу логическую модель)

Синтаксис:
Используется csharp
OnGUI() {
if condition
{
Function()
}
}
void Function() {
if(Input.GetButtonDown("Button"))
{
if(selected == 0)
{
condition = false;
}
else
{
selected = 0;
}
}
 


Но нажатии на Button и при (selected > 0) condition'у все равно присваивается значение false.
Ставил счетчик, выяснил, что при нажатии на Button, функция почему-то выполняется 2 раза: в первый раз он присваивает select значение 0, второй раз уже закрывает элемент GUI, т.к. selected == 0 уже возвращает true.
Хотелось бы узнать, в чем может заключаться проблема. Надеюсь объяснил понятно.
P. S. Скрипт привязан только к одному объекту и только в одном экземпляре.
dvoikik
UNец
 
Сообщения: 3
Зарегистрирован: 14 апр 2013, 21:13

Re: Нежелательное выполнение функции 2 раза

Сообщение Sality 04 май 2013, 22:20

Нужен весьс скрипт, неясно что где обьявлено и где какие переменные еще используются.
Аватара пользователя
Sality
Старожил
 
Сообщения: 771
Зарегистрирован: 26 ноя 2011, 15:31
Откуда: Украина

Re: Нежелательное выполнение функции 2 раза

Сообщение dvoikik 04 май 2013, 22:54

Скрипт пока ооочень недоработан, многие переменные пока не используются, но будут использованы в дальнейшем. Скрипт довольно большой.
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class newGUI: MonoBehaviour {
       
        public int times = 0;
        // General vars
        public GameObject _player, _cso, _sso, _mso, _om;
       
        // GUI stutus
        public bool paused, pausewindow, statuswindow, mapwindow, filewindow, optionwindow;
       
        // Screen and GUI proportions
        public int scrw, scrh, invw, invh, invsx, itemsx, itemsize, dx, dy, dw, dh;
       
        // Inventory vars
        public int capacity, sx, sy, s2x, s2y, my, selected;
       
        // Selection vars
        public GUIStyle mainstyle;
       
        // Zone Textures
        public Texture2D photozone, statzone, weaponzone, inventoryzone, imagezone, infozone, black;
       
        public Rect photorect, statrect, userect, combinerect, inforect;
       
        // Element Textures    
        public Texture2D mapimgact, mapimginact, fileimgact, fileimginact, sel1img, sel2img;
       
        // Menu button Textures
        public Texture2D use, comb, info, usesel, combsel, infosel;
       
        // Status Textures
        public MovieTexture statf, statc1, statc2, statd, statv;
       
        // Element var Textures
        private Texture2D mapimg, fileimg, photoimage, image, useb, combb, infob;
       
        // Status var texture
        /*private*/ public MovieTexture stat;
       
        // ItemVars
        public InventoryItem nullitem, weapon;
       
        // Infotext
        public string infotext, dialogtext;
       
        // Inventory
        public List<InventoryItem> items = new List<InventoryItem>();
        public List<int> quants = new List<int>();
        public List<FileItem> files = new List<FileItem>();
       
        void Start ()
        {
                Screen.showCursor = false;
                _player = transform.gameObject;
                _cso = GameObject.FindGameObjectWithTag("cso");
                _sso = GameObject.FindGameObjectWithTag("sso");
                _mso = GameObject.FindGameObjectWithTag("mso");
                _om = GameObject.FindGameObjectWithTag("optionmus");
                // Просчет переменных пропорций экрана и GUI
                scrh = Screen.height;
                scrw = Screen.width;
                invh = scrh;
                invw = scrh*4/3;
                itemsize = invw/8;
                invsx = (scrw - invw)/2;
                itemsx = invsx + invw/3 + invw/2;
                dx = invsx + invw/6;
                dy = invh*3/4;
                dw = invw*2/3;
                dh = invh/4;
               
                photorect = new Rect(invsx , 0, invw/6, invh/4);
                statrect = new Rect(invsx + invw/6, 0, invw/4, invh/4);
               
                userect = new Rect (invsx + invw/6 + invw/2 - itemsize, invh/4, itemsize, itemsize/2);
                combinerect = new Rect (invsx + invw/6 + invw/2 - itemsize, invh/4 + itemsize/2, itemsize, itemsize/2);
                inforect = new Rect (invsx + invw/6 + invw/2 - itemsize, invh/4 + itemsize, itemsize, itemsize/2);
               
                // Конец просчета переменных пропорция экрана и GUI
               
                photoimage = transform.GetComponent<PlayerChar>().photo;
                capacity = transform.GetComponent<PlayerChar>().invsize;
               
                // Определение стиля
                mainstyle.alignment = TextAnchor.MiddleCenter;
                mainstyle.normal.textColor = Color.green;
                // Конец определения стиля
               
                weapon = nullitem;

                stat.loop = true;
                stat.Play();
               
                for (int i = 0; i < capacity; i++)
                {
                        items.Add(nullitem);
                        quants.Add(0);
                }
               
                sx = 0; sy = 1;
                s2x = 0; s2y = 0;
               
                selected = 0;
        }
       
        void Update()
        {
                if (!mapwindow && !statuswindow && !filewindow && !pausewindow && !optionwindow)
                {
                        paused = false;
                               
                        if (Input.GetButtonDown("Map"))
                        {
                                SoundSelect();
                                mapwindow = true;
                        }
                       
                        if (Input.GetButtonDown("Start"))
                        {
                                pausewindow = true;
                        }
                       
                        /*if (Input.GetButtonDown("Status"))
                        {
                                SoundSelect();
                                statuswindow = true;
                        }*/

                       
                        if (Input.GetButtonDown("Select"))
                        {
                                SoundSelect();
                                optionwindow = true;
                                _om.GetComponent<AudioSource>().Play();
                        }
                }
                else
                {
                        paused = true;
                }
               
                if (paused)
                {
                        Time.timeScale = 0;
                }
                else
                {
                        Time.timeScale = 1;
                }
               
                if (selected == 0)
                {
                        if(Input.GetKeyDown(KeyCode.LeftArrow))
                        {
                                if (sx > 0)
                                {
                                        sx--;
                                        SoundMove();
                                }
                        }
                        if(Input.GetKeyDown(KeyCode.RightArrow))
                        {
                                if (sx < 1)
                                {
                                        sx++;
                                        SoundMove();
                                }
                        }
                        if(Input.GetKeyDown(KeyCode.UpArrow))
                        {
                                if (sy > 0)
                                {
                                        sy--;
                                        SoundMove();
                                }
                        }
                        if(Input.GetKeyDown(KeyCode.DownArrow))
                        {
                                if (sy < capacity/2)
                                {
                                        sy++;
                                        SoundMove();
                                }
                        }
                }
                else
                {
                        if(Input.GetKeyDown(KeyCode.LeftArrow))
                        {
                                if (s2x > 0)
                                {
                                        s2x--;
                                        SoundMove();
                                }
                        }
                        if(Input.GetKeyDown(KeyCode.RightArrow))
                        {
                                if (s2x < 1)
                                {
                                        s2x++;
                                        SoundMove();
                                }
                        }
                        if(Input.GetKeyDown(KeyCode.UpArrow))
                        {
                                if (s2y > 1)
                                {
                                        s2y--;
                                        SoundMove();
                                }
                        }
                        if(Input.GetKeyDown(KeyCode.DownArrow))
                        {
                                if (s2y < capacity/2)
                                {
                                        s2y++;
                                        SoundMove();
                                }
                        }
                }
        }
       
        void OnGUI()
        {
                if (mapwindow)
                {
                        MapWindow();
                }
               
                if (pausewindow)
                {
                        PauseWindow();
                }
               
                if (optionwindow)
                {
                        OptionWindow();
                }
               
                if (statuswindow)
                {
                        StatusWindow();
                }
        }
       
        void StatusWindow()
        {
                GUI.DrawTexture(new Rect(0, 0, scrw, scrh), black, ScaleMode.StretchToFill, false, 0); // Фон
                       
                GUI.DrawTexture(photorect, photoimage, ScaleMode.StretchToFill, false, 0); // Зона фото
                GUI.DrawTexture(photorect, photozone, ScaleMode.StretchToFill, true, 0); // Фото
                       
                GUI.DrawTexture(statrect, stat, ScaleMode.StretchToFill, false, 0); // Зона указ. жизни
                GUI.DrawTexture(statrect, statzone, ScaleMode.StretchToFill, true, 0); // Указ. жизни
                       
                GUI.DrawTexture(new Rect(invsx + invw/6 + invw/4, 0, invw/4, invh/4), weaponzone, ScaleMode.StretchToFill, false, 0); // Зона оружия
                GUI.DrawTexture(new Rect(invsx + invw/6 + invw/4 + invw/8 - itemsize/2, invh/8 - itemsize/2, itemsize, itemsize), weapon.inventoryTextureSmall, ScaleMode.StretchToFill, false, 0); // Оружие
                if (weapon != nullitem)
                {
                        GUI.Label(new Rect(invsx + invw/6 + invw/2 - itemsize/2, invh/4 - itemsize/4, itemsize/2, itemsize/4), "15", mainstyle);
                }
               
                GUI.DrawTexture(new Rect(invsx + invw/6 + invw/2, 0, invw/3, invh), inventoryzone, ScaleMode.StretchToFill, false, 0); // Зона инвентаря
               
                GUI.DrawTexture(new Rect(invsx, invh/4, invw*2/3, invh/2), imagezone, ScaleMode.StretchToFill, false, 0); // Зона большого изображения
                if (selected != 0)
                {
                        image = items[selected - 1].inventoryTextureLarge;
                        GUI.DrawTexture(new Rect(invsx + invw*2/6 - (invh/2 - 40)/2, invh/2 + 10 - (invh/2 - 40)/2, invh/2 - 40, invh/2 - 40), image, ScaleMode.StretchToFill, false, 0); // Большое изображение
                }
               
                GUI.DrawTexture(new Rect(invsx, invh/4 +invh/2, invw*2/3, invh/4), infozone, ScaleMode.StretchToFill, false, 0); // Зона информационного текста
                GUI.Label(new Rect(invsx, invh/4 +invh/2, invw*2/3, invh/4), infotext); // Информационный текст
               
                GUI.DrawTexture(new Rect(itemsx, 0, itemsize, itemsize/2), mapimginact, ScaleMode.StretchToFill, false, 0); // Кнопка Карты
                GUI.DrawTexture(new Rect(itemsx - itemsize, 0, itemsize, itemsize/2), fileimginact, ScaleMode.StretchToFill, false, 0); // Кнопка Файлы
               
                for (int i = 0; i < 2; i ++)
                {
                        for (int j = 0; j < capacity/2; j ++)
                        {
                                GUI.DrawTexture(new Rect(itemsx + itemsize*(i-1), itemsize/2 + itemsize*j, itemsize, itemsize), items[2*j + i].inventoryTextureSmall, ScaleMode.StretchToFill, false, 0);
                                if ((sx == i)&&(sy == j + 1))
                                {
                                        GUI.DrawTexture(new Rect(itemsx + itemsize*(i-1), itemsize/2 + itemsize*j, itemsize, itemsize), sel1img, ScaleMode.StretchToFill, true, 0);
                                }
                                if ((s2x == i)&&(s2y == j + 1))
                                {
                                        GUI.DrawTexture(new Rect(itemsx + itemsize*(i-1), itemsize/2 + itemsize*j, itemsize, itemsize), sel2img, ScaleMode.StretchToFill, true, 0);
                                }
                        }
                }
               
                if (Input.GetButtonDown("Action") && (sy > 0))
                {
                        times ++;
                        SoundSelect();
                        selected = 2*(sy-1) + sx + 1;
                        s2x = sx;
                        s2y = sy;
                }
               
                if (Input.GetButtonDown("Cancel"))
                {
                        if (selected == 0)
                        {
                                statuswindow = false;
                                SoundCancel();
                                sx = 0;
                                sy = 1;
                        }
                        else if (times > 0)
                        {
                                SoundSelect();
                                selected = 0;
                        }
                        s2x = 0;
                        s2y = 0;
                }
        }
       
        void PauseWindow()
        {
                GUI.Box(new Rect(0, 0, Screen.width, Screen.height), "");
                GUI.Label(new Rect(Screen.width/2 - 50, Screen.height/2 - 15, 100, 30), "Pause", mainstyle);
               
                if (Input.GetButtonDown("Cancel"))
                {
                        pausewindow = false;
                }
        }
       
        void MapWindow()
        {
                GUI.DrawTexture(new Rect(0, 0, scrw, scrh), black, ScaleMode.StretchToFill, false, 0); // Фон
               
                if (Input.GetButtonDown("Cancel"))
                {
                        mapwindow = false;
                        SoundCancel();
                }
        }
       
        void OptionWindow()
        {
                if (Input.GetButtonDown("Cancel"))
                {
                        optionwindow = false;
                        SoundCancel();
                        _om.GetComponent<AudioSource>().Stop();
                }
        }
       
        void FileWindow()
        {
               
        }
       
        void GetStatus(int hpstat)
        {
                switch (hpstat)
                {
                case 0:
                {
                        stat = statv;
                        break;
                }
                case 1:
                {
                        stat = statd;
                        break;
                }
                case 2:
                {
                        stat = statc2;
                        break;
                }
                case 3:
                {
                        stat = statc1;
                        break;
                }
                case 4:
                {
                        stat = statf;
                        break;
                }
                }
                stat.Play();
        }
       
        void SoundCancel()
        {
                _cso.GetComponent<AudioSource>().Play();
        }
       
        void SoundMove()
        {
                _mso.GetComponent<AudioSource>().Play();
        }
       
        void SoundSelect()
        {
                _sso.GetComponent<AudioSource>().Play();
        }
}
dvoikik
UNец
 
Сообщения: 3
Зарегистрирован: 14 апр 2013, 21:13

Re: Нежелательное выполнение функции 2 раза

Сообщение vva 05 май 2013, 12:41

для гуи нужно отлавливать евент вместо инпута .
vva
UNITрон
 
Сообщения: 215
Зарегистрирован: 16 мар 2011, 22:22
Откуда: планета земля
Skype: vvavvavva3
  • Сайт

Re: Нежелательное выполнение функции 2 раза

Сообщение dvoikik 05 май 2013, 14:46

For each event OnGUI is called in the scripts; so OnGUI is potentially called multiple times per frame. Event.current corresponds to "current" event inside OnGUI call.

Оказывается, OnGUI может выполнятся несколько раз за фрэйм. Я этого не знал.
Огромное спасибо!
dvoikik
UNец
 
Сообщения: 3
Зарегистрирован: 14 апр 2013, 21:13


Вернуться в Общие вопросы

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 12