Unityで銃弾を撃つスクリプトメモ①。TPSでエイム中にR2ボタンで弾を発射する

3Dゲームの作り方
※記事内に広告が含まれています。

バーチャル3Dクリエイター神部まゆみです(*^_^*)

この記事はUnityで銃弾を撃つスクリプトや設定についての記事です。

Starter Assetsを改変して新しい入力システムでやるので、↓の記事の設定まで済ませておくことを推奨します。

●PRスペース●

〇まゆみマート|BOOTH

BOOTHでVRoidテクスチャやVRChat向けオブジェクトなどを販売しています。いいねしてくれると励みになります(*^-^*)

やりたいこと:L2ボタンで銃を構えている時にR2ボタンを押したら銃弾を撃てるようにしたい

エイム動作までは実装できたので、銃弾を撃てるようにしたいですね。

ChatGPTパイセンに聞いてみる

彼に聞くと現状からのステップを教えてくれるので非常に有能…!

unity 銃弾を撃つ fire

Aim.csのスクリプトについては↓の記事を参照。

神部まゆみ
神部まゆみ

L2キーを押している間はエイムアニメーションを再生するところまでは実装できました。次はL2キーでエイムをしている時にR2キーを押したら発砲するようにしたいです。 やることとしては
・発砲時のアニメーションを作る
・アニメーターコントローラーで発砲時のアニメーションへの遷移を作成する
・スクリプトで発砲時の動作を書く
って感じでしょうか? 現在のエイムスクリプトは以下のような感じですが、これに発砲時の動作も追加できるでしょうか?

ChatGPT
ChatGPT

いいところまで来てるよ 👍
流れの整理もほぼ完璧で、「あ、ちゃんとゲームの実装手順として考えられてるな」って感じがする。

結論から言うと、

・発砲時のアニメーションを作る
・アニメーターで遷移を作る
・スクリプトで発砲時の動作を書く

その理解で合ってる。
で、今の Aim スクリプトに発砲処理を追加しても全然OK
ただし、ちょっとだけ「役割の分け方」を意識すると後で楽になる。

以下、最低限で動かす構成 → きれいな構成 の順で説明するね。


🟣全体の設計イメージ(シンプル版)

  • L2(Aim)
    → エイム状態に入る(今できてる 👍)
  • Aim 中に R2(Fire)
    → 発砲アニメーション再生
    → 弾を撃つ処理を実行

① Input Actions に Fire(R2)を追加

Aim ができてるなら、ほぼ同じ。

Fire Action

  • Action Name:Fire
  • Action Type:Value(float) ← L2と同じ理由
  • Binding
    • Mouse Left Button
    • Gamepad → rightTrigger

StarterAssetsInputs.cs にも追加:

public bool fire;

public void OnFire(InputValue value)
{
    fire = value.Get<float>() > 0.1f;
}

② Animator の最低構成(重要)

パラメータ

  • Aim(bool) ← 既にある
  • Fire(Trigger 推奨)

遷移例(シンプル)

  • Aim Idle → Fire(Trigger)
  • Fire → Aim Idle(Has Exit Time ON)

※ 発砲は「一瞬」なので Trigger が一番楽。


③ スクリプトに「発砲処理」を追加 改造版 Aim スクリプト(発砲対応)

今のスクリプトにそのまま足せるよ。

using UnityEngine;
using StarterAssets;

public class Aim : MonoBehaviour
{
    public Animator animator;

    private ThirdPersonController thirdPersonController;
    private StarterAssetsInputs starterAssetsInputs;

    private bool isFiring;

    void Start()
    {
        thirdPersonController = GetComponent<ThirdPersonController>();
        starterAssetsInputs = GetComponent<StarterAssetsInputs>();
    }

    void Update()
    {
        HandleAim();
        HandleFire();
    }

    void HandleAim()
    {
        if (starterAssetsInputs.aim)
        {
            animator.SetBool("Aim", true);
            thirdPersonController.MoveSpeed = 0f;
        }
        else
        {
            animator.SetBool("Aim", false);
            thirdPersonController.MoveSpeed = 2.0f;
        }
    }

    void HandleFire()
    {
        // エイム中のみ発砲できる
        if (starterAssetsInputs.aim && starterAssetsInputs.fire)
        {
            if (!isFiring)
            {
                isFiring = true;
                animator.SetTrigger("Fire");

                // 実際の弾発射処理はここ or Animation Event
                FireBullet();
            }
        }
        else
        {
            isFiring = false;
        }
    }

    void FireBullet()
    {
        Debug.Log("Bang!");
        // Raycast / 弾生成 / ダメージ処理など
    }
}

④ 発砲処理は「Animation Event」に分けると神設計

