Добавление поддержки мультисенсорного ввода в игры Unity* для Microsoft Windows* 7 и классического интерфейса Windows* 8

By Steve Hughes

Загрузка


Adding Multi-Touch Support to Unity* Games on Microsoft Windows* 7 and Windows* 8 Desktop [Eng., PDF 299.45 KB]
Check1.cs [ZIP 3.52 KB]
DLLMain.cpp [ZIP 8.21 KB]

Аннотация


В настоящее время Unity не обрабатывает сообщения касания в приложениях, работающих под управлением Windows 7 и классического интерфейса Windows 8. Мы предлагаем решение, с помощью которого разработчики могут получить доступ к доступным событиям мультисенсорного ввода в приложениях Unity, работающих под управлением Windows. Это решение выполнено в виде подключаемого модуля, использующего различные API-интерфейсы Windows для перехвата сообщений касания, отправляемых приложению. Мы обрабатываем информацию из этих сообщений касания, а затем создаем простой набор данных, доступ к которому возможен с помощью C# из сценария в приложении Unity.

1. Обработка сообщений касания в Windows

Процесс обработки сообщений касания хорошо задокументирован в сети MSDN и в других местах, но мы упомянем определенные моменты, имеющие отношение к обсуждаемому вопросу. WNDPROC активного окна получает сообщение WM_TOUCH, когда происходит событие касания. После получения сообщения приложение вызывает GetTouchInputInfo() для заполнения массива структур PTOUCHINPUT по одной для каждой точки касания на поверхности. Нижнее слово параметра wParam, переданного WNDPROC, содержит количество записей PTOUCHINPUT в массиве.

В этом случае нас особо интересует член dwID структур PTOUCHINPUT. Этот идентификатор связывает определенную запись PTOUCHINPUT с записями, предоставленными прежним вызовам GetTouchInputInfo(). Это обеспечивает временную продолжительность точки касания. Многие приложения пытаются найти предыдущую точку касания как можно ближе к новой точке и предполагают, что они совпадают. Это не всегда верно. Например, множество касаний могут приходиться близко друг от друга или пересекаться друг с другом на экране.

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

2. Использование подключаемых модулей в Unity

Подключаемые модули Unity компилируются в виде DLL-библиотек, механизм экспорта хорошо задокументирован. «Экспортированные функции» остаются такими же в подключаемых модулях Unity, какими они являются в любых других DLL-библиотеках. Подключаемый модуль может быть написан на любом языке, если компилятор способен создать выходной файл DLL, а экспортированные функции всегда можно вызвать из сценария C# в Unity.

Экспортированные функции можно вызвать напрямую из сценария C# после загрузки подключаемого модуля Unity. В C# для доступа к экспортированным функциям достаточно просто объявить их в сценарии C# как extern. Например, предположим, что экспортированная функция из DLL-библиотеки C++ с именем MyPlugin имеет следующий заголовок:

__declspec(dllexport) int __cdecl Init(int p);

Для доступа к ней из C# объявим ссылку типа extern на нее.

[dllimport (“MyPlugin”)] private static extern int Init(int p);

Затем вызовем функцию Init (int) в сценарии.

3. Реализация интерфейса касаний с помощью подключаемого модуля

Для успешного получения сообщений касания Windows, направленных для приложения Unity, нужно выполнить несколько действий. Сначала мы опишем действия, а затем завершим процесс с помощью комментариев в исходном коде.

Процедура настройки для подключаемого модуля включает присоединение обработчика с помощью SetWindowsHookEx() для получения сообщений WM_TOUCH для приложения Unity. Для этого требуются две вещи: дескриптор модуля DLL и идентификатор потока, создавшего окно Unity, имеющее фокус. Для получения идентификатора потока, создавшего окно Unity, нужно сначала найти его дескриптор. Запись DLLMain() в DLL покажет дескриптор модуля. Самый простой способ найти дескриптор окна Unity — передать имя окна Unity из C# в подключаемый модуль, а затем перечислить все окна рабочего стола в подключаемом модуле с помощью EnumDesktopWindows(), чтобы найти дескриптор. Когда окно будет найдено, можно получить его дескриптор. Имея дескриптор окна, вызовите GetWindowThreadProcessID() для получения идентификатора потока, необходимого для вызова SetWindowsHookEx().

В коде видно, что SetWindowsHookEx() вызывается дважды; установлено два обработчика: один присоединен к WH_GETMESSAGE, другой к WH_CALLWNDPROC. Дело в том, что сообщения WN_TOUCH прибывают в WNDPROC в Windows 7 не так, как в Windows 8. В Windows 7 сообщения публикуются в очередь. В Windows 8 они напрямую вставляются в WNDPROC. Не забудьте высвободить обработчики Windows по завершении работы, поскольку они являются ограниченным ресурсом в ОС.

AПо умолчанию приложения не поддерживают касания. Чтобы приложение Unity могло получать сообщения касаний, подключаемый модуль должен вызвать RegisterTouchWindow(), чтобы включить эти сообщения. Для этого вызова потребуется предварительно получить обработчик окон.

По завершении наши обратные вызовы будут вызываться всякий раз при отправке сообщений окну Unity. Остается всего лишь отслеживать сообщения касания, а остальные сообщения возвращать в Unity.

4. Обработка данных касания

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

Int GetTouchPointCount() возвращает целое число, представляющее количество контактных точек, активных в данный момент на экране.

Void GetTouchPoint(int ID, tTouchData Data) возвращает активную точку касания с идентификатором индекса из подключаемого модуля.

Как мы упомянули выше, для данных, предоставляемых вызовом метода GetTouchPoint(), требуется точность для поддержания временной согласованности при обработке точек касания в Unity. Подключаемый модуль поддерживает внутренний список активных точек и старается соблюдать идентификаторы, назначенные операционной системой Windows. Идентификаторы Windows не совпадают с идентификатором, предоставленным экспортированной функции GetTouchPoint(). Опросите структуру tTouchData для выяснения фактического идентификатора точки касания, чтобы поддерживать временную целостность между кадрами.

5. Заключение

Хотя движок Unity сам по себе не обрабатывает сообщения касания в приложениях для Windows 7 и классического интерфейса Windows 8, можно зарегистрировать окно Unity для получения касаний от подключаемого модуля. После регистрации окна определенные приемы предоставляют нам доступ к сообщениям касания в сценарии приложения Unity. Многие разработчики ценят Unity, поскольку это интуитивно понятное и гибкое средство, позволяющее быстро разрабатывать весьма привлекательные и мощные игры. Доступ к сенсорному вводу в Unity значительно расширит ваши возможности по созданию динамичных игр и приложений мультимедиа для современных сенсорных устройств под управлением Windows.

Ресурсы


 

Intel и эмблема Intel являются товарными знаками корпорации Intel в США и в других странах.
© Intel Corporation, 2013. Все права защищены.
*Прочие наименования и товарные знаки могут быть собственностью третьих лиц.

Для получения подробной информации о возможностях оптимизации компилятора обратитесь к нашему Уведомлению об оптимизации.