はじめに
Unityでアクションゲームを作っていると、
「キーを長押しして、離した瞬間にドン!と強い攻撃を出したい」
そんな操作を実装したくなること、ありますよね。
たとえばゼルダの伝説シリーズの回転斬りみたいな、
溜めて → 離して発動するチャージ攻撃です。
でも実際に作ろうとすると、
- Buttonコンポーネントだけでは長押し判定ができない
- Updateでゴリゴリ監視するとコードが複雑になる
- Input SystemのHoldを使ったけど、挙動がなんか違う…
こんな壁にぶつかりがちなんですよね。
そこでこの記事では、
Unityの新しいInput Systemを使って
「キーを押した瞬間」「押している間」「離した瞬間」をきれいに扱いながら、
チャージ攻撃を実装する方法を、順番に解説していきます。
ポイントは、
Updateに頼らず、イベント(started / canceled)で設計すること。
このやり方を覚えると、
チャージ攻撃だけじゃなく、溜めジャンプ・溜めショット・スキル詠唱など、
いろんな操作に応用できるようになりますよ 😊
初心者さんにも分かるように、
「なぜその設計になるのか?」という考え方から説明していくので、
安心して読み進めてくださいね。
Unity標準の入力処理ではなぜ実装しづらいのか
まず最初に、
「なんで普通に入力処理を書くだけじゃダメなの?」
というところから整理していきましょう。
ここを理解しておくと、
このあと紹介するInput Systemのイベント駆動設計が、
「あ、だからこうするんだ!」とスッと腑に落ちます。
Buttonコンポーネント・旧Input Managerの限界
UnityのUI Buttonや、旧Input Manager(Input.GetKey 系)は、
- 押した瞬間
- 押している間
- 離した瞬間
を自前で組み合わせて管理する必要があります。
たとえばよくある実装だと、こんな感じになりますよね。
- Updateで毎フレームキー入力を監視
- 押した瞬間にフラグON
- 押している間は時間を加算
- 離したらフラグを見て処理分岐
これ、最初は簡単そうに見えるんですが……
・フラグが増える
・状態が分かりにくくなる
・後から仕様変更しづらい
と、だんだんコードがつらくなっていきます 😢
Input SystemのHoldインタラクションがハマりやすい理由
「じゃあ新しいInput Systemなら解決するのでは?」
と思って、Holdインタラクションを使った人も多いはずです。
ただし、ここに落とし穴があります。
Input SystemのHoldは、
「一定時間押された瞬間にアクションが発動する」
という設計になっています。
つまり、
- チャージが完了した瞬間に発動する
- キーを離すタイミングは見ていない
という挙動なんですね。
今回作りたいのは、
「溜めて → 離した瞬間に攻撃」なので、
Hold単体では少し方向性がズレてしまいます。
Input Systemは「動かない」わけではない
ここで大事なのは、
「Input Systemが悪いわけではない」
「使いどころを間違えるとハマりやすい」
という点です。
実際、Input System自体の設定ミスや環境依存で、
「そもそも反応しない」というケースもよくあります。
もし、
- Input Systemが動かない
- イベントが呼ばれない
- 設定が合っているか不安
という場合は、先にこちらの記事をチェックしておくと安心です👇
土台がしっかりしていないと、
どんなに良い設計でも動かないですからね。
だから「イベント駆動」がベストな選択になる
ここまでをまとめると、
- Update監視はコードが膨らみやすい
- Holdは「離した瞬間」を扱えない
- 状態管理をシンプルにしたい
という理由から、
Input Systemの started / canceled イベントを使う設計が、
今回のチャージ攻撃にぴったりなんです。

