Menu
CoddyTech

Atributos da Arma

Parte da seção Arquitetura de Jogos no Unity do Journey de Unity da Coddy. Lição 24 de 64.

Uma espada e um martelo fazem a mesma coisa: balançam, esperam e balançam de novo. O que os diferencia são os números. Uma espada causa 4 de dano e balança 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 contém Hammer. Uma lança é mais um asset criado no menu Create, sem nenhuma alteração em qualquer script. Um asset pode apontar para prefabs e 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 nova arma, e uma subclasse Sword de Weapon que apenas define números significa uma classe por asset. Subclasses são para armas que agem de forma diferente, como um arco que dispara flechas. Uma arma que apenas causa mais dano ou balança mais rápido precisa do próprio asset e de nenhum código.

challenge icon

Desafio

Médio

Faça com que cada arma leia seus valores numéricos do recurso GunData.

  1. Em Gun, adicione public GunData data;.
  2. Dispare data.bulletPrefab, espere data.fireInterval entre os disparos e atribua data.damage a cada bala.
  3. Exclua gunType, os dois campos de bala, as três cópias privadas e Start().

Pressione “Jogar” e mantenha Espaço pressionado: o blaster também dispara. Depois, “Verificar”.

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

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

Pratique por conta própria: Playground de Unity