Zasoby danych
Część sekcji Architektura gier w Unity ścieżki Unity w Coddy. Lekcja 19 z 50.
W grze rolniczej rosną marchewki i dynie. Marchewka rośnie przez 30 sekund i sprzedaje się za 5 monet, a dynia rośnie przez 90 sekund i sprzedaje się za 40. Te liczby dotyczą uprawy, a nie pojedynczej rośliny: jako pola Inspector w skrypcie Plant każda marchewka w każdej scenie ma własną kopię wartości 30 i 5, a ich zmiana oznacza konieczność znalezienia ich wszystkich. ScriptableObject przechowuje takie dane w zasobie — pliku w projekcie, do którego może odwoływać się dowolna liczba obiektów. Jego klasa dziedziczy po ScriptableObject, a nie po MonoBehaviour:
using UnityEngine;
[CreateAssetMenu(fileName = "NewPlant", menuName = "Farm/Plant Data")]
public class PlantData : ScriptableObject
{
public string plantName;
public float growTime;
public int sellPrice;
}[CreateAssetMenu] umieszcza klasę w menu Create w oknie Project. Kliknij prawym przyciskiem myszy w oknie Project, wybierz Create > Farm > Plant Data, a Unity utworzy zasób o nazwie NewPlant; zmień jego nazwę na Carrot, zaznacz go i wpisz Carrot, 30 i 5 w jego polach w Inspectorze. Zasób Pumpkin tworzy się w ten sam sposób. Klasa trafia do pliku o tej samej nazwie, PlantData.cs, tak jak klasa MonoBehaviour.
Logika działania pozostaje w MonoBehaviour, które ma pole typu tego zasobu. Przeciągnij zasób Carrot na to pole, a skrypt odczyta przez nie liczby:
public class Plant : MonoBehaviour
{
public PlantData data;
private float age;
void Update()
{
age += Time.deltaTime;
if (age >= data.growTime)
{
Debug.Log(data.plantName + " is ready, worth " + data.sellPrice);
enabled = false;
}
}
}ScriptableObject nie znajduje się na żadnym GameObject ani w żadnej scenie. Nie ma Transform, a Unity nigdy nie wywołuje jego Update ani Start: przechowuje dane, a Plant zawiera logikę działania. Gdy 200 marchewek odwołuje się do jednego zasobu Carrot, ustawienie jego growTime na 25 zmienia wartość dla wszystkich 200. W kodzie instancję tworzy się za pomocą ScriptableObject.CreateInstance<PlantData>(), nigdy za pomocą new.
Wyzwanie
ŚredniBohater porusza się po arenie za pomocą strzałek. Jego imię, szybkość i kolor są polami skryptu Hero, a każdy nowy bohater kopiowałby je od nowa. Przenieś je do zasobu:
- W pliku
HeroData.csnapiszHeroData— ScriptableObject z publicznymi polamiheroName(string),moveSpeed(float) icolor(Color). Dodaj do niego[CreateAssetMenu]z nazwą menuHeroes/Hero Data. - W pliku
Hero.cszastąp te trzy pola jednym publicznym polemdatatypu HeroData i użyj wartości z zasobu w miejscach, w których skrypt korzystał z własnych pól.
W projekcie znajduje się zasób Knight utworzony za pomocą tego menu (Knight, szybkość 3, czerwony), a Inspector umieszcza go w polu data bohatera. Naciśnij Play i poruszaj Knightem, a następnie kliknij Check.
Spróbuj swoich sił
using UnityEngine;
// HeroData: imię, szybkość i kolor bohatera jako ScriptableObject
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Architektura gier w Unity
1Komponenty, nie hierarchie
Małe komponentyPodstawowy skrypt przeciwnikaKomponenty abstrakcyjneWspółpracujące komponentyPodsumowanie: modułowa wieżyczka4Dane serializowane
Klasy serializowalneListy w InspectorzeWyliczenia w InspectorzePodsumowanie: tabela łupów10Projekt: Arena przetrwania
BohaterTypy wrogów2Interfejsy w Unity
IDamageableInterfejsy i TryGetComponentGetComponentsPodsumowanie: klawisz interakcji5ScriptableObjects
Zasoby danychStatystyki broniWspółdzielone ustawieniaFale jako danePowtórka: baza danych przedmiotów8Kod wielokrotnego użytku
Metody rozszerzająceGeneryczny singletonGeneryczne metody pomocniczePodsumowanie: FindNearest