次の章では、
いよいよ具体的にどう考えて実装するのかを、
設計の考え方から解説していきますよ 😊
【本編】Input Systemで「長押し+離した瞬間」を実装する考え方
ここからが、いよいよ本編です ✨
「どうやって実装するか」だけでなく、
「なぜこの設計にするのか」を意識しながら見ていきましょう。
基本方針は「started」と「canceled」を使う
Input Systemの一番の強みは、
入力の状態をイベントとして受け取れることです。
今回のチャージ攻撃では、次の2つがとても重要になります。
- started:キーを押した瞬間
- canceled:キーを離した瞬間
この2つを使えば、
- 押した瞬間 → チャージ開始
- 押している間 → 時間を溜める
- 離した瞬間 → チャージ量に応じて攻撃
という流れを、
Updateを使わずにとても自然に表現できます。
押下時間は「イベント間の差分」で考える
チャージ攻撃で必要なのは、
「どれくらい長く押していたか」ですよね。
考え方はシンプルで、
- started時に「開始時刻」を記録
- canceled時に「今の時刻 − 開始時刻」を計算
これだけです。
この方法のいいところは、
- フラグ管理が最小限
- 処理の流れが追いやすい
- 後から仕様変更しやすい
という点です。
「◯秒以上ならチャージ攻撃」
「最大チャージ時間は△秒まで」
といった調整も、数値を変えるだけで済みます。
callbackContext.duration を使う方法もある
実はInput Systemには、
入力がどれくらい維持されたかを教えてくれるcallbackContext.durationというプロパティもあります。
これを使えば、
自前で Time.time を記録しなくても、
押下時間を取得できます。
ただし、
- 状況によっては値が0になる
- 設定やインタラクション依存になりやすい
という点もあるので、
まずは started / canceled + 時刻差分の考え方を理解する
のがおすすめです。
Input Systemや時間管理を体系的に理解したい人へ
ここまで読んで、
- Input Systemの設計思想をちゃんと知りたい
- Time.time や時間管理を整理して学びたい
- 自己流から一段レベルアップしたい
と感じた人もいるかもしれません。
そんな人には、こちらの書籍がとても相性いいです👇
Unityゲーム プログラミング・バイブル 2nd Generation
✅ Amazonでチェックする | ✅ 楽天でチェックする
Input System・時間管理・設計の考え方が、
バラバラではなく一本の線として理解できるので、
今回のチャージ攻撃のような実装が、ぐっと楽になりますよ。

次の章では、
この考え方を使って、
「チャージ量に応じて攻撃を分岐させる方法」
を具体的に見ていきます。
チャージ量に応じて攻撃を分岐させる実装例
では次に、
計測したチャージ時間をどう使って攻撃を分岐させるのか
を見ていきましょう。
ここは「チャージ攻撃っぽさ」が一番出るところなので、
設計の考え方をしっかり押さえておくのがおすすめです。
基本の考え方は「しきい値」で分ける
チャージ攻撃の判定は、とてもシンプルです。
- 押下時間が短い → 通常攻撃
- 押下時間が長い → チャージ攻撃
たとえば、
- 1.0秒未満:通常攻撃
- 1.0秒以上:チャージ攻撃
といった感じですね。
この判定は、
キーを離した瞬間(canceled)に行うのがポイントです。
押している途中で判定してしまうと、
「溜めてる途中で技が出る」
という不自然な挙動になってしまいます。
最大チャージ時間を決めておくと安定する
もうひとつ大事なのが、
チャージ時間に上限を設けることです。
無制限に溜められると、
- 数値が想定外に大きくなる
- バランス調整がしづらい
- UIゲージとも噛み合わなくなる
といった問題が出やすくなります。
なので実装では、
- 最大チャージ時間を定数で決める
- 実際の押下時間は clamp して使う
という形にしておくと安心です。
Rigidbodyを使った「溜めに応じた威力」表現
物理挙動を使うゲームの場合は、
チャージ時間に応じて力を変えることで、
直感的な手応えを出せます。
たとえば、
- 短押し:弱い力で弾く
- 長押し:強い力で吹き飛ばす
といった感じです。
このときは、ForceMode.Impulseを使うのがおすすめです。
Impulseは「瞬間的な力」なので、
チャージ攻撃のドン!という感覚と相性がいいんですね。
時間管理を理解しておくと実装が安定する
ここまでの処理は、すべて
「時間」を正しく扱えていることが前提になります。
Time.time や Time.deltaTime の違いがあいまいなままだと、
- チャージ時間がズレる
- 環境によって挙動が変わる
- 後から修正しづらくなる
というトラブルにつながりがちです。
もし時間管理が不安な場合は、
先にこちらの記事を読んでおくと理解がかなり楽になります👇

