Menu
CoddyTech

武器のステータス

CoddyのUnityジャーニー「Unityのゲームアーキテクチャ」セクションの一部。レッスン 24/64。

剣もハンマーも、振って、待って、また振るという動作は同じです。違うのは数値です。剣は4のダメージを与え、0.5秒ごとに振ります。ハンマーは10のダメージを与え、1.5秒ごとに振ります。つまり、どちらにも同じWeaponスクリプトを使い、それぞれの武器の数値はアセットに保存します。

[CreateAssetMenu(menuName = "Combat/Weapon Data")]
public class WeaponData : ScriptableObject
{
    public string weaponName;
    public int damage;
    public float swingTime;
    public GameObject hitEffect;
}
public class Weapon : MonoBehaviour
{
    public WeaponData data;
    private float nextSwing;

    public void Swing(Health target)
    {
        if (Time.time < nextSwing) return;
        nextSwing = Time.time + data.swingTime;
        target.TakeDamage(data.damage);
        Instantiate(data.hitEffect, target.transform.position, Quaternion.identity);
    }
}

プロジェクトには、Swordアセット(4、0.5、火花のPrefab)とHammerアセット(10、1.5、土煙のPrefab)があります。騎士もオーガもWeaponスクリプトを持っています。騎士のdataフィールドにはSwordが、オーガのフィールドにはHammerが設定されています。Createメニューから作成するだけで、槍ももう1つのアセットとして追加できます。スクリプトを変更する必要はありません。アセットはhitEffectのようにPrefabやほかのアセットを参照できますが、シーン内のオブジェクトは参照できません。アセットはプロジェクト内にあり、どのシーンにも属さないためです。

武器ごとに数値を変える別の方法では、どちらも数値をコード内に記述します。if (weaponName == "Sword") damage = 4; else if ...は武器が増えるたびに膨らんでいきます。また、数値を設定するだけのWeaponのサブクラスSwordを作ると、アセットごとにクラスが必要になります。サブクラスを使うのは、矢を放つ弓のように、武器の動作が異なる場合です。より強いダメージを与える、またはより速く振るだけの武器なら、専用のアセットを用意すればよく、コードは必要ありません。

challenge icon

チャレンジ

中級

すべての銃が、GunDataアセットから数値を読み込むようにします。

  1. Gunにpublic GunData data;を追加します。
  2. data.bulletPrefabを発射し、各ショットの間にdata.fireIntervalだけ待ち、各弾丸にdata.damageを設定します。
  3. gunType、2つの弾丸フィールド、3つのプライベートコピー、そしてStart()を削除します。

「プレイ」を押してSpaceキーを押し続けます。ブラスターも発射されます。その後、「確認」を押します。

自分で試してみよう

using UnityEngine;
using UnityEngine.InputSystem;

public class Gun : MonoBehaviour
{
    public string gunType = "Pistol";
    public GameObject pistolBullet;
    public GameObject rifleBullet;
    private GameObject bulletPrefab;
    private float fireInterval;
    private int damage;
    private float nextShot;

    void Start()
    {
        if (gunType == "Pistol")
        {
            bulletPrefab = pistolBullet;
            fireInterval = 0.25f;
            damage = 1;
        }
        else if (gunType == "Rifle")
        {
            bulletPrefab = rifleBullet;
            fireInterval = 0.6f;
            damage = 4;
        }
    }

    void Update()
    {
        if (Keyboard.current.spaceKey.isPressed && Time.time >= nextShot)
        {
            nextShot = Time.time + fireInterval;
            GameObject bullet = Instantiate(bulletPrefab, transform.position + transform.forward, transform.rotation);
            bullet.GetComponent<Bullet>().damage = damage;
        }
    }
}

Unityのゲームアーキテクチャのすべてのレッスン

自分で練習してみよう: Unityプレイグラウンド