Unity3D 3.X Получение Текущего Активного Окна

Недавно наша команда столкнулась с довольно простой задачей.

Нам нужно было перетащить вещи из инвентаря в другие окна (экипировка, сундук).

Если два окна расположены друг над другом, то вещь должна попасть в то окно, которое находится выше.



Unity3D 3.x Получение текущего активного окна

Бегло просмотрев список свойств в классе GUI, я не нашел ничего подходящего, тогда посмотрел GUIUtility и даже посмотрел GUILayout. В общем, такой собственности не существовало нигде.

Погуглив этот запрос, можно найти несколько вопросов в разделе «Вопросы и ответы» и пару скудных постов в оффлайне.

форум, которые заканчиваются ответами в стиле «так делать нельзя, но можно вручную отследить, на какое окно нажимали, и самостоятельно заполнить переменную активного окна».

Ничего из того, что там предлагалось, нас не устраивало, но один парень подал мне интересную идею.

Мы пишем код на C#, а это значит, что мы можем использовать все преимущества этого языка, включая C# Reflection.



Кишки
Скачать мой любимый Дис# , я сразу вошел в код функции Графический интерфейс.

Окно

  
  
   

public static Rect Window(int id, Rect clientRect, GUI.WindowFunction func, string text) { return GUI.DoWindow(id, clientRect, func, GUIContent.Temp(text), GUI.skin.window, true); } internal static Rect DoWindow(int id, Rect clientRect, GUI.WindowFunction func, GUIContent title, GUIStyle style, bool forceRectOnLayout) { GUIUtility.CheckOnGUI(); GUI._Window _window = (GUI._Window)GUI._WindowList.instance.windows[id]; if (_window == null) { _window = new GUI._Window(id); GUI._WindowList.instance.windows[id] = _window; GUI.s_LayersChanged = true; } if (!_window.moved) _window.rect = clientRect; _window.moved = false; _window.opacity = 1.0F; _window.style = style; _window.title.text = title.text; _window.title.image = title.image; _window.title.tooltip = title.tooltip; _window.func = func; _window.used = true; _window.enabled = GUI.enabled; _window.color = GUI.color; _window.backgroundColor = GUI.backgroundColor; _window.matrix = GUI.matrix; _window.skin = GUI.skin; _window.contentColor = GUI.contentColor; _window.forceRect = forceRectOnLayout; return _window.rect; }

Ага, значит список окон есть, осталось узнать в каком порядке они отрисовываются, для этого посмотрим на функцию GUI.BringWindowToFront

public static void BringWindowToFront(int windowID) { GUIUtility.CheckOnGUI(); GUI._Window _window1 = GUI._WindowList.instance.Get(windowID); if (_window1 != null) { int i = 0; foreach (GUI._Window _window2 in GUI._WindowList.instance.windows.Values) { if (_window2.depth < i) i = _window2.depth; } _window1.depth = i - 1; GUI.s_LayersChanged = true; } }

Все понятно, класс GUI имеет одноэлементный класс _WindowList который имеет список окон.

Каждое окно имеет Глубина .

Рендеринг происходит в порядке убывания Глубина .

Осталось выяснить, что это за список.



internal sealed class _WindowList { internal Hashtable windows; internal static GUI._WindowList instance; .



Вот мы и узнали :)

Пишем функцию для отбора хороших вещей
Функция хорошо прокомментирована и, надеюсь, не нуждается в пояснениях.

Теги: #unity3d #C++ #reflection #GUI #Разработка игр #C++ #unity

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.