Аспекты реализации собственного GUI

Программирование на Юнити.

Аспекты реализации собственного GUI

Сообщение Akai 28 окт 2010, 11:23

Введение

Кто-то, прочитав заголовок темы, сразу подумает: «А смысл?» — и отчасти будет прав. Но только отчасти.

Я и сам некоторое время назад пользовался интегрированным гуем Юнити и не комплексовал по этому поводу. Ну, а что? Всё, что необходимо в работе для вывода информации, относительно легко и относительно же просто реализуется с его помощью. Для подавляющего большинства проектов его возможности покрывают потребности.

Но, как водится, тут есть ещё кое-что, маленькая ложка дёгтя в этой бочке мёда.

Для наглядности снабжу пример иллюстрацией из жизни. Вот есть у меня, как это модно говорить, проект, а в нём — сцена, а в сцене — компьютеры. С монитором, клавиатурой и мышкой — всё как положено. Стоят на столах и ждут. Предполагается, что игрок может подойти к любому и поработать на нём (например, выйти в интернет, в «Сапёра» потыкать или раскинуть «Косынку» — что-то одно или всё сразу — я ещё не определился).

И вот тут я словно наткнулся на стену. Оказалось, что с помощью интегрированного гуя Юнити невозможно реализовать трёхмерный интерфейс пользователя (ну да, открыл Америку). Почему и отчего так — этот вопрос адресуй к разработчикам Видимо, им и в голову не пришло при проектировании и разработке этой подсистемы движка, что иногда гуй нужен не только двумерный. К слову, в фич-риквест-листе запрос на трёхмерный гуй (на рендер гуя в текстуру, что в условиях моей задачи эквивалентно) находится уже больше года.

Как я стал решать означенную задачу.

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

Вторым моим шагом стала попытка прикрутить к Юнити существующий гуй. Был выбран gtk+, как имеющий байндинг для дотНета — gtk#. Попытка провалилась. И это было очевидно с самого начала эксперимента, так как gtk# использует для вывода собственную графическую библиотеку (или там враппер — это не суть важно) gdk и собственные средства для контроля устройств ввода. Сего факта Юнити пережить оказалась не в состоянии. Она просто молча падала при каждой попытке запуска основного цикла gtk# (хотя инициализация и создание виджетов никакой видимой реакции не вызывали).

Однако необходимо заметить, что теоретически вот этот вариант весьма и весьма правильный.

Что я хочу этим сказать. А то, что gtk легко доступен в исходниках и при наличии времени и упорства может быть немножко переписан (правда, легко может оказаться, что придётся переписывать очень даже «множко»). И в итоге получится гибкий и мощный гуй. На котором можно будет даже немного заработать (кажется, лицензия GNU LGPL позволяет, если ошибаюсь, прошу поправить).

Есть большое количество других открытых гуёв (хм... интересное словечко), с которыми при этом можно творить, что душа пожелает, и ничего тебе за это не будет. Но в большинстве своём написаны они или на чистом С или на С++ и при этом байндингов под дотНет не имеют. Это, конечно, не фатально, но объём работы (и, как следствие, временные затраты) в данном случае значительно увеличивается. А работать-то хочется прямо сейчас.

Есть, например, известный в определённых кругах CE GUI. Что я успел к данному моменту вычитать из документации по нему, так это то, что он позволяет создавать собственный рендер для вывода. Очень интересная возможность. Кроме того, существует байндинг к нему для c# (правда, он мёртв уже два года и выглядит и пахнет соответственно, то есть, как мертвец).

Возможности есть. Но неизвестно, что проще: адаптировать к условиям Юнити существующий гуй или написать с нуля новый. В этом свете закономерный мой третий шаг — это как раз и есть разработка собственной системы.

Ах да, вот только вспомнил, есть ведь EZ GUI (читается: изи гуй). Кто не видел его демы, рекомендую глянуть, впечатляет. Весьма и весьма. Отзывы о нём неплохие. Но есть у него один (это как минимум) большой и жирный минус — он денег стоит (в одно рыло — 50 баксов). Для меня сейчас проблема на автобус 10 рублей найти (ах, чёрт, с 1 ноября уже 12), так что этот вариант я даже не рассматривал.

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

Итак, переписывать существующий никакого желания не было и нет. Покупать — просто отсутствует необходимая денежная сумма. Решение очевидно — писать своё. Наверное, не очень умное. Мне самому с этой позиции его сейчас не оценить. Это надо со стороны смотреть. А если есть ещё какие-то выходы из ситуации, камрад, подскажи.

