Menu
CoddyTech

Atributos das armas

Parte da seção Arquitetura de jogos no Unity do Journey de Unity da Coddy. Lição 20 de 50.

Uma espada e um martelo fazem a mesma coisa: golpeiam, esperam e golpeiam de novo. O que os diferencia são os números. Uma espada causa 4 de dano e golpeia a cada 0.5 segundos; um martelo causa 10 de dano a cada 1.5 segundos. Portanto, um único script Weapon serve para ambos, e os números de cada arma ficam em um asset:

[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);
    }
}

O projeto contém um asset Sword (4, 0.5, um prefab de faísca) e um asset Hammer (10, 1.5, um prefab de poeira). Tanto o cavaleiro quanto o ogro têm o script Weapon; o campo data do cavaleiro contém Sword, e o do ogro, Hammer. Uma lança é mais um asset criado pelo menu Create, sem nenhuma alteração em qualquer script. Um asset pode apontar para prefabs e para outros assets, como hitEffect, mas não para objetos em uma cena: ele fica no projeto, fora de todas as cenas.

As outras maneiras de obter armas diferentes colocam os números no código. if (weaponName == "Sword") damage = 4; else if ... cresce a cada arma, e uma subclasse Sword de Weapon que apenas define números significa uma classe por asset. Subclasses servem para armas que agem de forma diferente, como um arco que dispara flechas. Uma arma que apenas causa mais dano ou golpeia mais rápido precisa de seu próprio asset e de nenhum código.

challenge icon

Desafio

Médio

O campo de tiro tem quatro armas: duas pistolas, um rifle e um bláster novo. Segurar Space dispara todas elas. O script Gun escolhe sua bala, intervalo de disparo e dano com if/else em gunType, e o bláster não está incluído, então ele não dispara (olhe o Console).

Faça com que cada arma leia seus valores de um asset. GunData.cs está pronto, e o projeto tem assets de Pistol, Rifle e Blaster criados a partir dele, cada um com seu próprio prefab de bala.

  • Adicione a Gun um campo público data do tipo GunData; o Inspector coloca o asset de cada arma nele.
  • Dispare data.bulletPrefab, espere data.fireInterval entre os disparos e atribua data.damage a cada bala.
  • Remova gunType, os dois campos de bala, as cópias privadas e o if/else.

Pressione Play e segure Space, depois Check.

Experimente você mesmo

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;
        }
    }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Arquitetura de jogos no Unity