WinFormsのKeyDown/KeyUpからUnity Input Systemへ ― キー入力の考え方はどう変わる?
WinFormsでゲームを作るとき、私たちは「キーが押された」をイベントで受け取り、プレイヤーを動かしました。Unity 6のInput Systemでも、入力を受け取って動かす流れは変わりません。ただし、受け取るものが「キー」から「操作(Move)」に変わります。
この記事では、WinFormsで学んだことがUnityのどこにつながるのかを整理します。
この記事の位置づけ
学習の流れの中で、この記事は次の位置にあります。
- 落ち物キャッチゲーム:
KeyDownで直接動かす - キー長押し検知:入力状態を保存し、
Timer_Tickで動かす - この記事:この考え方がUnityにどうつながるかを整理する
- Unity 6でキー入力による移動を実装する:
MoveをUpdate()で読んで動かす
1. WinFormsでの2つの段階
段階1:KeyDownですぐ動かす
落ち物キャッチゲームでは、KeyDown の中で直接プレイヤーを動かしました(画面端のチェックは省略)。
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
int moveSpeed = 20;
if (e.KeyCode == Keys.Left)
pictureBoxPlayer.Left -= moveSpeed;
else if (e.KeyCode == Keys.Right)
pictureBoxPlayer.Left += moveSpeed;
}
キーが押された → KeyDown → その場で移動
分かりやすい反面、キーを押しっぱなしにすると、最初の1回のあとに間があき、その後に連続で KeyDown が発生します(キーリピート)。動きがぎこちなくなります。
段階2:押下状態を保存し、タイマーで動かす
キー長押し検知の記事では、この問題を次の構造で解決しました。
KeyDown / KeyUp → 押下状態を保存(isLeftPressed など)
Timer_Tick(約16ms)→ 状態を確認して移動
// KeyDown / KeyUp から呼ばれる
private void SetKeyState(Keys key, bool isPressed)
{
switch (key)
{
case Keys.Left: isLeftPressed = isPressed; break;
case Keys.Right: isRightPressed = isPressed; break;
}
}
// 約16msごとに呼ばれる
private void UpdatePaddlePosition()
{
if (isLeftPressed) paddleX -= PaddleSpeed;
if (isRightPressed) paddleX += PaddleSpeed;
}
(記事のコードから、画面端の制限と Invalidate() を省いた抜粋です。)
2. 実は、Unityへの橋はここにある
WinFormsでキー長押しに対応すると、構造はこうなります。
キーが押された/離された
↓
現在の入力状態を保存
↓
一定周期で状態を確認
↓
プレイヤーを移動
Unityでも、基本的な考え方は同じです。
キーやゲームパッド
↓
Move という入力状態
↓
Update() で現在の値を確認
↓
プレイヤーを移動
WinFormsで学んだ「入力」と「移動処理」を分ける考え方は、そのままUnityにつながっています。 この状態管理の考え方を理解していると、Unityの入力処理にもスムーズにつながります。
3. Unityで同じことをすると
Unity 6では、次の流れになります(詳しくはUnity 6でキー入力による移動を実装するを参照)。
WASD / 矢印キー / ゲームパッド
↓
InputSystem_Actions の Player / Move
↓
FindAction("Player/Move") で取得
↓
Update() で ReadValue<Vector2>()
↓
transform.position を変更
private void Update()
{
Vector2 moveInput = moveAction.ReadValue<Vector2>();
Vector3 move = new Vector3(moveInput.x, moveInput.y, 0);
transform.position += move * speed * Time.deltaTime;
}
4. 対応表
ここまでの対応を1枚の図にまとめると、次のようになります。

文字で整理すると、次の表になります。
| 考え方 | WinForms | Unity |
|---|---|---|
| 入力の受け取り | KeyDown / KeyUp | Input Actionの Move |
| 入力の中身 | Keys.Left など | Vector2 |
| 入力状態の扱い | isLeftPressed などに保存 | ReadValue<Vector2>() で現在値を取得 |
| 定期更新 | Timer_Tick | Update() |
| 移動 | 座標を一定量変更 | 方向 × speed × Time.deltaTime |
「一定のタイミングで、現在の入力状態を確認して移動する」という役割で見ると、WinFormsの Timer_Tick とUnityの Update() はよく似ています。ただし、Timer_Tick は指定した間隔で発生し、Update() は描画フレームごとに呼ばれる、という違いがあります。この違いは6章で扱います。
5. 違い① ― 「キー」ではなく「操作」を受け取る
WinFormsでは、プログラムが具体的なキーを判定します。
case Keys.Left: isLeftPressed = isPressed; break;
Unityでは、キーの種類は見ません。受け取るのは「Moveの値」です。
右 → ( 1, 0) 左 → (-1, 0)
上 → ( 0, 1) 下 → ( 0,-1)
「左キーが押された」ではなく、「Moveの値が (-1, 0) になった」と考えます。
6. 違い② ― 動かし方
WinFormsの例では、約16msごとに PaddleSpeed(5)ずつ動かしました。1回あたりの移動量が固定です。
Unityの Update() は、実行環境によって呼ばれる間隔が変わります。そこで経過時間 Time.deltaTime を掛けます。
移動量 = 方向 × speed × Time.deltaTime
これで「1秒あたり speed だけ動く」という考え方になり、フレームレートが違っても速さが揃います。
7. なぜ「操作」に分けるのか
WinFormsで、矢印キーに加えてA/Dキーでも動かしたくなったとします。
case Keys.Left:
case Keys.A:
isLeftPressed = isPressed;
break;
case Keys.Right:
case Keys.D:
isRightPressed = isPressed;
break;
キーが増えるたびにC#を書き換えます。ゲームパッドは標準のキーイベントにはなく、別の仕組みが必要です。
Unityでは、Moveに割り当て(Binding)を追加するだけで済みます。PlayerController は変更しません。
矢印キー ┐
WASD ├→ Move → PlayerController(そのまま)
左スティック ┘
これが、間にInput Actionを挟む理由です。
補足:コールバックで受け取る方法もあります
Unityには、入力が変化したときにメソッド(OnMove)が呼ばれる方法もあります。ただし本編では、WinFormsの「一定周期で状態を確認する」考え方から移行しやすい Update() + ReadValue<Vector2>() を使っています。コールバック方式は、本編の記事の折りたたみ部分で紹介しています。
8. まとめ
- WinFormsでは、直接動かす方法から、状態を保存して
Timer_Tickで動かす方法へ進んだ - Unityでも「入力状態を確認して
Update()で動かす」という考え方は同じ - 違いは、受け取るものが「具体的なキー」から「Moveという操作の値」になること
- 移動量は、固定値から
Time.deltaTimeを使った速度ベースへ変わる - 操作に分けることで、キーやゲームパッドを追加してもコードを変えずに済む
次は、実際にInput Systemで動かす記事に進みましょう。
→ Unity 6でキー入力による移動を実装する ― Input Systemの基本
発展:画面の外に出ないようにするには?
WinFormsの例では、Math.Max と Math.Min でパドルが画面外に出ないようにしていました。Unity本編では、まずInput Systemの理解に集中するため、この処理を入れていません。Unityではどのように移動範囲を制限すればよいでしょうか。余裕があれば考えてみてください。
確認問題
- WinFormsの
Timer_Tickと、UnityのUpdate()が似ている点は何ですか。違う点も1つ挙げてください。 Keys.LeftとMoveの違いを、「何を受け取るか」の観点で説明してください。- Moveにゲームパッドの左スティックを追加するとき、
PlayerControllerは変更が必要ですか。理由も答えてください。










ディスカッション
コメント一覧
まだ、コメントがありません