Аспекты реализации

Это была вводная часть, а теперь непосредственно перехожу к аспектам реализации собственного графического интерфейса пользователя.

Я видел перед собой необходимость разработки следующих частей гуя:
– подсистема обработки ввода и реализация на её основе подсистемы вызова событий гуя;
– подсистема графического отображения гуя;
– собственно иерархия классов для объектов гуя, так называемых виджетов, хотя мне привычнее называть их контролами (ударение на первый слог).

Если с виджетами всё должно быть ясно без дополнительных пояснений, то о вводе и рендеринге стоит высказать несколько дополнительных соображений.

В Юнити есть всё, что требуется самому взыскательному разработчику для отслеживания событий пользовательского ввода. Можно без труда получить состояние абсолютно любой клавиши на клавиатуре, кнопки мыши и даже кнопок джойстика (хотя ввиду отсутствия джойстика этого мне протестировать не удалось). Что интересно, координаты курсора мыши («in pixel coordinates» — цитата из Scripting Reference), которые отдаёт Юнити, имеют не целочисленный тип (в том числе и движение колеса), что несколько нелогично, так как дробного числа пикселов на экране просто физически быть не может.

Есть ещё один нюанс, который стоит учитывать при программировании пользовательского ввода и гуя: координаты нуля для экрана при вводе и рендеринге (например, с использованием интегрированного гуя) не совпадают. Для мыши нуль находится в левом нижнем углу экрана, а для гуя — в левом верхнем углу (что традиционно, привычно и понятно). Откуда взялось такое несоответствие, мне выяснить не удалось — могу только догадываться. Из этого следует, что для того, чтобы перевести координаты в одну систему отсчёта, необходимо, например, из координаты Y мыши вычитать высоту экрана:

Y = Y0 – Screen.height,

где
Y – координата Y мыши в системе гуя с нулём в левом верхнем углу экрана;
Y0 – координата мыши, которую отдаёт Input Юнити;
Screen.height – текущая высота экрана.

Ну, это очевидно.

Также необходимо заметить, что в Юнити проверка состояния клавиш и кнопок производится вызовом нескольких типов функций: проверка для виртуальных кнопок (функции GetButton это для проверки по псевдонимам клавиш), проверка для кнопок мыши (функции GetMouseButton) и проверка для всех клавиш и кнопок (функции GetKey).

Для организации корректной гуевой подсистемы ввода необходимо осуществлять диспетчеризацию всех событий ввода, а для этого надо знать состояние абсолютно всех клавиш на клавиатуре и кнопок мыши. А для этого требуется проверить их все путём вызова соответствующих функций. В данном контексте использование функций GetMouseButton не оптимально, так как определения для кнопок мыши входят в перечисление UnityEngine.KeyCode и прекрасно тестируются функциями GetKey (обычным циклом по перечислению).

Про рендер гуя говорить много не буду, так как, полагаю, что всё очевидно.