次の章では、
キーボードではなく、UIボタンで長押しチャージを実装する方法
を解説していきます。
UIボタンで長押しチャージを実装する方法(EventTrigger)
ここまではキーボード入力を前提に解説してきましたが、
スマホゲームやタッチ操作では、
UIボタンの長押しでチャージしたい場面も多いですよね。
そんなときに便利なのが、
EventTriggerコンポーネントを使った方法です。
EventTriggerを使う理由
UI Button単体では、
- 押した瞬間(Pointer Down)
- 離した瞬間(Pointer Up)
を細かく制御するのが少し大変です。
EventTriggerを使えば、
- Pointer Down:押し始め
- Pointer Up:指を離した
- Pointer Exit:ボタン外に指がずれた
といったイベントを、
明示的に扱えるようになります。
実装の流れ(考え方)
考え方は、キーボード入力のときとほぼ同じです。
- Pointer Down:チャージ開始時刻を記録
- 押している間:必要ならUIゲージを更新
- Pointer Up:チャージ時間を計算して攻撃発動
ここで大事なのは、
「押下中かどうか」を示すフラグを持つことです。
フラグがないと、
Pointer Up や Exit だけが呼ばれたときに、
意図しない攻撃が出てしまうことがあります。
Pointer Exit を必ず処理する理由
スマホ操作で特に多いのが、
- ボタンを押したまま指がずれる
- そのまま画面外で離してしまう
というケースです。
このときに Pointer Exit を無視すると、
- チャージが解除されない
- 次の入力でおかしな挙動になる
といった不具合が起きやすくなります。
なので、
- Pointer Exit でもフラグをリセット
- チャージをキャンセル扱いにする
という処理を入れておくのが安全です。
マウス長押しの仕組みと合わせて理解する
UIボタンの長押しは、
マウス入力の長押しと考え方がとても近いです。
「まだちょっとイメージが湧かないかも…」
という場合は、こちらの記事も合わせて読むと理解が深まります👇

次の章では、
チャージ中であることをプレイヤーに伝えるための演出やUI
について解説していきます 😊
チャージ中の演出とUIフィードバック
チャージ攻撃は、
「今どれくらい溜まっているのか」が分からないと、
プレイヤーにとって少し不親切になりがちです。
そこでこの章では、
チャージ中であることを分かりやすく伝える演出やUI
について解説していきます。
円形ゲージでチャージ量を可視化する
一番分かりやすいのが、
円形(またはバー)ゲージによる表現です。
UnityのUI Imageコンポーネントを使えば、
比較的かんたんに実装できます。
- Image Type:Filled
- Fill Method:Radial 360(円形の場合)
- Fill Amount:0 ~ 1
あとは、
現在のチャージ時間 ÷ 最大チャージ時間
で求めた割合を、fillAmount に代入するだけです。
こうすることで、
- 押し始めるとゲージが溜まり始める
- 最大チャージで満タンになる
という、直感的なフィードバックが作れます。
チャージ完了を「演出」で伝える
ゲージだけでも十分ですが、
チャージが完了した瞬間を
演出で伝えてあげると、気持ちよさが一気に上がります。
たとえば、
- キャラクターが光る
- 効果音が鳴る
- オーラやパーティクルを出す
といった演出ですね。
このときに便利なのが、
Coroutineを使った処理です。
チャージ開始時にコルーチンを開始して、
一定時間経過したら演出を出す、という形にすると、
処理の流れがとても分かりやすくなります。
Updateを使わない設計が活きてくる
ここまでの実装を見て、
「あれ、Updateほとんど使ってないな」
と感じた人もいるかもしれません。
実はこれ、かなり大事なポイントです。
Updateに処理を詰め込みすぎると、
- どこで何が起きているか分かりにくい
- 不要な処理が毎フレーム走る
- パフォーマンスが落ちやすい
といった問題が出やすくなります。
イベント駆動+必要なところだけコルーチン、
という設計にしておくと、
見通しがよく、後から拡張しやすいコードになります。
この考え方については、
こちらの記事でさらに詳しく解説しています👇

