UnityUnityメモ

Unityで弾の命中率を調整!ランダムな誤差を加える方法

Unity

はじめに

Unityを使ったゲーム開発では、弾を発射する際に「命中率」を調整することが重要なポイントになります。単純に弾をまっすぐ発射するだけでは、ゲームが簡単すぎたり、逆に単調になってしまうことがありますよね。

そこで今回は、弾にランダムな誤差を加えて、命中率を意図的に下げる方法を解説します。この技術を使うことで、例えば「敵に当たる確率をランダムにして緊張感を高める」や「プレイヤーのスキルに応じた命中精度を再現する」といった応用が可能になります。


1. 必要な3Dオブジェクトを作成する

Unityで弾にランダムな誤差を加える仕組みを作るために、まずは必要なオブジェクトや環境を整えていきます。以下の手順に沿って準備を進めてください!


地面(Plane)を作成

  1. ヒエラルキー(Hierarchy)ウィンドウを右クリックします。
  2. 「3D Object」→「Plane」を選択します。

弾(Sphere)を作成

  1. 同じくヒエラルキーウィンドウを右クリックし、「3D Object」→「Sphere」を選択します。
  2. Sphereの名前を「Bullet」などに変更します。
  3. プロジェクトウィンドウを右クリック、「Create」→「Material」を作成して赤い色を設定しましょう。(任意)
  4. インスペクターの「Add Component」ボタンをクリックして「Rigidbody」を選択します

目標物(Cube)を作成

  1. ヒエラルキーウィンドウを右クリックし、「3D Object」→「Cube」を選択します。
  2. CubeをPlaneの上に配置し、床の奥のほうに移動します(例:位置をX=0、Y=0.5、Z=4に設定)。
  3. プロジェクトウィンドウを右クリック、「Create」→「Material」を作成して青い色を設定しましょう。(任意)

発射位置を作成

  • ヒエラルキーウィンドウを右クリックして「Create Empty」を選択し、空のゲームオブジェクトを作成します。
  • Cubeの手前の直線上のあたりに配置します。(例:位置をX=0、Y=1、Z=-5に設定)。



2. プレハブを作成する

弾を動的に生成するために、Bulletをプレハブ化します。

  1. Bulletをプロジェクトウィンドウにドラッグ&ドロップ
    • ヒエラルキーウィンドウの「Bullet」をプロジェクトウィンドウにドラッグ&ドロップします。
  2. Bulletプレハブを確認
    • プレハブ化したBulletをクリックして、インスペクターで設定を確認します。



3. スクリプトの準備

次に、弾を発射するスクリプトを作成します。

  1. スクリプトを作成
    • プロジェクトウィンドウを右クリックし、「Create」→「C# Script」を選択します。
    • スクリプト名を「ShootingError」に変更します。
  2. スクリプトを空のゲームオブジェクトにアタッチ
    • 作成した「ShootingError」スクリプトを先ほど作成した空のオブジェクトにドラッグ&ドロップしてアタッチします。

スクリプトを入力

以下のコードは、弾を発射する際にランダムな誤差を加えるスクリプトです。

スクリプトを開いて以下のコードを入力します。


using UnityEngine;

public class ShootingError : MonoBehaviour
{
    public GameObject bulletPrefab; // 弾のプレハブ
    public Transform spawnPoint; // 弾の発射位置
    public float errorMargin = 5.0f; // 誤差の大きさ
    public float force = 10.0f; // 発射力

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            GameObject bullet = Instantiate(bulletPrefab, spawnPoint.position, spawnPoint.rotation);
            float errorX = Random.Range(-errorMargin, errorMargin);
            float errorY = Random.Range(-errorMargin, errorMargin);
            Vector3 errorDirection = Quaternion.Euler(errorY, errorX, 0) * spawnPoint.forward;
            Rigidbody bulletRigidbody = bullet.GetComponent<Rigidbody>();
            bulletRigidbody.AddForce(errorDirection * force, ForceMode.Impulse);
        }
    }
}

① 弾のプレハブと発射位置を指定

public GameObject bulletPrefab; // 弾のプレハブ
public Transform spawnPoint; // 弾の発射位置
  • bulletPrefab: 発射する弾をプレハブとして設定します。プレハブは、プロジェクトウィンドウに作成した弾のオブジェクトをドラッグ&ドロップして設定します。
  • spawnPoint: 弾の発射位置を表すTransform(位置と向き)を設定します。例えば、発射するオブジェクトの先端を指定すると良いでしょう。

② 誤差の大きさと発射力を設定

public float errorMargin = 5.0f; // 誤差の大きさ
public float force = 10.0f; // 発射力
  • errorMargin: 弾の進行方向にどれだけ誤差を加えるかを設定します。この値を大きくするほど、発射方向のばらつきが増えます。
  • force: 弾を発射する力の大きさを設定します。値を調整することで弾のスピードを変えることができます。

③ 弾を生成する

GameObject bullet = Instantiate(bulletPrefab, spawnPoint.position, spawnPoint.rotation);
  • Instantiate: 弾のプレハブをspawnPointの位置と回転を基準に生成します。
  • 生成された弾は、bulletという名前の変数に保存され、後続の処理で使用されます。

④ ランダムな誤差を計算する

float errorX = Random.Range(-errorMargin, errorMargin);
float errorY = Random.Range(-errorMargin, errorMargin);
Vector3 errorDirection = Quaternion.Euler(errorY, errorX, 0) * spawnPoint.forward;
  • Random.Range: –errorMarginからerrorMarginの間でランダムな値を生成します。
    • errorX: 水平方向(X軸)の誤差。
    • errorY: 垂直方向(Y軸)の誤差。
  • Quaternion.Euler: 誤差を回転として適用します。
  • spawnPoint.forward: オブジェクトの正面方向を基準に、誤差を加えた新しい方向(errorDirection)を計算します。

⑤ Rigidbodyで弾を発射する

Rigidbody bulletRigidbody = bullet.GetComponent<Rigidbody>();
bulletRigidbody.AddForce(errorDirection * force, ForceMode.Impulse);
  • GetComponent<Rigidbody>(): 弾に物理演算(Rigidbodyコンポーネント)がアタッチされているか確認し、取得します。
  • AddForce: errorDirectionに基づいて、弾に力を加えます。
    • forceが大きいほど、弾の速度が速くなります。
    • ForceMode.Impulse: 瞬間的に力を加えるモードを指定します。

動作の流れ

  1. マウスの左クリックを検知します。
  2. 弾のプレハブを指定した位置で生成します。
  3. ランダムな誤差を計算し、進行方向に加えます。
  4. Rigidbodyに力を加え、弾を発射します。



4.スクリプトをゲームオブジェクトにアタッチ

  1. プロジェクトウィンドウで作成した「ShootingError」スクリプトを、ヒエラルキーウィンドウの空のオブジェクトにドラッグ&ドロップします。
  2. スクリプトの「Bullet Prefab」フィールドに、先ほど作成した弾のプレハブをドラッグ&ドロップします。
  3. 「Spawn Point」フィールドには、作成した空のオブジェクトをドラッグ&ドロップします。



5. テストプレイ

では、スクリプトの設定が完了したら、いよいよ実行して動作を確認してみましょう!



よくある質問

Q
弾が動かないのですが?
A

弾のプレハブにRigidbodyが追加されているか確認してください。

Q
発射方向の誤差が思ったように変わらないのですが?
A

誤差の範囲(errorMargin)が小さい可能性があります。値を大きくして試してください。

Q
プレハブを作成する方法は?
A

作成したオブジェクトをプロジェクトウィンドウにドラッグ&ドロップすると簡単に作成できます