📚

瞬間の打撃感デザイン記録 ―― ShaderとURPで作るダッシュアタックのリズム

に公開

✦ 前書き|シェーダーは分からないけど、「ここで手応えが必要」なタイミングは分かる

最初から、ただの飾りのエフェクトを作るつもりはありませんでした。
自分がやりたかったのは、プレイヤーが操作した瞬間、「今キャラが何をしているか」が直感的に伝わるようにすることです。

シェーダーを正式に学んだことはありません。URPも今回が初めての触りです。
自分のやり方は、ひたすら:

  • インスペクターで値の変化を見て、
  • アニメーションを1フレームずつ手動でキーフレームを打って、
  • 手元にあるツールを片っ端から試して、組み合わせていく、
  • そんな感じで作り上げました。

だから、ダッシュ攻撃の一連の流れも、「非典型的」だけど実用的な方法で実装しています。


前書き:これはただのヒットテストじゃなく、インタラクティブなリズムの実験

自分は昔から「動作のリズム」や「打撃感」に非常に敏感です。
格ゲーが得意だから、ではなく、「もしキャラが技を出すとき、画面に適切な間やフィードバック、空気感が生まれたら――単なるダメージ表示よりも、ずっとリアルに感じるんじゃないか?」とよく妄想していました。

そんな思いから、このプロトタイプを作り始めました。
「ゲームを完成させる」のが目的ではなく、打撃設計・スキルエフェクト・アニメーションの組み合わせ・フィードバック・画面演出を全部のせできる基本的なバトルシステムを構築することがゴール。その開発過程をここに記録します。


✦ 最初の過程:キャラクターが一瞬で消える角色瞬間消失

ダッシュ開始時、ただアニメーションを伸ばすだけじゃなく、キャラ自体を消したいと思いました。
Shader Graph で _Alpha という float パラメータを作って、Animator でその値を制御しています。


キャラが消えると、画面に思いがけない「間」が生まれ、次のアクションの予兆を感じさせます。
これは単にカッコいいエフェクトのためではなく、「本当に一瞬で避けた」ような錯覚――普段のリズムを崩し、プレイヤーに無意識の緊張感を与えるための工夫です。


✦ URPの魚眼:勢いを画面圧縮で表現

ダッシュが始まった瞬間、URPのポストプロセスVolumeで魚眼圧縮エフェクトを加え、画面中央が少し押し広げられる感じにしています。

これはビジュアルの小技ではなく、「空間を絞る」ことで「今から高速アクションに入る」という合図にしたかったのです。

静から動への起点となる演出です。

✦ 再出現+攻撃:一瞬で登場+カメラ急接近

ダッシュの終点は元の位置ではなく、敵の目の前です。

再登場の瞬間には、発光エッジ付きの別シェーダーを使い、光がパッと走る感じ&画面も軽く揺れます。

カメラについては、キャラに直接バインドするのではなく、スクリプトで常にキャラの位置を計算し、slerpで追従しています。
なので、キャラが一気に敵前にワープしても、カメラはハードカットせず、滑らかに目標位置へ寄っていき、「キャラの背後にぴったり付いてる」ような臨場感を出せました。

    Vector3 targetPosition = Vector3.Lerp(transform.position, targetTransform.position, delta / followSpeed);
    transform.position = targetPosition;

「「カメラをバインドせず、スクリプトでキャラ位置を逐次計算し、slerpで寄せている」

この手法自体が、カメラシステム全体の「計算式追従」設計に由来し、ダッシュの移動も自然にカメラが新しい位置へ寄っていく。
この副産物として「カメラがじわじわ追い付く」演出も生まれました。

✦ エンディング:全てを元に戻し、リズムを静かに締める

攻擊完後,全部 shader / volume 效果收返,角色站穩收招,畫面冇多餘動態。撃後は全てのシェーダー/ボリューム効果を戻し、キャラは構えを解いて静止。画面も余計な動きを一切入れません。

この「静」は技術的な話ではなく、リズムを落ち着かせるためのものです。
プレイヤーに「今、技が終わった。次は自分のターンだ」と分かってもらうための工夫です。

✦ 開発過程:実験と試行錯誤で作り上げる

全体の流れは Timeline や特別なVFXツールは一切使っていません。ただ:

  • AnimatorでMaterialのfloat値を操作、
  • 死亡エフェクトはシェーダーのdissolveでキャラを徐々に消す、
  • 全シェーダー状態は自作のMaterialコントローラーで一括管理、
  • 透明化、発光、dissolveは全てシェーダーの切替/値操作で実現。
//ノーマル状態
public Material[] PlayerNormalMaterialList;

//闘う状態
public Material[] PlayerAttackMaterialList

実装中にハードコーディングを避けるため、各状態ごとに個別のMaterialを使っています。
切り替えは1行ででき、後の修正も楽です。

//闘う時の変換
Player.materials = PlayerAttackMaterialList;

//闘う終わりの変換
Player.materials = PlayerNormalMaterialList;

このやり方で、シェーダーコードを書かずにMaterialの差し替えだけで攻撃アニメ同期のエフェクトも実現できました。

しっかりしたVFXパイプラインはなく、全て実験・観察・分解・組み立ての繰り返しです。

✦ 自分のエフェクトは「設計」じゃなく「操作体感の再現」

自分は「ビジュアルデザイン」をしているというより、「画面上で操作リズムを分解して見せている」感覚に近いです。

例えば:

  • 開始 → 消失(静止+圧縮)
  • 再登場 → 攻撃(出現+カメラ接近+エフェクト)
  • 終了 → リセット(静止画面)

全て、感覚で試して「これ、十分面白いか?分かりやすいか?」と何度も自問しながら作っています。

https://github.com/Kenji966/Rpg-Action-Character-Controller-Combat-System

✦ 結び:カッコよさじゃなく、「今キャラが何しているか」を明確に見せたい

このダッシュコンボは決して業界標準のVFXではありません。
でも一つ一つ自分でイメージして、手探りで積み上げてきたものです。

シェーダーは書けなくても、どうすれば「伝わる」かは分かる。
美術センスがなくても、画面の「区切り」を作るべきタイミングは分かる。
ツールのパッケージに頼らず、自分でリズムを一歩ずつ作り上げてきました。

もしあなたも初心者、一人開発者、シェーダーに詳しくなくても——
画面イメージと直感、想像力さえあれば、
自分なりの「打撃感」を必ず作り出せるはずです。

この内容はRPGバトルシステム開発記録の補足記事です。全体の流れや背景はメインポストをご覧ください:
私のRPGバトルシステム開発記録 ➞

この記事が参考になったら、いいね👍をお願いします!

Discussion