Unityを触り始めた頃は、つい何でもかんでも Update() に書いてしまいがちですよね。移動処理、アニメーション、入力、UI更新…全部ひとつのスクリプトに押し込んでしまうと、だんだん「どこを直せばいいのか分からない巨大スクリプト(Godクラス)」になってしまいます。
とくに「入力まわり」は膨らみやすいポイントです。「前進」「ダッシュ」「ジャンプ」「オートラン」などを1つのスクリプトで管理し続けると、条件分岐だらけでカオスになっていきます。
そこでこの記事では、「オートラン(一定のキーで前進入力を入れっぱなしにする)」だけに責務を絞ったコンポーネント 「AutoRun」 を作ってみましょう。
プレイヤーの移動ロジックとは分離し、「前進入力をどう扱うか」だけを担当させることで、コンポーネント指向らしいスッキリした設計にしていきます。
【Unity】ワンキーで前進固定!「AutoRun」コンポーネント
今回の AutoRun は、
- 特定のキーを押すと「前進入力ON / OFF」をトグル切り替え
- 通常の前進入力(Wキーなど)も併用可能
- 「現在の前進入力値」をほかのコンポーネントから参照できる
というシンプルな役割だけを持つコンポーネントです。
あくまで「前進の入力値」を提供するだけにして、実際の Rigidbody 移動などは別コンポーネントに任せる設計にします。
フルコード:AutoRun.cs
using UnityEngine;
/// <summary>
/// 前進入力を「オートラン」できるようにするコンポーネント。
/// - 特定キーでオートランON/OFFをトグル切り替え
/// - 通常の前進入力(Wキーなど)も上乗せ可能
/// - 「最終的な前進入力値」を他コンポーネントが利用できるように公開
///
/// 想定用途:
/// - 一人称/三人称のキャラクターコントローラーの前進入力ソース
/// - ランゲームでの自動前進ON/OFF
/// </summary>
public class AutoRun : MonoBehaviour
{
// --- 設定項目 ---
[Header("オートランのトグル設定")]
[SerializeField]
[Tooltip("オートランのON/OFFを切り替えるキー")]
private KeyCode toggleKey = KeyCode.R;
[SerializeField]
[Tooltip("ゲーム開始時にオートランを有効にするかどうか")]
private bool startWithAutoRun = false;
[Header("前進入力の設定")]
[SerializeField]
[Tooltip("通常の前進入力に使うキー(例: Wキー)")]
private KeyCode forwardKey = KeyCode.W;
[SerializeField]
[Tooltip("オートラン時の前進入力の強さ(1.0でフル入力)")]
private float autoRunForwardValue = 1.0f;
[SerializeField]
[Tooltip("通常のキー入力時の前進入力の強さ(1.0でフル入力)")]
private float normalForwardValue = 1.0f;
[Header("入力合成の設定")]
[SerializeField]
[Tooltip("オートランと通常の前進入力を合成する方法\n" +
"Add: オートラン + キー入力を足し合わせる\n" +
"OverrideWhenKey: キー入力があるときはそれを優先する")]
private CombineMode combineMode = CombineMode.Add;
/// <summary>
/// オートランと通常入力の合成モード
/// </summary>
private enum CombineMode
{
Add,
OverrideWhenKey
}
// --- 内部状態 ---
/// <summary>現在オートランが有効かどうか</summary>
public bool IsAutoRunning => _isAutoRunning;
/// <summary>
/// 現在の「前進入力値」
/// -1.0 ~ 1.0 の範囲で返す想定
/// (今回は前進のみなので 0 ~ 1.0 が主な値)
/// </summary>
public float CurrentForwardInput => _currentForwardInput;
// 実際のフラグと入力値
private bool _isAutoRunning = false;
private float _currentForwardInput = 0f;
private void Awake()
{
// 初期状態を設定
_isAutoRunning = startWithAutoRun;
}
private void Update()
{
UpdateToggle();
UpdateForwardInput();
}
/// <summary>
/// トグルキーが押されたかどうかをチェックし、
/// オートランのON/OFFを切り替える。
/// </summary>
private void UpdateToggle()
{
// KeyDown なので、1フレームだけ反応する
if (Input.GetKeyDown(toggleKey))
{
_isAutoRunning = !_isAutoRunning;
}
}
/// <summary>
/// オートラン状態と通常の前進キーから、
/// 最終的な前進入力値を計算する。
/// </summary>
private void UpdateForwardInput()
{
// オートランによる前進入力
float autoRunInput = _isAutoRunning ? autoRunForwardValue : 0f;
// 通常のキー入力による前進入力
bool isForwardKeyPressed = Input.GetKey(forwardKey);
float normalInput = isForwardKeyPressed ? normalForwardValue : 0f;
float result = 0f;
switch (combineMode)
{
case CombineMode.Add:
// オートランと通常入力を足し合わせる
result = autoRunInput + normalInput;
break;
case CombineMode.OverrideWhenKey:
// 通常キーが押されているときはそれを優先
result = isForwardKeyPressed ? normalInput : autoRunInput;
break;
}
// 念のため 0~1 にクランプしておく
_currentForwardInput = Mathf.Clamp01(result);
}
/// <summary>
/// オートラン状態を強制的にONにする(外部から呼び出し用)。
/// 例: カットシーン開始時に自動で前進させたい場合など。
/// </summary>
public void EnableAutoRun()
{
_isAutoRunning = true;
}
/// <summary>
/// オートラン状態を強制的にOFFにする(外部から呼び出し用)。
/// 例: メニューを開いたときに前進を止めたい場合など。
/// </summary>
public void DisableAutoRun()
{
_isAutoRunning = false;
}
/// <summary>
/// オートラン状態を反転させる(外部から呼び出し用)。
/// UIボタンなどから簡単にトグルしたい場合に使えます。
/// </summary>
public void ToggleAutoRun()
{
_isAutoRunning = !_isAutoRunning;
}
}
シンプルな移動コンポーネント例:AutoRunForwardMover.cs
AutoRun は「前進入力値」を提供するだけなので、実際にキャラクターを動かすためのコンポーネントをもう1つ用意しておくと便利です。
プレイヤーや敵など、前進方向を transform.forward にしたいオブジェクトにアタッチして使えます。
using UnityEngine;
/// <summary>
/// AutoRun から前進入力値を受け取り、Transform を前方に移動させるだけのコンポーネント。
/// 「移動ロジック」と「入力ロジック」を分けることで責務を小さくしています。
/// </summary>
[RequireComponent(typeof(AutoRun))]
public class AutoRunForwardMover : MonoBehaviour
{
[SerializeField]
[Tooltip("1.0 の入力時に何 m/s で移動するか")]
private float moveSpeed = 5f;
private AutoRun _autoRun;
private void Awake()
{
// 同じGameObject上の AutoRun を必ず取得
_autoRun = GetComponent<AutoRun>();
}
private void Update()
{
// AutoRun が計算した前進入力値を取得
float input = _autoRun.CurrentForwardInput;
// 入力値に応じて前方に移動
Vector3 move = transform.forward * (input * moveSpeed * Time.deltaTime);
transform.position += move;
}
}
使い方の手順
-
スクリプトをプロジェクトに追加
- 任意のフォルダ(例:
Scripts/Movement)にAutoRun.csとAutoRunForwardMover.csを作成し、上記コードをコピペします。
- 任意のフォルダ(例:
-
プレイヤー(または前進させたいオブジェクト)にアタッチ
- シーン内のプレイヤーオブジェクト(例:
Player)を選択。 Add ComponentボタンからAutoRunを追加。- 同じく
AutoRunForwardMoverも追加します。
RequireComponentによってAutoRunは自動で補完されますが、順番に追加しておくと分かりやすいです。
- シーン内のプレイヤーオブジェクト(例:
-
インスペクターでキー設定を調整
Toggle Key:オートランをON/OFFするキー(デフォルトはR)。Start With Auto Run:ゲーム開始時からオートラン有効にしたい場合はチェック。Forward Key:通常の前進キー(デフォルトはW)。Combine Mode:Add:オートラン + Wキー入力を足し合わせて前進力を増やす。OverrideWhenKey:Wキーを押している間はそちらを優先。
Auto Run Forward Value / Normal Forward Value:それぞれの入力の強さ(通常は 1.0 のままでOK)。Auto Run Forward MoverのMove Speed:キャラクターの移動速度(例: 5~10 くらい)。
-
実行して挙動を確認
例として、プレイヤーキャラクターでの使用例を挙げます。- ゲームを再生すると、Wキーで前進、キーを離すと停止。
- Rキー(トグルキー)を押すとオートランONになり、キーを離しても前進し続けます。
- もう一度Rキーを押すとオートランOFFになり、停止します。
Combine Mode = Addにしている場合は、- オートランONの状態でさらにWキーを押すと、前進スピードが増加します(ランゲームのダッシュ的な挙動)。
他の具体例:
- 敵キャラクターの巡回:敵に
AutoRun+AutoRunForwardMoverを付けておき、
一定距離進んだらtransform.Rotate(0, 180, 0)するスクリプトと組み合わせると、
シンプルな往復移動AIが作れます。 - 動く床:床オブジェクトに
AutoRun+AutoRunForwardMoverを付けておくと、
ステージ上を一定方向に流れるベルトコンベアのようなギミックを簡単に作れます。
メリットと応用
AutoRun コンポーネントのメリットは、
- 入力ロジックが分離される:移動スクリプトから「どのキーでオートランするか」「トグルの状態管理」などを切り離せる。
- プレハブが再利用しやすい:プレイヤー、敵、動く床など、前進するオブジェクトに同じ
AutoRunをポン付けできる。 - レベルデザインが楽になる:動くギミックを作るとき、「とりあえず前進し続ける」挙動を統一コンポーネントで持てるので、
ステージ上に複数配置しても設定が一貫しやすい。 - 保守性が高い:オートランの仕様を変えたいときは
AutoRunだけを修正すればよく、
移動系スクリプトをいじらずに済む。
例えば、ランゲームのように「常に前に走り続けるけど、一時停止ボタンで止めたい」という仕様が出た場合、
ポーズメニューのスクリプトから AutoRun.DisableAutoRun() を呼ぶだけで制御できます。
入力と移動が分かれているおかげで、仕様変更に強い構造になります。
改造案:一定時間だけオートランを有効にする
「スイッチを踏んだら、数秒だけ自動で前進させたい」といったギミックを作る場合、
AutoRun にコルーチンを1つ追加するだけで対応できます。
using System.Collections;
using UnityEngine;
// AutoRun クラスの中に追記する例
public void EnableAutoRunForSeconds(float duration)
{
// すでに実行中のコルーチンがあれば止めてもよい
StopAllCoroutines();
StartCoroutine(AutoRunTimerCoroutine(duration));
}
private IEnumerator AutoRunTimerCoroutine(float duration)
{
EnableAutoRun();
yield return new WaitForSeconds(duration);
DisableAutoRun();
}
これを使えば、トリガーゾーンに入ったときに EnableAutoRunForSeconds(3f); を呼び出すだけで、
「3秒間だけ強制的に前進させる」ような仕掛けを簡単に作れます。
このように、小さな責務のコンポーネントを組み合わせていくと、
巨大な Update() に全てを書き込むスタイルから卒業しやすくなります。
ぜひ自分のプロジェクト用に、入力系コンポーネントを分割していってみてください。