Рендер должен обеспечивать как можно менее затратный (в плане количества draw call'ов в терминологии Юнити) вывод. В идеале должен быть лишь один вызов для отрисовки всего гуя (собственно, эта задача проста до невозможности). Для этого необходимо работать с гуем в памяти, лишь при необходимости собирая его элементы в единую текстуру, которая затем отдаётся Юнити.

В реализации возможны два способа. К сожалению, у меня не было возможности сравнить их по затратам памяти и производительности. Первый способ: отрисовка элементов каждый раз по новой на единственной внеэкранной поверхности с последующим её копированием в текстуру. Второй способ: подготовка внеэкранной поверхности для каждого элемента гуя и отрисовка всего один раз (дальнейшая перерисовка требуется лишь при изменении каких-либо параметров элементов) и последующее копирование в текстуру Юнити (или другую внеэкранную поверхность — например, для создания какие-то эффектов — тогда уже её нужно будет копировать в текстуру).

Есть чисто умозрительный вывод, что первый способ будет менее расходовать память, чем второй, а по скорости работы они примерно одинаковы. Для создания же скинующегося интерфейса придётся пользоваться вторым способом, так как в этом случае затраты на масштабирование битмапов при отрисовке станут превышать затраты на копирование. Впрочем, может быть, на деле всё и не так будет. Ещё раз повторюсь: это всего лишь мысли, не подкреплённые опытными данными.

Собственно сама реализация гуя, если говорить об иерархии классов объектов, не представляет сложности даже для неопытного программиста.

Что сделано

– Подсистема обработки ввода Юнити.

Производит форматирование информации ввода в понятную контролам (виджетам) гуя, затем на основе этой информации диспетчер дёргает контролы за яй... э... осуществляет вызов соответствующих ивентов.

Обработка ввода пока происходит только в экранном пространстве.

– Иерархия классов объектов гуя.

Реализованы следующие классы: базовый контрол, кнопка, лэйбл (короткий текст), чекбокс, радиобатон, окно (не полностью). Контролы поддерживают объединение в контейнеры (по принципу один родитель— неограниченно детей). Вызываются следующие ивенты: получение и потеря фокуса ввода, нажатие, удержание и отпускание клавиши клавиатуры, нажатие, удержание и отпускание кнопки мыши, двойной клик мышью, движение колеса мыши, движение указателя мыши.

Этого минимума вполне достаточно для демонстрации принципов.

– Подсистема вывода изображения.

При подготовке гуя производится рендеринг элементов во внеэкранную поверхность, которая после необходимых преобразований (связанных с особенностями хранения битмапов в памяти) копируется в текстуру Юнити и рендерится. Для рисования элементов гуя используется библиотека векторного рисования cairo (если точнее, то её дотНет байнд Mono.Cairo). Для вывода текста используется она же (работает в UTF-8).

Cairo производит достаточно быстрый рендеринг, так что здесь единственное тонкое место — копирование битмапа из памяти в текстуру.

GUI_img_0.png

GUI_img_1.png


Что сделать

Безусловно, с настоящим наборов контролов интерфейс не может считаться полнофункциональным. Пока это всего лишь демонстрация. Необходимо ещё как минимум реализовать меню, текстовые поля для ввода и отображения больших объёмов текста, полосы прокрутки. Также необходимо реализовать возможность создания скинов для интерфейса.

Крайне важно обеспечить корректную работу ввода не только в экранных координатах, но и в координатах сцены.

Необходимо также уточнить, что представленное решение подходит пока что только для standalone-сборок, в браузере этот интерфейс работать не будет.

А нахрена?

Вроде я сказал всё, что хотел. Надеюсь, это небольшое эссе не утомило тебя, камрад.

А теперь самый главный вопрос: а для чего всё это? А вот для чего. Я догадываюсь, что не единственный такой на свете, кому вдруг понадобилась возможность рендерить гуй в текстуру. Ну, и вот, может быть, ты тоже как-то что-то похожее когда-нибудь делал в Юнити? Я хочу знать, что у тебя получилось, а что нет и почему?

Хочу обменяться опытом.

Да, демки пока нет, только скриншоты, и кода не привожу, поскольку его много, да и не нужен здесь он, разговор-то ведь скорее о принципах нежели. Но если попросишь, покажу код, естественно не весь (ещё раз: его реально много), а только интересующие места.
У вас нет доступа для просмотра вложений в этом сообщении.
Akai
UNец
 
Сообщения: 29
Зарегистрирован: 11 сен 2010, 08:26
Откуда: Вельск

Re: Аспекты реализации собственного GUI

Сообщение Pyx 28 окт 2010, 12:24

Может я не совсем допонял суть,но что мешает подобный GUI сделать обычными плашками ?И через Editor Script написать удобный инструмент для использования.
Pyx
 

Re: Аспекты реализации собственного GUI

Сообщение gnoblin 28 окт 2010, 14:09

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


Можно).

Texture2D.ReadPixels()
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Аспекты реализации собственного GUI

Сообщение gnoblin 28 окт 2010, 14:11

Я делал переход от гуи к "гуи на плейнике, который улетает".

А так вообще много букв, интересно почитать, спасибо!

Буду ждать демку :) .

Классно когда люди не ленятся писать о своем опыте [unity 3D]
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Аспекты реализации собственного GUI

Сообщение Neodrop 28 окт 2010, 16:59

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

Re: Аспекты реализации собственного GUI

Сообщение Akai 28 окт 2010, 18:03

Pyx писал(а):Может я не совсем допонял суть,но что мешает подобный GUI сделать обычными плашками ?И через Editor Script написать удобный инструмент для использования.

