Jump to content

Как можно сохранить и воспроизвести нажатые клавиши ?


photo

Recommended Posts

Posted

Здравствуйте, как можно сохранить, а потом воспроизвести нажатые клавиши клавиатуры и мыши в приложении ?
Заранее спасибо.

Posted

Здравствуйте.

Чтобы получить все события нажатий клавиатуры и мыши можно добавить коллбэк в Input. Я бы советовал использовать CALLBACK_IMMEDIATE_INPUT, чтобы получать события также, как и движок без всякой обработки. В этот коллбэк будет приходить объект InputEvent, из которого можно получить всю необходимую информацию. В этом случае будут интересовать только события типа INPUT_EVENT_MOUSE_BUTTON и INPUT_EVENT_KEYBOARD. Сохраняем их параметры, а также кадр движка, когда получили событие. Для воспроизведения нужно использовать метод sendEvent. В нужный кадр создаем событие нужного типа и с сохраненными параметрами, а после отправляем в движок.

В статье про Input есть пример как эмулировать открытие консоли и ввод команды show_profiler 1. Можно для начала разобрать его. Возможно ещё будет полезен метод получения буфера событий, которые накопились за кадр.

Posted

Спасибо, просто мне казалось, что для этого уже есть встроенный механизм. На Unigine Open Air 2023 была лекция про оптимизацию и там затрагивался этот момент, но вот нюансов уже не помню )

Posted

@karpych11sendEvent не отрабатывает, сделал все по инструкции. 
 

int AppWorldLogic::update()
{
	int frame = Game::getFrame();
	if (frame == 100)
	{
		InputEventKeyboardPtr key = InputEventKeyboard::create();
		key->setAction(InputEventKeyboard::ACTION_DOWN);
		key->setKey(Input::KEY_BACK_QUOTE);
		Input::sendEvent(key);
	}
	return 1;
}

Можете подсказать в чем проблема ?

Posted

Попробуйте эмулировать полный цикл событий клавиши:

InputEventKeyboardPtr key_down = InputEventKeyboard::create();
key_down->setAction(InputEventKeyboard::ACTION_DOWN);
key_down->setKey(Input::KEY_BACK_QUOTE);

InputEventKeyboardPtr key_repeat = InputEventKeyboard::create();
key_repeat->setAction(InputEventKeyboard::ACTION_REPEAT);
key_repeat->setKey(Input::KEY_BACK_QUOTE);

InputEventKeyboardPtr key_up = InputEventKeyboard::create();
key_up->setAction(InputEventKeyboard::ACTION_UP);
key_up->setKey(Input::KEY_BACK_QUOTE);

Input::sendEvent(key_down);
Input::sendEvent(key_repeat);
Input::sendEvent(key_up);

Должно точно сработать.

  • Like 1
Posted

@karpych11 да, так работает. Пример с доков совсем не рабочий.
 

#include "AppWorldLogic.h"
#include <UnigineInput.h>

using namespace Unigine;

enum
{
	STATE_OPEN_CONSOLE = 0,
	STATE_TYPING_COMMAND,
	STATE_APPLY_COMMAND,
	STATE_FINISH,
};

int state = STATE_OPEN_CONSOLE;
const char* command = "show_profiler 1";

int AppWorldLogic::update()
{

	switch (state)
	{
	case STATE_OPEN_CONSOLE:
	{
		InputEventKeyboardPtr key = InputEventKeyboard::create();
		key->setAction(InputEventKeyboard::ACTION_DOWN);
		key->setKey(Input::KEY_BACK_QUOTE);
		Input::sendEvent(key);
		state = STATE_TYPING_COMMAND;
		break;
	}

	case STATE_TYPING_COMMAND:
	{
		int size = strlen(command);
		for (int i = 0; i < size; i++)
		{
			InputEventTextPtr text = InputEventText::create();
			text->setUnicode(command[i]);
			Input::sendEvent(text);
		}
		state = STATE_APPLY_COMMAND;
		break;
	}

	case STATE_APPLY_COMMAND:
	{
		InputEventKeyboardPtr key = InputEventKeyboard::create();
		key->setAction(InputEventKeyboard::ACTION_REPEAT);
		key->setKey(Input::KEY_ENTER);
		Input::sendEvent(key);
		state = STATE_FINISH;
		break;
	}

	default: break;
	}

	return 1;
}

 

Posted

Спасибо что сообщили. Поправим этот пример в ближайшее время.

Posted

@karpych11 Можете пожалуйста помочь еще с мышью ?
Воспроизвожу события мыши,  но камера на них не реагирует, GUI отзывается.

 

if (type == InputEvent::INPUT_EVENT_MOUSE_BUTTON)
{
  auto inputEventMouseButton = InputEventMouseButton::create();
  inputEventMouseButton->setAction((InputEventMouseButton::ACTION)actionKey);
  inputEventMouseButton->setButton((Input::MOUSE_BUTTON)key);
  inputEventMouseButton->setMousePosition(mousePosition);
  Input::setMousePosition(mousePosition);
  Input::sendEvent(inputEventMouseButton);
}
else if (type == InputEvent::INPUT_EVENT_MOUSE_MOTION)
{
  auto inputEventMouseMotion = InputEventMouseMotion::create();
  inputEventMouseMotion->setMousePosition(mousePosition);
  inputEventMouseMotion->setDelta(delta);
  Input::setMousePosition(mousePosition);
  Input::sendEvent(inputEventMouseMotion);
}

 

Posted

Если вы используете движковое управление камерой на основе ControlsApp, то проверьте значение MouseHandle. Оно должно быть MOUSE_HANDLE_GRAB или MOUSE_HANDLE_SOFT. При этом если используется MOUSE_HANDLE_GRAB, то управление камерой захватится только по клику вне виджетов. Для теста можно выставить ControlsApp::setMouseEnabled(true) в начале эмуляции, а после выключить. Если заработает, то нужно смотреть в эмуляцию первого клика мышки.

Posted

@karpych11 Был выключен параметр RawInput, я его включил и мышь камера начала принимать сигнал.
Спасибо.
 

ControlsApp::setMouseRawInput(true);

 

×
×
  • Create New...