Unityが非フォーカス/バックグラウンドでも入力を受け取るテクニック集

#はじめに
何かとUnityで非フォーカス/バッググラウンド(他のウインドウを選択している状態)で入力を受け取りたいというこということがあると思います(Vtuberのシステムとか)。しかし、**Unityはバックグランドの状態ではInputを扱うことができません。**

この記事ではUnityが非フォーカス状態でも入力を受け取るテクニックを書いていきます。
まず、前提として[Unityバックグラウンドでの処理 & 動作の検出](https://qiita.com/takish/items/36cf7b84189f12632606)を参考にUnityがUnityバックグラウンドでも処理が行われるようにしておきましょう。
![Inkedキャプチャ_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/140271/0fb0d684-16cb-05db-cee1-0acd6061dc51.jpeg)


#1. 動作環境
 - Windows10
 - Unity2017.4.12f1  
※OSに依存したライブラリが多く、Windows限定なものが多いです。

#2. キーボードの入力を受け取る
**[UnityrawInput](https://github.com/Elringus/UnityRawInput)パッケージを導入すると、バックグランド時でもキーボードの入力を受け取れるライブラリが使えるようになります。**なお、[Windows Raw Input API](https://docs.microsoft.com/ja-jp/windows/desktop/inputdev/raw-input)というWindowsのAPIを利用しているため、Windowsでしか使えません。

詳しい使い方はパッケージ配布ページにて説明されています。
また、[【Unity】バックグラウンド動作時のキー入力取得](https://qiita.com/neku/items/c6ffb5c5b83d0104efd8)でもサンプルプログラムとともに紹介されています。

#3. マウスの入力を受け取る
Inputだとバックグラウンドで入力を受け取れませんが、**[Event](https://docs.unity3d.com/ja/current/ScriptReference/Event.html)だとバックグラウンド状態でもマウスの入力を受け取ることができます。**

以下にサンプルプログラムを置いておきます。

```MouseBackgroundInput.cs
using UnityEngine;

public class MouseBackgroundInput : MonoBehaviour
{
    void OnGUI()
    {
        Event e = Event.current;
        //マウスのクリック
        if (e.button == 0 && e.isMouse)
        {
            Debug.Log("Left Click");
        }
        else if (e.button == 1)
        {
            Debug.Log("Right Click");
        }
        else if (e.button == 2)
        {
            Debug.Log("Middle Click");
        }
        else if (e.button > 2)
        {
            Debug.Log("Another button");
        }
        //マウスのポジション:Vector2
        Debug.Log("MousePos: " + e.mousePosition);
    }
}
```
#4. ゲームコントローラの入力を受け取る
XboxコントローラかつWindows限定ですが、[Unityでウィンドウが非フォーカスでもジョイパッドの入力を取得する方法](http://blog.vrai.jp/article/463326756.html)にて非フォーカス状態でもゲームコントローラの入力が受け取れるサンプルプロジェクトが配布されております。

また、上記のサンプルプロジェクトを拡張し、unitypackageとしてまとめたものも作成しました。prefabを配置するだけで、コントローラの入力を監視でき、VRMモデルを用いたサンプルもあるため使いやすいかと思います。
[XinputGamaPad](https://github.com/kaikikazu/XinputGamePad)

できるだけ詳しく使い方をREADME書いたつもりですが、もし分からない点や不具合などあればisuueを立てたり、直接私([@kaikofkaiki](https://twitter.com/kaikiofkaiki))にご報告してくださると幸いです。



#5. マイクの入力を受け取る
こちらに関しては**実はデフォルトからバックグラウンドでマイクの入力を受け取れます。(動作確認Windows)**
自分はOVRLipSyncを使っていて、バックグラウンド状態だと反応せず、「マイクの入力がバックグラウンドで取れていないのでは」と深読みして苦しんだのでここに記しておきます。

この項は**OVRLipSyncのバックグラウンド入力で苦しんだ人に向けて書きます。**
OVRLipsyncはUnityがバックグラウンド状態かどうかを監視し、バックグラウンド状態であればマイクを止める処理がなされております。その処理をコメントアウトしてしまうか、消してしまえば非フォーカス状態でも動いてくれるようになります。
`OVRLipSyncMicInput.cs`にある`StopMicrophone();`を全部消すかコメントアウトしてしまいましょう。
以下は全てではなく一部ですが、以下のようなコードがあるはずです。

```OVRLipSyncMicInput.cs
~~~中略~~~
if (!Application.isPlaying)
{
    //コメントアウト
    //StopMicrophone();
    return;
}
~~~中略~~~
if (!focused){
    //コメントアウト
    //StopMicrophone();
}
~~~中略~~~
```

#6. 参考
 - [Mouse入力　Event, OnMouse, Input](http://unitygeek.hatenablog.com/entry/2013/03/26/174605)
 - [Unityでウィンドウが非フォーカスでもジョイパッドの入力を取得する方法](http://blog.vrai.jp/article/463326756.html)
 - [【アーカイブ】VRMモデルをOVRLipSyncに対応させる方法](http://blog.vrai.jp/article/463326756.html)
 - [【Unity】バックグラウンド動作時のキー入力取得](https://qiita.com/neku/items/c6ffb5c5b83d0104efd8)