次の章では、
実装時にハマりやすい注意点や、不具合を防ぐコツ
をまとめていきます。
注意点・よくある不具合と対策
最後に、
チャージ攻撃を実装するうえで
特にハマりやすいポイントをまとめておきます。
ここを押さえておくと、
「なんか挙動がおかしい…」
というトラブルをかなり減らせますよ。
押していないのに canceled が呼ばれるケース
Input Systemでは、状況によって
- 入力デバイスが切り替わった
- フォーカスが外れた
といったタイミングで、
canceledだけが呼ばれることがあります。
このときにそのまま攻撃処理を書いていると、
- 勝手に攻撃が出る
- チャージしていないのに発動する
といったバグにつながります。
対策としては、
- started で「押下中フラグ」を true
- canceled では必ずフラグを確認
という形にしておくのが安全です。
UI操作では「押下中フラグ」を必ず持つ
EventTriggerを使ったUI長押しでも、
考え方は同じです。
Pointer Up や Pointer Exit は、
- 押していなくても呼ばれる可能性がある
という点を忘れがちです。
なので、
- Pointer Down でフラグON
- Pointer Up / Exit ではフラグ確認 → リセット
という流れを必ず入れておきましょう。
チャージ中に別の入力を受け付けるかどうか
もうひとつ、設計として考えておきたいのが、
- チャージ中に移動できるか
- ジャンプや回避を許可するか
といった部分です。
ここを曖昧にすると、
- 入力が競合する
- 状態が壊れやすくなる
原因になります。
おすすめなのは、
「チャージ中」という状態を明確に定義する
ことです。
チャージ中フラグを元に、
- 移動処理を止める
- 別スキルを無効化する
といった制御をすると、
後から仕様を足すときも楽になります。
物理挙動は ForceMode を意識する
Rigidbodyを使った攻撃では、
ForceModeの選択も大切です。
チャージ攻撃のように、
- 一瞬で力を加えたい
場合は、
ForceMode.Impulse
を使いましょう。
ForceModeを意識していないと、
- 思ったより飛ばない
- フレームレートで挙動が変わる
といった違和感につながることがあります。

これらのポイントを押さえておけば、
チャージ攻撃はかなり安定して動くはずです 👍
まとめ
今回は、UnityのInput Systemを使って、
「キーを長押しして、離した瞬間に発動するチャージ攻撃」
を実装する考え方と手順を解説しました。
ポイントを振り返ると、こんな感じです。
- Updateで毎フレーム監視する設計は、複雑になりやすい
- Holdインタラクションは「離した瞬間」用途には向かない
- started / canceled イベントを使うと設計がシンプルになる
- 押下時間は「開始時刻と終了時刻の差分」で考える
- UIボタンでは EventTrigger+フラグ管理が安全
- チャージ中の演出やゲージ表示で、操作感が大きく向上する
特に大事なのは、
「いつ処理を走らせるか」を明確にすることです。
押した瞬間、押している間、離した瞬間。
この3つをイベントとして分けて考えるだけで、
コードは驚くほど読みやすく、壊れにくくなります。
チャージ攻撃は、
- 溜めジャンプ
- 溜めショット
- スキル詠唱
- 必殺技
など、いろいろなアクションに応用できます。
今回の考え方をベースに、
ぜひ自分のゲームに合った形へアレンジしてみてくださいね 😊
ここまで読んでくれて、ありがとうございました!
参考文献
- Unity Input Systemでチャージ攻撃を実装する方法(uhiyama-lab)
- Unityで長押し(ロングタップ)入力を判定する方法(coacoa)
- Unityでボタンを長押しする処理の実装方法(SOLE GAME CREATER)
- Charge Jump with the New Unity Input System(Medium)
- Unity公式ドキュメント:Input System Interactions
よくある質問(FAQ)
- QHoldインタラクションは使わない方がいいですか?
- A
使えないわけではありませんが、
「キーを離した瞬間に技を発動したい」場合には、
Holdインタラクション単体はあまり向いていません。Holdは「一定時間押された瞬間」にアクションが発火する仕組みなので、
チャージ完了と同時に技が出てしまいます。そのため、
- 溜めている最中は何も起こらない
- 離した瞬間にまとめて処理したい
という用途では、
started / canceled を使ったイベント駆動設計の方が、
挙動をコントロールしやすくおすすめです。
- Qチャージ時間は無制限にしても問題ありませんか?
- A
技術的には可能ですが、
あらかじめ最大チャージ時間を決めておく方が安全です。無制限にすると、
- 数値が想定以上に大きくなる
- バランス調整が難しくなる
- UIゲージとズレやすくなる
といった問題が起きやすくなります。
おすすめは、
- 最大チャージ時間を定数で定義
- 実際に使う値は clamp して制限
という設計です。
こうしておくと、
あとから数値調整するだけでゲーム性を変えられます。
- QPCとスマホで同じ設計を使えますか?
- A
はい、使えます。
考え方としては、
- キーボード・ゲームパッド:Input System(started / canceled)
- タッチ操作:EventTrigger(Pointer Down / Up)
と、
入力の取り方だけを切り替えるイメージです。「押した瞬間に開始」「離した瞬間に確定」という
チャージのロジック自体は共通なので、
内部処理をまとめておくと管理しやすくなります。将来的に、
- PC版とモバイル版を両方出したい
- 操作方法を後から増やしたい
といった場合でも、
今回の設計ならスムーズに対応できますよ。









※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。
※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。