Menu
CoddyTech

Waffenwerte

Teil des Abschnitts Spielarchitektur in Unity der Unity-Journey von Coddy. Lektion 24 von 64.

Ein Schwert und ein Hammer machen dasselbe: Sie schwingen, warten und schwingen erneut. Was sie unterscheidet, sind die Zahlen. Ein Schwert verursacht 4 Schaden und schwingt alle 0.5 Sekunden, ein Hammer verursacht alle 1.5 Sekunden 10 Schaden. Daher reicht ein Weapon-Skript für beide, und die Zahlen jeder Waffe stehen in einem 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);
    }
}

Das Projekt enthält ein Schwert-Asset (4, 0.5, ein Funken-Prefab) und ein Hammer-Asset (10, 1.5, ein Staub-Prefab). Sowohl der Ritter als auch der Oger verwenden das Weapon-Skript; im Feld data des Ritters ist das Schwert hinterlegt, im Feld des Ogers der Hammer. Ein Speer ist ein weiteres Asset, das über das Create-Menü erstellt wird, ohne dass ein Skript geändert werden muss. Ein Asset kann auf Prefabs und andere Assets verweisen, wie hitEffect, aber nicht auf Objekte in einer Szene: Es befindet sich im Projekt, außerhalb jeder Szene.

Bei den anderen Möglichkeiten, verschiedene Waffen zu erstellen, stehen die Zahlen jeweils im Code. if (weaponName == "Sword") damage = 4; else if ... wird mit jeder Waffe umfangreicher, und eine Sword-Unterklasse von Weapon, die nur Zahlen festlegt, bedeutet eine Klasse pro Asset. Unterklassen sind für Waffen gedacht, die sich anders verhalten, etwa ein Bogen, der Pfeile abschießt. Für eine Waffe, die nur härter trifft oder schneller schwingt, braucht es ein eigenes Asset und keinen Code.

challenge icon

Aufgabe

Mittel

Lass jede Waffe ihre Werte aus ihrem GunData-Asset lesen.

  1. Füge in Gun public GunData data; hinzu.
  2. Schieße data.bulletPrefab ab, warte zwischen den Schüssen data.fireInterval und weise jeder Kugel data.damage zu.
  3. Lösche gunType, die beiden Kugelfelder, die drei privaten Kopien und Start().

Drücke auf „Spielen“ und halte die Leertaste gedrückt: Auch der Blaster feuert. Drücke dann auf „Prüfen“.

Probier es selbst

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

Alle Lektionen in Spielarchitektur in Unity

Übe selbstständig: Unity-Playground