Il seguente post sul blog, se non diversamente specificato, è stato scritto da un membro della comunità di Gamasutras.
I pensieri e le opinioni espresse sono quelle dello scrittore e non di Gamasutra o della sua società madre.
Obiettivo
L’obiettivo principale di questo post del blog è quello di darvi un’idea su ScriptableObject in Unity.
Che cos’è Scriptable Object?
Qual è la differenza tra ScriptableObject e la classe Monobehaviour?
Quali sono i pro e i contro di Scriptableobject?
Come usare ScriptableObject?
Sottolineiamo tutte le domande facendo un giro in questo blog su ScriptableObject
Secondo la documentazione API di Unity,
“ScriptableObject è una classe da cui puoi derivare se vuoi creare oggetti che non hanno bisogno di essere attaccati agli oggetti del gioco.”
Confuso…
Non preoccuparti, se non hai capito. Qui, ti spiegherò cosa significa.
Come sappiamo, con Unity, tutto è un Oggetto.
I Monocomportamenti sono uno degli Oggetti.
GameObjects: Nella tua scena, puoi muoverti con i transform.
ScriptableObject è un tipo di Oggetto ma, può contenere solo Dati.
Quindi, non vengono coinvolti nel gioco vero e proprio.
Spero che tu abbia capito la definizione di ScriptableObject.
Discutiamo i pro e i contro di ScriptableObject.
Prospetti degli ScriptableObject:
- Costruiti in Unity
- Sono molto ben mantenuti da Unity.
- Puoi interagire con loro molto facilmente in Unity inspector.
- Puoi essere salvati come Assets
- Puoi crearli come mini file all’interno del tuo progetto.
- Puoi aggiornarlo e salvarlo secondo i tuoi requisiti di gioco.
- Puoi salvare durante il runtime
- Se cambi qualcosa durante il runtime lo ricorderà.
- Soluzione interna
- Quando stai cercando di ottenere i dati durante il runtime del gioco, non ti preoccupi di analizzare i file esterni che entreranno in gioco di più.
- Grande quantità di dati
- Puoi salvare milioni di interi all’interno di uno ScriptableObject.
- Così, c’è molto spazio (nessuna funzione di limite di dimensione).
- Aggiungi alla struttura mentre vai
- Come stai costruendo un oggetto scrivibile e crei alcune istanze di esso e ti rendi conto, ohh ho bisogno di una nuova impostazione per ‘moveSpeed’ o qualsiasi altra variabile aggiuntiva di cui hai bisogno, puoi aggiungere, non disturberà la tua variabile.
- Cancellare la variabile può avere un impatto un po’ negativo.
Cons di ScriptableObject:
- Richiede un editor di scripting
- Se vuoi creare asset con lo scripting allora devi conoscerlo un po’.
- Non puoi modificare fuori da Unity
- Se stai lavorando strettamente con Unity questo non è davvero un grosso problema.
- Ma se hai una soluzione tipo team base, dove vuoi mandare i file a qualcuno e farli modificare, allora non funzionerà.
- Non puoi salvare una volta distribuito
- Non puoi salvare durante il runtime, una volta che hai costruito il gioco, il che significa che questa non è una soluzione per salvare i dati di un giocatore.
Prendiamo un esempio per capire come usare ScriptableObject nel gioco.
Lasciate che vi dia prima un compito.
Supponiamo di avere 10 livelli di gioco e ad ogni livello il comportamento del nemico cambierà.
Qualche idea, come farete questo?
Ahh, si potrebbe pensare che fare 10 prefabbricati di 10 nemici diversi e assegnarlo ad ogni livello. Giusto??
Sei sicuro, è davvero una buona pratica?
In realtà, la risposta è No.
“Perché un oggetto nemico può avere 4 variabili e la funzione Update() con esso, e supponiamo che usi 4 Mb di memoria, quindi 10 livelli nemici possono richiedere 40 Mb di memoria.”
Quindi, ecco la soluzione. Usare ScriptableObject per memorizzare i dati dell’oggetto nemico.
Sviluppiamo il nostro mini gioco con ScriptableObject.
Primo, creerò un semplice script senza usare uno ScriptableObject. (Come per il nostro primo pensiero di creare diversi prefabbricati di ogni diverso nemico e assegnarli ad ogni livello 😉 )
Step 1
- Crea un GameObject vuoto chiamandolo Enemy.
Step 2
- Crea lo script C# e chiamalo EnemyMove
Scrivi il seguente codice in 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}
Step 3
- Assegnalo a GameObject(Enemy) vuoto.
- Lo script EnemyMove ha tre variabili pubbliche.
- Se il gioco ha tanti GameObject nemici con lo script enemyMove allora usa molta memoria.
- Per questo come per la nostra soluzione ScriptableObject, possiamo fare uno script EnemyData invece di memorizzare queste variabili nello script EnemyMove.
Passo 4
- Creiamo uno script C# con nome EnemyData.
- che eredita ScriptableObject invece di Monobehaviour.
Scriviamo il seguente codice in EnemyData.cs.
public class EnemyData : ScriptableObject {#region PUBLIC_VERIABLEpublic string name;public int moveSpeed;public Color color;public string colorName; #endregion}
Passo 5
- Cambia il codice all’interno di ‘EnemyMove’, che è stato precedentemente creato.
- Crea una variabile pubblica ‘data’ che è il riferimento di ‘EnemyData’.
- Rimuovi la pubblica che è già in ‘EnemyData’
Cambia secondo il seguente codice.
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}
Ora si può vedere che all’interno dell’ispettore per GameObject nemico su ‘Data’ variabile apparirà,
Ha idea..cosa si suppone assegnare qui?
Seguimi…
Step 1
- Aggiungi una linea in EnemyData.cs come segue
public class EnemyData : ScriptableObject {#region PUBLIC_VERIABLEpublic string name;public int moveSpeed;public Color color;public string colorName; #endregion}
Step 2
- Crea una cartella Game data e fai come segue
Step 3
- Nominala come vuoi.
- Ora, puoi vedere tutte le variabili dentro EnemyData nella finestra dell’ispettore, puoi cambiare i valori delle variabili qui.
Passo 4
- Assegnare questo nello script ‘EnemyMove’
Sono sicuro che hai tutte le risposte ora.
Conclusione
- ScriptableObject sono davvero buoni per il fatto che possono spezzare i tuoi dati in pezzi più grandi.
- Così non stai consumando molta memoria.
- ScriptableObject è solo per lo scopo di sviluppo.