Unityで「回転する銃口」から弾を発射する方法【2D / 3D対応】

概要

シューティングゲームやアクションゲームで「プレイヤーが向いている方向に弾を発射したい」という場面は非常に多くあります。

特に、銃が回転する場合(マウス方向を向く、敵を追尾するなど)は、発射方向を正しく計算する必要があります。

この記事では、銃口(muzzle)を子オブジェクトとして設置し、そこから弾を発射するという、最もシンプルで堅牢な方法を紹介します。


1. 構成イメージ

Gun (空オブジェクト)
 ├─ Model(銃の見た目)
 └─ Muzzle(銃口の位置と方向)
  • Gun … 回転の中心(プレイヤーに追従)
  • Muzzle … 銃口の先端位置。弾を発射する起点
  • Projectile(弾) … Rigidbody付きプレハブ

Muzzle は銃の子オブジェクトとして配置し、銃が回転すると一緒に向きが変わるようにします。


2. 3D版コード例:

GunController3D.cs

using UnityEngine;

public class GunController3D : MonoBehaviour
{
    [Header("References")]
    [SerializeField] Transform muzzle;            // 銃口
    [SerializeField] GameObject projectilePrefab; // 弾プレハブ(Rigidbody付き)

    [Header("Settings")]
    [SerializeField] float muzzleSpeed = 40f;     // 弾速

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
            Fire();
    }

    void Fire()
    {
        if (muzzle == null || projectilePrefab == null) return;

        // 弾生成(銃口位置・回転を継承)
        var proj = Instantiate(projectilePrefab, muzzle.position, muzzle.rotation);

        // Rigidbodyに初速を与える
        var rb = proj.GetComponent<Rigidbody>();
        if (rb != null)
        {
            rb.linearVelocity = muzzle.forward * muzzleSpeed; // 銃口の前方向へ
        }
    }
}

ポイント

  • muzzle.forward … 銃口の「前方向」を取得(Z軸)
  • 弾プレハブの「Z方向」が進行方向と一致している必要があります
  • 回転しても常に正しい方向に発射されます

3. 2D版コード例:

GunController2D.cs

using UnityEngine;

public class GunController2D : MonoBehaviour
{
    [SerializeField] Transform muzzle;            // 銃口
    [SerializeField] GameObject projectilePrefab; // 弾プレハブ(Rigidbody2D付き)
    [SerializeField] float muzzleSpeed = 10f;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
            Fire();
    }

    void Fire()
    {
        if (muzzle == null || projectilePrefab == null) return;

        var proj = Instantiate(projectilePrefab, muzzle.position, muzzle.rotation);

        var rb = proj.GetComponent<Rigidbody2D>();
        if (rb != null)
        {
            rb.linearVelocity = muzzle.right * muzzleSpeed; // muzzleの右方向
        }
    }
}

2Dの注意点

  • 通常、スプライトの右方向(X軸)が進行方向です。
  • muzzle.right を使うと「回転に追従した正しい向き」で弾が飛びます。
  • Unity 6 では rb.velocity の代わりに rb.linearVelocity が推奨です。

4. 弾(Projectile)のスクリプト

using UnityEngine;

public class Projectile : MonoBehaviour
{
    [SerializeField] float lifeTime = 5f;

    void Start()
    {
        Destroy(gameObject, lifeTime);
    }

    void OnCollisionEnter(Collision collision)
    {
        // 当たった瞬間に削除(またはエフェクト再生)
        Destroy(gameObject);
    }
}

改良ポイント

  • 当たり判定:OnTriggerEnter / OnCollisionEnter2D
  • パフォーマンス:ObjectPool による再利用
  • 視覚効果:MuzzleFlash やTrailRendererを追加

5. よくあるトラブルと対策

症状原因対処法
弾が変な方向に飛ぶ弾プレハブの軸とmuzzle.forward/rightが合っていないモデルのローカル軸を確認
発射位置がズレるMuzzleの位置が銃口の先端にないシーンビューで正確に配置
弾がすり抜ける高速移動によるトンネリングRigidbodyの Collision Detection を “Continuous” に設定
弾が遅い/止まるRigidbodyのDragや重力が影響Dragを0、重力をオフに設定

6. まとめ

  • 銃口(Muzzle)を銃の子オブジェクトにして、発射点を明示するのが定番
  • 発射時は Instantiate(projectilePrefab, muzzle.position, muzzle.rotation)
  • 向きは muzzle.forward(3D) / muzzle.right(2D)
  • Unity 6では linearVelocity を使用

この方法なら、銃が回転しても正確に「銃口の先から」弾を飛ばせます。

訪問数 3 回, 今日の訪問数 3回

Unity,Unity6

Posted by hidepon