ひつまぶし

主にメモと雑記と小ネタ。勉強会のレポートとかも時々。

Unityの入力イベントをフックしたい(願望)

UIの自動テストという魅力的な言葉につられ、ホイホイ仕事を請け負ってしまったので調べながら、書きながらやっていきます。

Java

検証1

MotionEvent | Android Developers

MotionEventというのを使えばできそうな雰囲気。

   /**
    * 入力イベントの実行
    *
    */
    public static void Invoke(final int x, final int y) {
        // アクティビティの取得
        final Activity activity = UnityPlayer.currentActivity;

        final long downTime   = SystemClock.uptimeMillis();
        final long eventTime  = SystemClock.uptimeMillis() + 100;

        // 接触時のイベント発行
        MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0);

        // イベントを突っ込む
        activity.dispatchTouchEvent(event);

        // 離れた時のイベント発行
        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);

        // イベントを突っ込む
        activity.dispatchTouchEvent(event);
    }

ダメでした。 そもそもUnityPlayer.currentActivityで取得できるActivityのonTouchEventは見てない模様。 そりゃそうかーと思いつつ、もう少し調べてみる。

検証2

UnityPlayerNativeActivityのUnityPlayerで入力制御をしてる雰囲気なので、次はこのあたりを攻めてみます。

UnityPlayerNativeActivityを継承している場合

public class UnityPlayerNativeActivity extends NativeActivity
{
    protected UnityPlayer mUnityPlayer;

    //中略//
}

protectedで宣言されているUnityPlayerが触れるので、

public class InputEventEmitter extends UnityPlayerNativeActivity {
    // Unity側から呼べるようにstaticで。
    private static UnityPlayer mPlayer = null;

    @Override public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        // 参照を保持
        mPlayer = mUnityPlayer;
    }
    @Override protected void onDestroy ()
    {
        super.onDestroy();
        // 参照を破棄
        mPlayer = null;
    }
    /**
    * 入力イベントの実行
    *
    */
    public static void Invoke(final int x, final int y) {
        final long downTime   = SystemClock.uptimeMillis();
        final long eventTime  = SystemClock.uptimeMillis() + 100;

        // 接触時のイベント発行
        MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0);

        // イベントを突っ込む
        mUnityPlayer.dispatchTouchEvent(event);

        // 離れた時のイベント発行
        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);

        // イベントを突っ込む
        mUnityPlayer.dispatchTouchEvent(event);
    }
}

こんなことをしてみました。 ダメでした。

結論

アクティビティを継承する形での入力イベントの発生は難しそう。 iOS編はまた今度まとめて書きます。。。