Отправлено: Jeff Laflam (Intel), 12 июня 2015 г.
Загрузить Intel® Toolkit на сайте Unity* Asset Store
В этой статье приводятся советы, которые мы получили при работе с разработчиками игр. Первый совет касается отображения встроенных средств сенсорного управления Windows и наглядных средств обратной связи. Второй совет относится к определению типа установленного в системе ГП и режима, в котором работает аккумулятор устройства (если исходить из того, что устройство оборудовано аккумулятором). И наконец, мы описываем, как использовать встроенную экранную клавиатуру Windows* 8 в Unity*, а также как определять, отображается ли экранная клавиатура на экране. Здесь приводится информация, касающаяся лишь некоторых вопросов наших внешних партнеров. Такие вопросы нередко возникают при реализации поддержки игр на разных платформах, поэтому мы решили собрать эту информацию в общедоступную статью. Этот ресурс доступен на сайте Unity Asset Store по адресу http://u3d.as/content/intel/intel-toolkit.
Основной для этого проекта послужила статья Стива Хьюза Добавление поддержки мультисенсорного ввода в игры Unity* для Microsoft Windows* 7 и классического интерфейса Windows* 8и код, позволяющий добавить встроенные средства сенсорного ввода Windows 7/8 в Unity.
Сенсорное управление и наглядное отображение обратной связи
Используя код Хьюза в качестве отправной точки, мы добавили в него наглядные элементы, чтобы пользователи могли видеть данные и работать с ними. Для каждого пальца на экране отображается отдельный индикатор, указывающий, что эта точка касания записана.
Мы также добавили код, отключающий наглядную обратную связь, используемую в Windows по умолчанию для сенсорного управления. Например, если провести пальцем по экрану в Windows, вы, вероятно, заметите белый след, указывающий траекторию движения точки касания. Это удобная обратная связь, но для игры она может не подходить. Как же отключать такие вещи программным образом? Ниже приводится фрагмент вызова API Windows, который мы нашли и использовали.
//in win8 sdk header typedef enum tagFEEDBACK_TYPE { FEEDBACK_TOUCH_CONTACTVISUALIZATION = 1, FEEDBACK_PEN_BARRELVISUALIZATION = 2, FEEDBACK_PEN_TAP = 3, FEEDBACK_PEN_DOUBLETAP = 4, FEEDBACK_PEN_PRESSANDHOLD = 5, FEEDBACK_PEN_RIGHTTAP = 6, FEEDBACK_TOUCH_TAP = 7, FEEDBACK_TOUCH_DOUBLETAP = 8, FEEDBACK_TOUCH_PRESSANDHOLD = 9, FEEDBACK_TOUCH_RIGHTTAP = 10, FEEDBACK_GESTURE_PRESSANDTAP = 11, FEEDBACK_MAX = 0xFFFFFFFF } FEEDBACK_TYPE ; //check if win8 function exists //if so turn off the windows 8 touch feedback stuff typedef BOOL (*LPSETWINFEEDBACK)(HWND hwnd, FEEDBACK_TYPE feedback, DWORD dwFlags, UINT32 size, const VOID *configuration); HINSTANCE hDLL = NULL; LPSETWINFEEDBACK lpSetWinFeedBack; hDLL = LoadLibrary("User32.DLL"); lpSetWinFeedBack = (LPSETWINFEEDBACK)GetProcAddress((HMODULE)hDLL, "SetWindowFeedbackSetting"); if( lpSetWinFeedBack ) { setval = FALSE; if(lpSetWinFeedBack( g_hRemoteWnd, FEEDBACK_TOUCH_CONTACTVISUALIZATION, 0, sizeof(BOOL), (void*)&setval) == false) return -7; setval = FALSE; if(lpSetWinFeedBack( g_hRemoteWnd, FEEDBACK_TOUCH_TAP, 0, sizeof(BOOL), (void*)&setval) == false) return -7; setval = FALSE; if(lpSetWinFeedBack( g_hRemoteWnd, FEEDBACK_TOUCH_PRESSANDHOLD, 0, sizeof(BOOL), (void*)&setval) == false) return -7; setval = FALSE; if(lpSetWinFeedBack( g_hRemoteWnd, FEEDBACK_TOUCH_DOUBLETAP, 0, sizeof(BOOL), (void*)&setval) == false) return -7; setval = FALSE; if(lpSetWinFeedBack( g_hRemoteWnd, FEEDBACK_TOUCH_RIGHTTAP, 0, sizeof(BOOL), (void*)&setval) == false) return -7; setval = FALSE; if(lpSetWinFeedBack( g_hRemoteWnd, FEEDBACK_GESTURE_PRESSANDTAP, 0, sizeof(BOOL), (void*)&setval) == false) return -7; }
В принципе, нужно вызвать SetWindowFeedbackSetting, но требуется осторожность, поскольку, если не задать элементы в нужном порядке, возможны сбои в работе программы. В этом примере показан порядок, который мы использовали для правильного отключения всей наглядной обратной связи в приложении без каких-либо неполадок.
Определение типа ГП
Мы взяли один из опубликованных ранее образцов — GPU Detect, показывающий разработчикам, как определить тип ГП Intel®и получить нужную для игр информацию. Обычно эта информация используется для создания настроек производительности по умолчанию для различных моделей оборудования. Иногда только названия модели оборудования недостаточно для определения нужного уровня производительности. Например, если в двух системах используется одна и та же модель какого-либо компонента, но с разными ограничениями по выделяемой тепловой мощности, производительность между такими устройствами может значительно различаться. В нашем примере с определением типа ГП предоставляется механизм, позволяющий получить подробную информацию, в том числе и о выделяемом тепле, поэтому можно очень точно настраивать параметры для различных платформ. Вот последняя версия образца GPU Detect.
Здесь мы получаем данные из образца и отображаем их в элементах пользовательского интерфейса в Unity.
Данные аккумулятора и ограничение кадровой скорости
Мы не только выявляем полезную информацию, но и получаем определенные метрики мобильности системы и отображаем их в Unity с помощью элементов пользовательского интерфейса. Метрики мобильности включают информацию о времени работы от аккумулятора и о режимах работы. Эту информацию можно использовать для ограничения кадровой скорости, к примеру до 30 кадров в секунду, если пользователь отключает устройство от электросети. Ограничение кадровой скорости, если обычно она выше, поможет увеличить время работы устройства от аккумулятора. Чтобы ограничить кадровую скорость 30 кадрами в секунду, можно добавить следующий код в сценарий Unity.
Application.targetFramerate = 30; QualitySettings.vSyncCount = 2;
Использование экранной клавиатуры Windows с Unity
Написание собственной экранной клавиатуры может быть непростой задачей, особенно если требуется локализация. При этом в нашем распоряжении уже есть экранная клавиатура, созданная корпорацией Microsoft, поэтому достаточно добиться ее правильного взаимодействия с движком Unity. Для использования этой экранной клавиатуры в Unity необходимо, чтобы окно Unity отображалось в оконном режиме без рамки. В полноэкранном режиме это будет невозможно. Можно запускать или отображать различные клавиатуры с помощью простого вызова функции, который предоставлен в образце (в .dll). Также нужен способ определения состояния экранной клавиатуры (она отображается в данный момент или скрыта?). В нашем примере есть вызов, позволяющий это сделать, но он закомментирован (см. ниже).
__declspec(dllexport) BOOL __cdecl IsVirtualKeyboardVisible() { BOOL bRet = FALSE; RECT InputPaneScreenLocation = { 0, 0, 0, 0 }; /* __try { HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); IFrameworkInputPane *IinputPane = NULL; if (SUCCEEDED(hr)) { // // http://msdn.microsoft.com/en-us/library/windows/desktop/hh706967(v=vs.85).aspx // hr = CoCreateInstance(__uuidof(FrameworkInputPane), 0, CLSCTX_ALL, __uuidof(IFrameworkInputPane), (LPVOID*)&IinputPane); IinputPane->Location(&InputPaneScreenLocation); if (InputPaneScreenLocation.bottom == 0 && InputPaneScreenLocation.left == 0 && InputPaneScreenLocation.right == 0 && InputPaneScreenLocation.top == 0) { // VKB is not visible bRet = FALSE; } else { // VKB is visible bRet = TRUE; } } } // try __finally { CoUninitialize(); } */ return bRet; }
Надеюсь, эти примеры кода вам пригодятся. Выберите нужные решения, наиболее подходящие для ваших проектов.
Об авторе
Джефф Лафлам (Jeff LaFlam) уже в течение 8 лет работает над оптимизацией компьютерных игр для оборудования Intel®. Он работал в сотрудничестве с несколькими разработчиками игр в США. Свободное время он предпочитает посвящать дизайну, творчеству и играм.
Пример исходного кода распространяется на условиях лицензионного соглашения корпорации Intel на использование образцов исходного кода.