Ну, вот навскидку:
1. Большое неудобство применения (позиционирование и масштабирование).
2. Сильный батхёрт при реализации работы с текстом. Легко выливающийся в увеличение количества дро коллов.
3. То же самое, но уже при обработке ввода.
Как, например, быстро отловить движение мышки над плашкой, если плашка произвольно расположена и произвольно же ориентирована в пространстве? Не, я понимаю, что надо сначала проверить расстояние между плашкой и игроком, потом координаты крысы перегнать в локальную систему координат плашки, спроецировать точку (где как бы находится крыса) на плашку, и дальше уже всё не так сложно, но это же лишние расчёты.
4. Добавляется новая сущность — геометрия, хотя можно обойтись только текстурой — так и хочется взять в руки бритву Оккама.
Если подумать, может быть, ещё что-нибудь придумаю.

Мне сразу с текстурой работать показалось проще.

gnoblin писал(а):Буду ждать демку :) .

Я постараюсь что-нибудь эдакое подготовить. Но вряд ли это случится очень скоро.

Neodrop писал(а):В разработке новый GUI для Unity
Просто предупреждаю - не стрельба ли это по воробьям из пушки?

Да, я знаю, что его разрабатывают. И с большим удовольствием я воспользовался бы им. Вот если бы только знать точно, что он сможет, а что нет... И потом, когда ещё его зарелизят?.. Знать бы, я, конечно, взялся совсем за другое, но у меня прямо с первой сцены, с самого меню востребован трёхмерный гуй, и без него совсем никак.
Akai
UNец
 
Сообщения: 29
Зарегистрирован: 11 сен 2010, 08:26
Откуда: Вельск

Re: Аспекты реализации собственного GUI

Сообщение Neodrop 28 окт 2010, 18:22

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

Re: Аспекты реализации собственного GUI

Сообщение gnoblin 28 окт 2010, 18:30

> 1. Большое неудобство применения (позиционирование и масштабирование).
Не понял, пачему неудобно?

> 2. Сильный батхёрт при реализации работы с текстом. Легко выливающийся в увеличение количества дро коллов.
Батхерт если только потому что надо писать велосипед ).

> 3. То же самое, но уже при обработке ввода.
> Как, например, быстро отловить движение мышки над плашкой, если плашка произвольно расположена и произвольно же ориентирована в пространстве? Не, я понимаю, что надо сначала проверить расстояние между плашкой и
> игроком, потом координаты крысы перегнать в локальную систему координат плашки, спроецировать точку (где как бы находится крыса) на плашку, и дальше уже всё не так сложно, но это же лишние расчёты.
OnMouseOver и коллайдер?
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Аспекты реализации собственного GUI

Сообщение Tolking 29 окт 2010, 10:35

Одну поверхность удобнее размещать чем несколько, а если окошек в ГУИ больше одного и кнопочек много? Как это будет выглядеть с плашками?!!!

Если OnMouseOver и коллайдер - значит разные объекты и не один ДравКол? Если собрать програмно из своих квадов поверхность, то хорошо получится, но реализация сложная, нужно учитывать перекрываемость окон и т.п. (и дравкол не один) Главное приемущество квадов/плашек нет необходимости перерисовывать весь интерфейс при изменении состояния одного контрола.

P.S. ИМХО если не нужно выводить интерфейс в 3Д нет смысла гимороиться со всем этим... Да и если нужно пару кнопок сделать в 3Д тоже огород городить не стоит... Нужен "работающий" компьютер в игре? Сделал объект интеракитвный, кликнул понему "развернул" экран игрушечного монитора на настоящий и работай в 2Д.
Ковчег построил любитель, профессионалы построили Титаник.
Аватара пользователя
Tolking
Адепт
 
Сообщения: 2715
Зарегистрирован: 08 июн 2009, 18:22
Откуда: Тула

Re: Аспекты реализации собственного GUI

Сообщение gnoblin 29 окт 2010, 14:15

Одну поверхность удобнее размещать чем несколько, а если окошек в ГУИ больше одного и кнопочек много? Как это будет выглядеть с плашками?!!!

А как будет выглядеть?

Если OnMouseOver и коллайдер - значит разные объекты и не один ДравКол? Если собрать програмно из своих квадов поверхность, то хорошо получится, но реализация сложная, нужно учитывать перекрываемость окон и т.п. (и дравкол не один) Главное приемущество квадов/плашек нет необходимости перерисовывать весь интерфейс при изменении состояния одного контрола.

Коллайдер к дроколам никакого отношения не имеет. Можно сделать и в 1 дк.

