🐕

inputsystemのInputEventTraceでリプレイ操作を可能にしよう

2021/12/28に公開

前置き

Unity upmでinput systemを使うと、replayが簡単にできるので、そのやり方をメモ.

設定

1. upm

まずはupmにinputsystemを登録

{
  "dependencies": {
    "com.unity.inputsystem": "1.2.0"
  }
}

2. PlayerInput

PlayerInput componentをAttachする.

player input

3. EventSystemにUIInputModuleを設定する

uGUIでの応答を見たかったので、EventSystemのInputModuleを置換する必要があった
Input System UI Input Moduleに変更.
(PlayerInputがある状態だと置換するボタンが出現するのでそれを押すといいかも)

eventsystem

4. replay用のコードを書く

こんな雑にこんな感じのコードを書いた.

public class SampleInputController : MonoBehaviour
{
    [SerializeField] private InputActionAsset actionAsset;
    private InputEventTrace recordTrace = null;
    private InputEventTrace replayTrace = null;

    private void Start()
    {
        recordTrace = null;
        replayTrace = null;
    }

    private void OnDestroy()
    {
        recordTrace?.Dispose();
        replayTrace?.Dispose();
        recordTrace = null;
        replayTrace = null;
    }

    [ContextMenu("StartTrace")]
    public void StartTrace()
    {
        Debug.Log("StartTrace");
        recordTrace = new InputEventTrace();
        recordTrace?.Enable();
    }

    [ContextMenu("StopTrace")]
    public void StopTrace()
    {
        Debug.Log("StopTrace");
        if (recordTrace == null) return;
        recordTrace?.Disable();
        recordTrace?.WriteTo("/tmp/trace.log");
        recordTrace?.Clear();
        recordTrace?.Dispose();
        recordTrace = null;
    }

    [ContextMenu("Replay")]
    public void Replay()
    {
        Debug.Log("Replay");
        replayTrace = new InputEventTrace();
        replayTrace.ReadFrom("/tmp/trace.log");
        var replayController = replayTrace.Replay()
            .WithAllDevicesMappedToNewInstances()
            .OnFinished(() => UnityEngine.Debug.Log("Finish"));
        replayController.Rewind();
        replayController.PlayAllEventsAccordingToTimestamps();
    }
}

実行結果

ボタンを交互に押している様子が、記録、再現できている..!

https://youtu.be/Ts--IM6bMp8

感想

既存のInput.GetMouse()...とかInput.touchとか使ってると移行がめんどいかも.
新規に作るプロジェクトならばinputsystemつかうとreplay容易にできるので恩恵ありそう...!

Discussion