Następujący wpis na blogu, o ile nie zaznaczono inaczej, został napisany przez członka społeczności Gamasutras.
Wyrażone myśli i opinie są własnością piszącego, a nie Gamasutry lub jej firmy macierzystej.
Cel
Głównym celem tego wpisu na blogu jest przybliżenie pojęcia ScriptableObject w Unity.
Co to jest Scriptable Object?
Jaka jest różnica między ScriptableObject a klasą Monobehaviour?
Jakie są zalety i wady Scriptableobject?
Jak używać ScriptableObject?
Zrozummy wszystkie pytania, biorąc jedną przejażdżkę po tym blogu o ScriptableObject
Zgodnie z dokumentacją Unity API,
„ScriptableObject jest klasą, z której możesz się wywodzić, jeśli chcesz tworzyć obiekty, które nie muszą być dołączone do obiektów gry.”
Confuesed…?
Nie martw się, jeśli nie zrozumiałeś. Tutaj wyjaśnię, co to znaczy.
Jak wiemy, w Unity wszystko jest Obiektem.
Monobehaviours są jednym z Obiektów.
Obiekty gry: W twojej scenie, możesz poruszać się za pomocą transformacji.
ScriptableObject jest rodzajem Obiektu, ale, może on tylko Zawierać Dane.
Więc, nie angażują się one w rzeczywistą grę.
Mam nadzieję, że zrozumiałeś definicję ScriptableObject.
Przedyskutujmy Pros i Cons of ScriptableObject.
Proza ScriptableObject:
- Wbudowane w Unity
- Jest bardzo dobrze utrzymywane przez Unity.
- Możesz z nimi bardzo łatwo współdziałać w inspektorze Unity.
- Można je zapisać jako Assets
- Możesz je utworzyć jako mini plik wewnątrz swojego projektu.
- Możesz to aktualizować i zapisywać zgodnie z wymaganiami gry.
- Możesz zapisywać podczas runtime
- Jeśli zmienisz coś podczas runtime, to będzie to pamiętać.
- Wewnętrzne rozwiązanie
- Gdy próbujesz uzyskać dane w czasie działania gry, nie martwisz się o parsowanie zewnętrznych plików, które będą wchodzić w grę bardziej.
- Duża ilość danych
- Możesz zapisać miliony liczb całkowitych wewnątrz ScriptableObject.
- Więc jest dużo miejsca(brak funkcji ograniczającej rozmiar).
- Dodawanie do struktury w miarę postępu
- Jak budujesz obiekt skryptowy i tworzysz kilka jego instancji i zdajesz sobie sprawę, że potrzebuję nowego ustawienia dla 'moveSpeed’ lub jakiejkolwiek dodatkowej zmiennej, którą potrzebujesz, możesz dodać, to nie zakłóci twojej zmiennej.
- Usuwanie zmiennych może mieć trochę negatywny wpływ.
Cons of ScriptableObject:
- Wymaga edytora skryptów
- Jeśli chcesz tworzyć aktywa ze skryptów to musisz się trochę na tym znać.
- Nie możesz edytować poza Unity
- Jeśli pracujesz ściśle z Unity to nie jest to naprawdę wielki problem.
- Ale jeśli masz rozwiązanie typu team base, gdzie chcesz wysłać pliki do kogoś i kazać mu je edytować, to nie zadziała.
- Nie można zapisać po wdrożeniu
- Nie można zapisać podczas runtime, po zbudowaniu gry, co oznacza, że nie jest to rozwiązanie do zapisywania danych gracza.
Przyjmijmy jeden przykład, aby zrozumieć, jak używać ScriptableObject w grze.
Pozwól mi dać ci jedno zadanie jako pierwsze.
Załóżmy, że mamy 10 poziomów gry i na każdym poziomie zachowanie wroga będzie się zmieniać.
Jakieś pomysły, jak to zrobisz??
Możesz pomyśleć, że możesz zrobić 10 prefabrykatów 10 różnych wrogów i przypisać je do każdego poziomu. Prawda??
Czy jesteś pewien, że to naprawdę dobra praktyka?
Właściwie, odpowiedź brzmi Nie.
„Ponieważ jeden obiekt wroga może mieć 4 zmienne i funkcję Update() z nim, i załóżmy, że używa 4 Mb pamięci, więc 10 poziomów wroga może wymagać 40 Mb pamięci.”
Więc, oto rozwiązanie. Użyj ScriptableObject do przechowywania danych wrogiego obiektu.
Rozwińmy naszą mini grę za pomocą ScriptableObject.
Na początek stworzę prosty skrypt bez użycia ScriptableObject. (Zgodnie z naszą pierwszą myślą o stworzeniu innego prefabu każdego innego wroga i przypisaniu go do każdego poziomu 😉 )
Krok 1
- Utwórz pusty GameObject nazwij go Enemy.
Krok 2
- Utwórz skrypt C# i nazwij go EnemyMove
Napisz następujący kod w EnemyMove.cs
public class EnemyMove : MonoBehaviour {#region PUBLIC_VARIABLESpublic string name;public int moveSpeed;public Color color;public string colorName; public SpriteRenderer spriterendere;#endregion#region PRIVATE_VARIABLESprivate float speed;Vector3 newPosition;#endregion#region UNITY_CALLBACKSvoid Update () {ChangeSpeed();gameObject.name = name;spriterendere.color = color;newPosition=transform.position;newPosition.y = Mathf.Sin (Time.time) * speed;transform.position = newPosition;}#endregion#region PROVATE_METHODSprivate void ChangeSpeed(){speed = Mathf.MoveTowards (speed,moveSpeed,Time.deltaTime);}#endregion}
Krok 3
- Przypisać go do pustego obiektu GameObject(Enemy).
- Skrypt WrogiMove ma trzy zmienne publiczne.
- Jeśli gra ma tak wiele wrogich GameObject ze skryptem WrogiMove z nim wtedy używa dużo pamięci.
- Dla tego jak w naszym rozwiązaniu ScriptableObject, możemy zrobić skrypt EnemyData zamiast przechowywać te zmienne w skrypcie WrogiMove.
Krok 4
- Utwórz skrypt C# o nazwie EnemyData.
- który dziedziczy ScriptableObject zamiast Monobehaviour.
Napisz następujący kod w EnemyData.cs.
public class EnemyData : ScriptableObject {#region PUBLIC_VERIABLEpublic string name;public int moveSpeed;public Color color;public string colorName; #endregion}
Krok 5
- Zmień kod wewnątrz 'EnemyMove’, który został wcześniej utworzony.
- Utwórz jedną zmienną publiczną 'data’, która jest odniesieniem do 'EnemyData’.
- Usuń publiczną, która jest już w 'EnemyData’
Zmień zgodnie z następującym kodem.
public class EnemyMove : MonoBehaviour {#region PUBLIC_VARIABLESpublic EnemyData data;public SpriteRenderer spriterendere;#endregion#region PRIVATE_VARIABLESprivate float speed;Vector3 newPosition;#endregion#region UNITY_CALLBACKSvoid Update () {ChangeSpeed();gameObject.name = name;spriterendere.color = data.color;newPosition=transform.position;newPosition.y = Mathf.Sin (Time.time) * speed;transform.position = newPosition;}#endregion#region PROVATE_METHODSprivate void ChangeSpeed(){speed=Mathf.MoveTowards (speed,data.moveSpeed,Time.deltaTime);}#endregion}
Teraz możesz zobaczyć, że wewnątrz inspektora dla Enemy GameObject na zmiennej 'Data’ pojawi się,
Jakiś pomysł..co przypuszczasz przypisać tutaj?
Podążaj za mną…
Krok 1
- Dodaj jedną linię w EnemyData.cs w następujący sposób
public class EnemyData : ScriptableObject {#region PUBLIC_VERIABLEpublic string name;public int moveSpeed;public Color color;public string colorName; #endregion}
Krok 2
- Utwórz jeden folder Game data i wykonaj następujące czynności
Krok 3
- Nazwij go jak chcesz.
- Teraz możesz zobaczyć wszystkie zmienne wewnątrz EnemyData w oknie inspektora, możesz zmienić wartości zmiennych tutaj.
Krok 4
- Przypisanie tego do skryptu 'EnemyMove’
Jestem pewien, że teraz masz wszystkie odpowiedzi.
Podsumowanie
- ScripTableObject są naprawdę dobre dla tego, że mogą rozbić twoje dane na większe kawałki.
- Dlatego nie pożerasz dużo pamięci.
- ScripTableObject jest tylko dla celów rozwojowych.
.