Mouse Over GUI

Оптимизация кода.

Mouse Over GUI

Сообщение Neodrop 09 июл 2011, 09:26

Малюсенький класс с очень полезной реализацией - затратив минимум усилий, вы всегда будете знать, находится ли мышь над каким-нибудь GUI элементом.

Использование : Просто проверить Event.current.mousePosition на попадание в контроллируемый рект.
Предположим, у вас есть панелька, на ней две кнопки и поле ввода текста. Кнопки и ввод текста проверять нет смысла, а вот панельку стоит проверить. Если она рисуется не лайоутами, то просто проверяете её рект, если наоборот, то используете GUILayoutUtility.GetLastRect и назначаете значение GlobalGUI.MouseOverGUI
Интересует только положительное значение. False же выставится автоматом, если в последнем кадре ни разу небыло TRUE установки.

Вот и всё. Проверил Rect, назначил состояние переменной и забыл о ней. Она обнулится (встанет на False) сама, об этом не стоит беспокоиться.
:-h

Синтаксис:
Используется csharp
 public static class GlobalGUI
    {
        public static bool MouseOverGUI
        {
            get
            {
                return Time.renderedFrameCount <= _lastFrameOverGUI + 1;
            }

            set
            {
                if (value)
                {
                    _lastFrameOverGUI = Time.renderedFrameCount;
                }
            }
        }
        private static int _lastFrameOverGUI;
    }
 
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Mouse Over GUI

Сообщение Woolf 10 июл 2011, 19:08

Конечно спасибо, но за такую структуру организации проекта надо отрезать руки и ссылать на картофелеуборочные работы ))
Идея с флагом isGUIClick гораздо лучше, она не требует повторной проверки координат кнопок и так далее.

Я, кстати, уже почти закончил набор гуи классов по принципу "Создал и забыл". Т.е. создал окно, кнопки, лейблы, эдиты - а потом только обрабатывай от них события.
Как закончу - выложу для всех,. (хотя, этот гуиманагер разрабатывается для моей новой игры )
Разработчик theFisherOnline - там, где клюёт
Разработчик Atom Fishing II - Первая 3D MMO про рыбалку
Разработчик Atom Fishing - Рыбалка на поплавок, донку, нахлыст, блесну в постъядерный период.
Аватара пользователя
Woolf
Адепт
 
Сообщения: 7179
Зарегистрирован: 02 мар 2009, 16:59

Re: Mouse Over GUI

Сообщение asterkhov 11 июл 2011, 19:38

Woolf писал(а):Конечно спасибо, но за такую структуру организации проекта надо отрезать руки и ссылать на картофелеуборочные работы ))
Идея с флагом isGUIClick гораздо лучше, она не требует повторной проверки координат кнопок и так далее.


А в какой момент устанавливать флаг isGUIClick? Обработка нажатий происходит в OnGUI. Если OnGUI вызывается раньше всех Update() то оно сработает. Я просто не нашел в какой момент вызывается OnGUI.
А проверять того что указатель мыши находится надо гуями по моему вполне себе решение, единственно что действительно надо проверять самый большой гуёвый элемеент (незачем проверять кнопки внутри панельки).

p.s. Нашел: OnGUI is called for rendering and handling GUI events.
т.е. OnGUI вызывается на этапе отрисовки, что в свою очередь после всех вызовов Update(), соответственно нажатие кнопки мыши уже было отработано в Update(), что не есть правильно.
Аватара пользователя
asterkhov
UNец
 
Сообщения: 20
Зарегистрирован: 22 мар 2011, 10:18

Re: Mouse Over GUI

Сообщение Neodrop 12 июл 2011, 09:26

Woolf писал(а):Конечно спасибо, но за такую структуру организации проекта надо отрезать руки и ссылать на картофелеуборочные работы ))
Идея с флагом isGUIClick гораздо лучше, она не требует повторной проверки координат кнопок и так далее.

Я не имею ни малейшего понятия чем вы тут засоряете мою тему. Какой флаг isGUIClick ?
Не понравился код - напишите лучше.
З.Ы. Rect.Contain черезвычайно быстрая операция, кстати.


asterkhov писал(а):А проверять того что указатель мыши находится надо гуями по моему вполне себе решение, единственно что действительно надо проверять самый большой гуёвый элемеент (незачем проверять кнопки внутри панельки).

