Unityで武器のリロード&射撃を実装する方法:初心者向け徹底ガイド【改訂版】
自己紹介
はじめまして、ゲーム開発所RYURYUの「りゅうや」と申します。
ゲーム開発ランキング【1位】獲得実績
ココナラでの総販売200件超
GC甲子園2022や東京ゲームショウ2023などで出展経験あり
Unityを駆使した「ゲーム・VR・メタバース開発」や「オンライン教育サービス」を幅広く展開しています。Zennでも5日間でFPSを作る学習教材を執筆し、初心者向けの開発支援に力を入れています。
武器のリロード&射撃をシンプルに作るポイント
弾数管理:マガジン内の弾数と、リロード時に増える弾数をコントロール
サウンド再生:射撃音・リロード音などで没入感をアップ
コルーチン(IEnumerator):リロード時間などの待機処理をうまく表現
UI連動:残弾数を画面に表示して、プレイヤーに状況を伝える
これらを一度に考えると大変ですが、次に紹介するコード例をベースに、少しずつカスタマイズすれば自然と完成度を高められます。
事前準備:プロジェクト&GameObjectのセットアップ
新しいUnityプロジェクトを開き、必要なアセット(武器モデル・弾・サウンドなど)をインポート
Hierarchy で空のGameObjectを作成し、「Weapon」という名前を付ける
ここにスクリプトやサウンドなどを関連付けていきます
Weaponスクリプト:リロード&射撃の中核
「Weapon」GameObjectを選択し、Inspector から「Add Component」→「New Script」を選択し、以下のコードを貼り付けてください。
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class Weapon : MonoBehaviour
{
public int magazineCapacity = 10;
public int currentAmmoInMagazine;
public int totalAmmo;
public float reloadTime = 2f;
public float fireRate = 0.5f;
public GameObject bulletPrefab;
public Transform firePoint;
public AudioSource reloadSound;
public AudioSource fireSound;
public Text ammoText;
public int bulletsPerReload = 1;
private bool isReloading = false;
private float nextTimeToFire = 0f;
private void Start()
{
// 起動時にマガジンを満タンにする
currentAmmoInMagazine = magazineCapacity;
}
private void Update()
{
// UIに弾数を表示
ammoText.text = $"{currentAmmoInMagazine} / {totalAmmo}";
// Rキーでリロード
if (Input.GetKeyDown(KeyCode.R) && !isReloading)
{
StartCoroutine(Reload());
}
// マウス左クリックで射撃
if (Input.GetMouseButton(0) && Time.time >= nextTimeToFire && !isReloading && currentAmmoInMagazine > 0)
{
nextTimeToFire = Time.time + 1f / fireRate;
Shoot();
}
}
private void Shoot()
{
// 弾を1発消費
currentAmmoInMagazine--;
// 弾のプレファブを生成
Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
// 射撃音の再生
fireSound.Play();
}
private IEnumerator Reload()
{
isReloading = true;
int ammoNeeded = magazineCapacity - currentAmmoInMagazine;
int ammoToReload = Mathf.Min(ammoNeeded, totalAmmo, bulletsPerReload);
// 1リロードにつきbulletsPerReload発ずつ装填する(ショットガンなどにも応用可能)
while (ammoToReload > 0 && totalAmmo > 0)
{
// リロード音を再生
reloadSound.Play();
// 指定時間だけ待ってから装填する
yield return new WaitForSeconds(reloadTime);
// 実際に弾を補充
currentAmmoInMagazine += ammoToReload;
totalAmmo -= ammoToReload;
// 次のループに向けて再計算
ammoNeeded = magazineCapacity - currentAmmoInMagazine;
ammoToReload = Mathf.Min(ammoNeeded, totalAmmo, bulletsPerReload);
}
isReloading = false;
}
}
Inspectorで設定する主なプロパティ
magazineCapacity: マガジンの容量
totalAmmo: プレイヤーの所持弾数
reloadTime: リロードにかかる時間(秒)
fireRate: 射撃レート(1秒あたりの発射回数)
bulletPrefab: 発射される弾のプレファブ
firePoint: 弾が飛び出す位置
reloadSound & fireSound: リロード・射撃時の効果音
ammoText: 弾数を表示するUIテキスト
bulletsPerReload: 1回のリロードで装填する弾数
弾のプレファブを作成:Bulletスクリプト
Hierarchy で右クリック → 3D Object > Sphere
このSphereを弾とみなし、「Bullet」スクリプトを下記のように作成&アタッチ
using UnityEngine;
public class Bullet : MonoBehaviour
{
public float speed = 20f;
public float lifeTime = 3f;
void Start()
{
// lifeTime秒後に自動破棄
Destroy(gameObject, lifeTime);
}
void Update()
{
// 前方向へ移動させる
transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
}
作成したSphereを Project ウィンドウへドラッグ&ドロップしてプレファブ化
Weapon スクリプトの bulletPrefab に、このプレファブを設定
ゲームを実行してテスト
マウス左クリックで射撃し、弾が飛ぶか確認
弾数が0になったら射撃できなくなるか
Rキーでリロードし、弾数が回復するか
UIに弾数が表示されているか
射撃音・リロード音が正しく再生されるか
ここまでで、最低限のリロード&射撃システムが完成です。
Time.time
Time.time は、Unityエンジン起動後の「ゲーム内で経過した時間(秒)」を返すプロパティです。
if (Time.time >= nextTimeToFire)
{
// ...
}
このように、次に射撃可能になる時間 (nextTimeToFire) と比較することで、一定の射撃間隔を保つ(連射制限をかける)ことができます。例えば、fireRate を 2 にすれば、1秒間に2回まで発射できる計算になるわけです。
Instantiate
Instantiate は、シーン上にプレファブやオブジェクトを動的に生成するためのメソッドです。
Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
上記のように、生成したいオブジェクト(bulletPrefab)と生成先の位置・回転(firePoint.position / firePoint.rotation)を指定することで、弾丸をその場で複製して飛ばせます。
このメソッドを使うと、シーンで管理していないオブジェクトも任意のタイミングで複製できるため、弾丸・敵の追加・爆発エフェクトなど、様々な場面で活用されます。
IEnumerator & Coroutines(コルーチン)
コルーチンは、Unity特有の非同期処理スタイルを実現する仕組みです。
IEnumerator を返すメソッドを StartCoroutine() で呼ぶことで、処理を中断・再開しながら進行できます。
private IEnumerator Reload()
{
// リロード処理のフロー
yield return new WaitForSeconds(reloadTime);
// 指定時間が経過したら続きの処理を行う
}
本記事では、リロード時間を演出するためにコルーチンを使っています。通常のメソッドだと「待機時間を入れる」ことが難しいですが、コルーチンならyieldを挟むだけで、メインスレッドを止めずに待機処理を実装できるのが大きな利点です。
yield return new WaitForSeconds(float)
yield return new WaitForSeconds(○秒); は、コルーチンの中で指定秒数だけ処理を中断し、経過後に再開するための命令です。
リロードのように「一定時間後に弾数を回復する」処理や、短い演出を挟みたいケースで重宝します。
reloadSound.Play();
yield return new WaitForSeconds(reloadTime);
// 実際に弾数を補充
このように、中断→再開の流れをスクリプト上で自然に表現できるのが、コルーチンの最大の魅力です。
応用例:アニメーションや物理演算の追加
アニメーション
武器リロード時にアームやマガジンが動くアニメを入れると、よりリアルに物理挙動
弾に Rigidbody を付与し、衝突判定や重力を適用することで本格的なFPSを目指せますUI演出
弾数が少なくなったらアラートを表示する、リロード中はUIを点滅させるなど、演出強化
まとめ:各種機能を理解し、自由にカスタマイズを
Unityには、FPS開発に欠かせない多彩な機能が用意されています。
Time.time を使えば簡単に連射制限
Instantiate で弾丸やエフェクトを動的に生成
IEnumerator や yield return new WaitForSeconds() でスムーズな待機処理
まずは今回のサンプルを動かし、弾数管理やリロード演出を自分好みに調整してみてください。ゲームの手応えが大きく変わる部分なので、ぜひ試行錯誤を重ねながら、あなただけの武器システムを作り上げていきましょう!
この記事を読んで「もっと実践したい!」と感じたあなたへ
Unity開発を効率よく進めるためには、実践的スキルと仲間の交流が大切。
おすすめステップは下記3つ:
1. 有料教材「どこでもUnity教室」でゲーム制作を短期マスター
5日でシンプルFPS完成: 初心者でも要点を網羅
最新InputSystem, FPS実装まで: つまずきやすいポイント先回り解説
購入特典: Discord招待+サンプルプロジェクト
2. 無料コミュニティで疑問即解消&モチベUP
初心者~中級OK: 学習ペースに合わせた質問・情報共有
質問サポートが充実: 講師や仲間に即相談
切磋琢磨できるから挫折しにくい
3. ゲーム開発所RYURYUがトータルサポート
コナラ総販売200件超: 多様なUnity案件対応
VR/AR/AI含む先端技術にも精通
ゲームクリエイター甲子園/TGS出展実績多数
いいなと思ったら応援しよう!
![ゲーム開発所RYURYU](https://assets.st-note.com/production/uploads/images/128268055/profile_28b8810144b6d3f716f55694b5c66ccd.jpg?width=600&crop=1:1,smart)