Menu
CoddyTech

Характеристики оружия

Часть раздела Архитектура игр в Unity путешествия по Unity на Coddy. Урок 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, префаб искры) и ресурс Hammer (10, 1.5, префаб пыли). И рыцарь, и огр используют скрипт Weapon; поле data у рыцаря содержит Sword, а у огра — Hammer. Копьё — ещё один ресурс, созданный через меню Create, при этом ни один скрипт менять не нужно. Ресурс может ссылаться на префабы и другие ресурсы, как это делает hitEffect, но не на объекты в сцене: он находится в проекте, вне всех сцен.

При других способах создания разных видов оружия числа задаются в коде. Конструкция if (weaponName == "Sword") damage = 4; else if ... разрастается с каждым новым оружием, а подкласс Sword класса Weapon, который только задаёт числа, — это отдельный класс для каждого ресурса. Подклассы нужны для оружия, которое действует иначе, например для лука, стреляющего стрелами. Если оружие лишь наносит больше урона или быстрее замахивается, ему нужен собственный ресурс, а код не нужен.

challenge icon

Задание

Средне

Пусть каждое оружие считывает свои параметры из ресурса GunData.

  1. В Gun добавь public GunData data;.
  2. Стреляй снарядом data.bulletPrefab, выдерживай data.fireInterval между выстрелами и задавай каждому снаряду data.damage.
  3. Удали gunType, два поля снарядов, три приватные копии и Start().

Нажми «Играть» и удерживай пробел: бластер тоже начнёт стрелять. Затем нажми «Проверить».

Попробуйте сами

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