А я разве про это не написал ? :-?

Обоим предупреждение за мусор в чужой теме. В следующий раз накажу.
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Mouse Over GUI

Сообщение Medveckij 30 дек 2012, 11:44

Странный script. Первый случай когда я вообще ничего не понял, но очень надо. Можно мини скрипт с готовой сценкой?

Я понимаю, что подобного рода вопрос на этом (да и вообще) форуме приветствуется если вопрошающий хочет пулю в лоб.
Дело в том что я себе уже мозг стер по данной теме. На Unity community ответа не нашел тем более.

Пожалуйста, люди, help.


Сделал вот таким вот образом:
Но это ведь шляпа, ИМХО.

Синтаксис:
Используется csharp

void Update()
        {
           Vector2 mousePos = new Vector2(Input.mousePosition.x,Screen.height - Input.mousePosition.y);
               
                if(BottomRegion.Contains(mousePos))
           {
             moving.SP.raycastHitOff();
                         Debug.Log("Off");
           }
                else
                {
                        moving.SP.raycastHitOn();
                        Debug.Log("On");
                }
        }

 
Аватара пользователя
Medveckij
Адепт
 
Сообщения: 1014
Зарегистрирован: 10 ноя 2012, 15:44

Re: Mouse Over GUI

Сообщение Neodrop 30 дек 2012, 16:03

Я так понимаю, вы рейкастите какие-то коллайдеры от камеры? В вашем коде идея работать не будет вовсе, потому что нет ресета состояния mouseOver

Код выше работает следующим образом :
Представим, что у вас есть 5 окон интерфейса. Каждое в каждом кадре проверяет нет ли мыши над ним и каждое выставляет полученное значение в этот статический флаг.
Если кто-то устанавливает флаг MouseOverGUI в true, класс запоминает в каком кадре это было сделано и в данном кадре уже не сбросится на false.
Если кто-то запрашивает состояние флага MouseOverGUI, то если флаг в true, класс проверяет, в данном ли кадре было установлено состояние. Если нет, то возвращает false.

Таким образом, если уж мышь над каким-то окном, флаг гарантированно выставится в true. Если мышь выйдет за пределы всех проверяемых областей, то и флаг тоже, гарантированно станет false.

Чтобы использовать мой код, вам достаточно просто ставить его в true или в false там, где вы проверяете состояние мыши относительно GUI элементов.
Правда, если вы делаете свои рейкасты в Update, то проверять значение флага стоит в LateUpdate (чтобы все рейкасты успели отработать до проверки состояния флага.)
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Mouse Over GUI

Сообщение Medveckij 30 дек 2012, 20:53

Ммм, вот оно как. Большое спасибо за подробное объяснение, буду иметь ввиду.

А задачу я решил просто. Примерно вот так:

Скрытый текст:
public static Rect BottomRegion = new Rect(0, 0, 80, 300);

int count = Input.touchCount;

for (int i = 0; i < count; i++)
{
Touch touch = Input.GetTouch (i);

Vector2 fingerPos = new Vector2(touch.position.x,Screen.height - touch.position.y);

if (touch.phase == TouchPhase.Began)

if(BottomRegion.Contains(fingerPos))
{
//off

}

else
{

OnTouchBegan(touch.fingerId, touch.position); //on
}

else if (touch.phase == TouchPhase.Canceled || touch.phase == TouchPhase.Ended)
OnTouchEnded(touch.fingerId);



Тоже самое и для мыши.

Еще раз спасибо :)
Аватара пользователя
Medveckij
Адепт
 
Сообщения: 1014
Зарегистрирован: 10 ноя 2012, 15:44

Re: Mouse Over GUI

Сообщение Seola 15 июл 2016, 19:51

Всем привет. Использую GUI.matrix = Matrix4x4.TRS. Старые способы проверки перестали работать. Проверяет как будто GUI.matrix не работает. Детект происходит на том месте где рект должен был быть без матрицы. Поможет ли этот метод корректно отловить событие и если да то не мог бы кто то скинуть пример как использовать данный код. Что то попробовал не выходит.
Аватара пользователя
Seola
UNец
 
Сообщения: 33
Зарегистрирован: 30 май 2013, 07:41


Вернуться в Код

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2