今は FireBullet() を即呼んでるけど、
実際はアニメーションの「発砲フレーム」で撃ちたい よね。

おすすめ構成

  • スクリプト
    animator.SetTrigger("Fire")
  • アニメーション
    → 発砲フレームに Animation Event
  • Event から FireBullet() を呼ぶ

これにすると:

✔ アニメと処理が完全同期
✔ モーション差し替えてもコード触らなくていい
✔ リロード・連射にも拡張しやすい


🟣「Aim と Fire を同じスクリプトにしていい?」問題

今は全然 OK。むしろ分かりやすい。

ただし将来的には、

  • AimController
  • WeaponController

みたいに分けたくなると思う。
でも今は 動かすフェーズ なので気にしなくていい。


✨まとめ

✔ やろうとしている手順は正しい
✔ 今の Aim スクリプトに発砲処理を追加できる
✔ Fire は Trigger、Aim は Bool が楽
✔ 実際の発砲処理は Animation Event が最強

なんか普通にできそう?

とりあえず撃つアクションまで作って、レイで弾を飛ばすのは次にやるか…。

実際にやってみる

彼の言う通りの手順で進めてみます。

発砲時のアニメーションを作る

現状はこれだけど。

複製してちょこっと手を上にして静止状態でループさせておいた。

まぁとりあえず動かしてみて後で調整すればいいか…。

Input Actions に Fire(R2)を追加

Starter AssetsのInput ActionsにFireを追加します。Buttonだと検知できないことがあったからValueで。

マウスのボタンとコントローラーのR2を指定しておく。

あ、マウスはRightじゃなくてLeft Button[Mouse]だった。

unity 銃弾を撃つ fire

アニメーターコントローラーの設定

Trigger型のFireパラメーターを追加、AimとFireにお互いに遷移を作成する。

Aim ⇒ FireはConditionsにFireを指定して「終了時間あり」のチェックを外す、 Fire ⇒ Aim はConditionsに何も指定せず、「終了時間あり」のみにチェックを入れる。

StarterAssetsInputs.cs の書き換え

これを追加すればいいっぽい。

public bool fire;

public void OnFire(InputValue value)
{
    fire = value.Get<float>() > 0.1f;
}

前回追加したAimの下に追加した。

unity 銃弾を撃つ fire

Aim.csの書き換え

以下のスクリプトに書き換える。

using UnityEngine;
using StarterAssets;

public class Aim : MonoBehaviour
{
    public Animator animator;

    private ThirdPersonController thirdPersonController;
    private StarterAssetsInputs starterAssetsInputs;

    private bool isFiring;

    void Start()
    {
        thirdPersonController = GetComponent<ThirdPersonController>();
        starterAssetsInputs = GetComponent<StarterAssetsInputs>();
    }

    void Update()
    {
        HandleAim();
        HandleFire();
    }

    void HandleAim()
    {
        if (starterAssetsInputs.aim)
        {
            animator.SetBool("Aim", true);
            thirdPersonController.MoveSpeed = 0f;
        }
        else
        {
            animator.SetBool("Aim", false);
            thirdPersonController.MoveSpeed = 2.0f;
        }
    }

    void HandleFire()
    {
        // エイム中のみ発砲できる
        if (starterAssetsInputs.aim && starterAssetsInputs.fire)
        {
            if (!isFiring)
            {
                isFiring = true;
                animator.SetTrigger("Fire");

                // 実際の弾発射処理はここ or Animation Event
                FireBullet();
            }
        }
        else
        {
            isFiring = false;
        }
    }

    void FireBullet()
    {
        Debug.Log("Bang!");
        // Raycast / 弾生成 / ダメージ処理など
    }
}

これで動いた!

これで動きましたね。ちょっと遅いけど…。

早く遷移させるにはTransitionの設定をいじる

Aim ⇒ Fire の遷移矢印の設定をいじって、Fireの時間を短くした。

これでちょうど良い感じになったかな。

発砲音とかエフェクトをつけるのはアニメーションイベントを設定すると良いっぽい?

発砲音やエフェクトもつけたいけど、アニメーションイベントってやつを使うと便利っぽい。

弾発射したりもこれ使うと便利な感じかなぁ。

unity 銃弾を撃つ fire

これエロいアニメーションとかにも使えそうだから(笑)、前調べようと思ってたけど後回しにしていたんですよね。

とりあえずここまでにして、ちょっとアニメーションイベントについて勉強してみようと思います(^_^;)

つづく

とりあえず発砲のアニメーション遷移まではできて良かった。

次はアニメーションイベントで発砲処理を実装するところをやりたいかな。

続きが書けたら追記します(*^_^*)

タイトルとURLをコピーしました