P.S. ИМХО если не нужно выводить интерфейс в 3Д нет смысла гимороиться со всем этим... Да и если нужно пару кнопок сделать в 3Д тоже огород городить не стоит... Нужен "работающий" компьютер в игре? Сделал объект интеракитвный, кликнул понему "развернул" экран игрушечного монитора на настоящий и работай в 2Д.
[/quote]

С тем что напрягаться надо поменьше, я согласен :D
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Аспекты реализации собственного GUI

Сообщение Akai 29 окт 2010, 15:18

gnoblin писал(а):> 1. Большое неудобство применения (позиционирование и масштабирование).
Не понял, пачему неудобно?

Вот возьмём мою задачу. Мне надо разместить гуй на экране замоделенного монитора. Не удобно руками подгонять родительский плейн (пусть это будет главное окно) к экрану. В моей версии гуя ничего такого делать не надо — назначил экрану материал, и всё.

gnoblin писал(а):> 2. Сильный батхёрт при реализации работы с текстом. Легко выливающийся в увеличение количества дро коллов.
Батхерт если только потому что надо писать велосипед ).

В смысле? А как можно вывести текст на плашке без «велосипеда»? Какое есть готовое решение?

gnoblin писал(а):> 3. То же самое, но уже при обработке ввода.
> Как, например, быстро отловить движение мышки над плашкой, если плашка произвольно расположена и произвольно же ориентирована в пространстве? Не, я понимаю, что надо сначала проверить расстояние между плашкой и
> игроком, потом координаты крысы перегнать в локальную систему координат плашки, спроецировать точку (где как бы находится крыса) на плашку, и дальше уже всё не так сложно, но это же лишние расчёты.
OnMouseOver и коллайдер?

Так тут всё равно придётся часть тех расчётов делать, которые я указал. Коллайдер только с расстоянием может помочь, и всё.

Tolking писал(а):Главное приемущество квадов/плашек нет необходимости перерисовывать весь интерфейс при изменении состояния одного контрола.

Ну, это и без плашек можно сделать, если заморочиться. Только, думаю, не стоит, выигрыш мизерный.

Tolking писал(а):Нужен "работающий" компьютер в игре? Сделал объект интеракитвный, кликнул понему "развернул" экран игрушечного монитора на настоящий и работай в 2Д.

Отличный вариант. Но тут есть нюанс: игра на время работы аватары игрока на компьютере должна «замирать». Иначе будет странно, если тот вдруг помрёт во время сеанса игры на виртуальном ноутбуке. Подкрадётся, например, к нему кто-нибудь и даст по голове, а игрок так до самого геймовера и не поймёт ничего.

Фишка в том, чтобы иметь перед глазами экран, и чтобы часть сцены при этом была видна, чтобы можно было головой вертеть и постоянно мониторить ситуацию вокруг. Чтобы ситуацию нагнетать всё время. Мне саспенс нужен, а при «разворачивании» виртуального монитора на реальный игрок будет переключаться и отдыхать, и впечатление сгладится.
Akai
UNец
 
Сообщения: 29
Зарегистрирован: 11 сен 2010, 08:26
Откуда: Вельск

Re: Аспекты реализации собственного GUI

Сообщение gnoblin 29 окт 2010, 16:50

> Так тут всё равно придётся часть тех расчётов делать, которые я указал. Коллайдер только с расстоянием может помочь, и всё

Вот тут я совсем не понял
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Аспекты реализации собственного GUI

Сообщение Akai 29 окт 2010, 19:55

gnoblin писал(а):Вот тут я совсем не понял

А, не бери в голову, это я туплю.

С помощью коллайдера и OnMouseOver мы можем узнать, что крыса на плашке. Маловато для того, чтобы определить, стоит она или она побежала. Придётся запоминать, где она в прошлый кадр была. Или нет?
Akai
UNец
 
Сообщения: 29
Зарегистрирован: 11 сен 2010, 08:26
Откуда: Вельск

Re: Аспекты реализации собственного GUI

Сообщение Pyx 29 окт 2010, 20:08

Akai писал(а):
gnoblin писал(а):Вот тут я совсем не понял

Придётся запоминать, где она в прошлый кадр была. Или нет?

Нет.
Pyx
 

Re: Аспекты реализации собственного GUI

Сообщение gnoblin 29 окт 2010, 23:57

Да, можно запомнить ).

+ еще есть OnMouseEnter()/OnMouseExit()
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

След.

Вернуться в Скрипты

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

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