Back to list
Unreal Engineにおける入力替えとタッチ入力のシミュレーション
Simulated Touch With Input Swapping In Unreal Engine
Translated: 2026/3/7 8:30:58
Japanese Translation
問題 タッチとキーボードの互換性は Unreal Engine のデフォルトでとても簡単だ。一つ必要な関数は ActivateTouchInterface であり、PlayerController->ActivateTouchInterface (TouchInterface); コマンドを使えばよいだけである。もし我々のプロジェクトにピクセルストリーミングがオンされているならそれが問題となる。それは always 远隔コンピュータへとシフトし続けるのである. それを触れることが可能なシミュレートされた入力はそのシナリオ下で実装しなければならない. これはプロジェクト設定から使用すると我々の UI オブジェクトに"Use Mouse for Touch"という選択肢が存在するので簡単にやることができる。しかし、この選択をオンした場合にキーボードを切り替えて実行するとカメラコントロールエラーがある. 当時テスト中によく見つけた問題がありそれは DefaultInput テンプレートにまだ false が設定されているためだと我々はわかった. 我々の項目を改めて、SlateApplication に存在する FSlateApplication::SetGameIsFakingTouchEvents (シミュレータ用の入力としてマウスとキーボードを扱う)関数を使うことで、このエラーは解決される。 同じ画面で UI をビルドし始めると player_controller のメソッドと Widget blueprint にいくつかのコードが含まれる。 ゲームオブジェクト作成クラスに UI をビルドする構造体を導入する必要がある. すべてのゲームにおいてもこの機能を使っておくべきだろうが、PlayerController にまとめるが最適であり、そのための例題として Game Instance で使うことを選んだ。 以下のような関数を使用して手動で Touch モードやキーボードモードを切り替えることもできる.AMyPlayerController::ToggleTouchInput (PlayerController, TouchInterface); Implementation:AMyGameInstance::ToggleTouchInput(APlayerController* PlayerController, UTouchInterface* TouchInterface) { if (!isValid(PlayerController)) return; AMyPlayerController* MyPlayerController = Cast (PlayerController); } 基底となる関数の呼び出しを前にして、以下の関数を実行すると問題が解決されるとの我々は見た。 この関数には 2つの引数があり、1つ目にカスタムで作成した Boolean 型の変数が渡される。その値によって選択された UI も変わるので、それを利用することに同意するプレイヤーもいることから。 詳細: AMyPlayerController::ToggleTouchInput(PlayerController, TouchInterface) { UInputSettings* InputSittings = GetInputSettings(); if (!Input_settings) { return; } 基本的な変数の中には 'bUseMouseForTouch' も含まれる. 値だけを変えるとエラーメッセージが表示される。そこで、我々は以下のように 3つの関数からなるプロトコルを使ってそれを解決した。FSlateApplication::Get().SetGameIsFakingTouchEvents(); グローバルのフラグもその一部に含まれる. これらの変更を含む Config の保存とクリア機能を利用すれば、ピクセルストリームプロジェクト内で touch モードとデスクトップモードを作動させ続けることが可能になるのである。
Original Content
Problem So swapping keyboard with touch input is quite easy by default in unreal engine all you need is one function which is called ActivateTouchInterface. PlayerController->ActivateTouchInterface(TouchInterface); If you provide no touch interface it will switch your input from touch to mouse and keyboard, but our problem is that our project has pixel streaming enabled which means it always run on a remote PC. To support touch even in that scenario we have to simulate mouse as touch input, this can be done in project settings: Use Mouse for Touch You can find this setting in Engine→Input inside your project settings. With this option enabled there is now another issue at hand upon switching to keyboard at runtime will mess up your camera controls even if you turn this option off in Input Settings. We noticed this bug in our testing phase and found out that this maybe happening because of the DefaultInput Config is still set to false even if you change your bUseMouseForTouch inside the input settings. Upon manually writing in that DefaultInput Config still didn’t solve the issue because turns out the engine is still overwriting it. In order to fix this issue we came across a function inside SlateApplication there is function called: void FSlateApplication::SetGameIsFakingTouchEvents(const bool bIsFaking, FVector2D* CursorLocation) So in our function where we swap the inputs we call this function via getting the slate application and it fixed the issue. My UI gets added to viewport on begin play and it pops up 2 buttons which player needs to choose which input mode they want to use. Here is how the Widget blueprint looks like: Construct: Desktop Button: Mobile Button: UTouchInterface Create a new game instance class, honestly it might be better to move this function into player controller but I choose game instance for this example. UFUNCTION(BlueprintCallable, Category = "Input") void ToggleTouchInterface(APlayerController* PlayerController, UTouchInterface* TouchInterface); Implementation: void UMyGameInstance::ToggleTouchInterface(APlayerController* PlayerController, UTouchInterface* TouchInterface) { if (!IsValid(PlayerController)) { return; } AMyPlayerController* MyPlayerController = Cast(PlayerController); if (IsValid(MyPlayerController)) { return; } const bool bIsUsingTouch = IsValid(TouchInterface); MyPlayerController->ToggleTouchInput(bIsUsingTouch); PlayerController->ActivateTouchInterface(TouchInterface); } before calling the ActivateTouchInterface we run a custom function which we created in our player controller called: ToggleTouchInput this takes a Boolean as parameter which determines if we are using touch or not. void AMyPlayerController::ToggleTouchInput(bool IsUsingTouch) { UInputSettings* InputSettings = UInputSettings::GetInputSettings(); if (!InputSettings) { return; } InputSettings->bUseMouseForTouch = IsUsingTouch; InputSettings->SaveConfig(); FSlateApplication::Get().SetGameIsFakingTouchEvents(IsUsingTouch); GConfig->SetBool(TEXT("/Script/Engine.InputSettings"), TEXT("bAlwaysShowTouchInterface"), IsUsingTouch, FPaths::ProjectConfigDir() + "DefaultInput.ini"); GConfig->SetBool(TEXT("/Script/Engine.InputSettings"), TEXT("bUseMouseForTouch"), IsUsingTouch, FPaths::ProjectConfigDir() + "DefaultInput.ini"); GConfig->Flush(false, FPaths::ProjectConfigDir() + "DefaultInput.ini"); } Nothing fancy here at first all we are doing is getting and saving the input settings with our new input mode, after that we call the function from Slate application and update our touch mode there as well. Once that is finished for sake completion we save the Booleans in our Default input config as well. Hope this helps, it is quite common for Clients to demand both touch and desktop controls in pixel streaming projects, switching them isn’t as straight forward since you need to be using simulated touch from the get-go.