unity3d
ScriptableObject
Recherche…
Remarques
ScriptableObjects avec AssetBundles
Faites attention lorsque vous ajoutez des prefabs à AssetBundles s'ils contiennent des références à ScriptableObjects. Étant donné que ScriptableObjects sont essentiellement des actifs, Unity en crée des doublons avant de les ajouter à AssetBundles, ce qui peut entraîner un comportement indésirable lors de l'exécution.
Lorsque vous chargez un objet GameObject à partir d'un AssetBundle, il peut être nécessaire de réinjecter les actifs ScriptableObject dans les scripts chargés, en remplacement des fichiers groupés. Voir Injection de dépendance
introduction
ScriptableObjects sont des objets sérialisés qui ne sont pas liés à des scènes ou des objets de jeu comme MonoBehaviours. Pour le dire d'une certaine manière, il s'agit de données et de méthodes liées à des fichiers d'actif dans votre projet. Ces actifs ScriptableObject peuvent être transmis à MonoBehaviours ou à d'autres ScriptableObjects, où leurs méthodes publiques sont accessibles.
En raison de leur nature de ressources sérialisées, elles constituent d'excellentes classes de gestionnaires et de sources de données.
Création d'actifs ScriptableObject
Vous trouverez ci-dessous une implémentation simple de ScriptableObject.
using UnityEngine;
[CreateAssetMenu(menuName = "StackOverflow/Examples/MyScriptableObject")]
public class MyScriptableObject : ScriptableObject
{
[SerializeField]
int mySerializedNumber;
int helloWorldCount = 0;
public void HelloWorld()
{
helloWorldCount++;
Debug.LogFormat("Hello! My number is {0}.", mySerializedNumber);
Debug.LogFormat("I have been called {0} times.", helloWorldCount);
}
}
En ajoutant l'attribut CreateAssetMenu
à la classe, Unity le répertoriera dans le sous-menu Assets / Create . Dans ce cas, il se trouve sous Assets / Create / StackOverflow / Examples .
Une fois créées, les instances de ScriptableObject peuvent être transmises à d'autres scripts et à ScriptableObjects via l'inspecteur.
using UnityEngine;
public class SampleScript : MonoBehaviour {
[SerializeField]
MyScriptableObject myScriptableObject;
void OnEnable()
{
myScriptableObject.HelloWorld();
}
}
Créer des instances ScriptableObject via le code
Vous créez de nouvelles instances ScriptableObject via ScriptableObject.CreateInstance<T>()
T obj = ScriptableObject.CreateInstance<T>();
Où T
étend ScriptableObject
.
Ne créez pas ScriptableObjects en appelant leurs constructeurs, c.-à-d.
new ScriptableObject()
.
La création de ScriptableObjects par code pendant l'exécution est rarement requise car leur utilisation principale est la sérialisation des données. Vous pourriez aussi bien utiliser des classes standard à ce stade. C'est plus fréquent lorsque vous écrivez des extensions d'éditeur.
ScriptableObjects sont sérialisés dans l'éditeur même dans PlayMode
Des précautions supplémentaires doivent être prises lors de l'accès aux champs sérialisés dans une instance ScriptableObject.
Si un champ est marqué comme public
ou sérialisé via SerializeField
, sa modification est permanente. Ils ne se réinitialisent pas lorsque vous quittez le mode de lecture, comme le fait MonoBehaviours. Cela peut être utile parfois, mais cela peut aussi causer des dégâts.
Pour cette raison, il est préférable de rendre les champs sérialisés en lecture seule et d'éviter les champs publics.
public class MyScriptableObject : ScriptableObject
{
[SerializeField]
int mySerializedValue;
public int MySerializedValue
{
get { return mySerializedValue; }
}
}
Si vous souhaitez stocker des valeurs publiques dans un scriptableObject réinitialisé entre les sessions de lecture, envisagez d'utiliser le modèle suivant.
public class MyScriptableObject : ScriptableObject
{
// Private fields are not serialized and will reset to default on reset
private int mySerializedValue;
public int MySerializedValue
{
get { return mySerializedValue; }
set { mySerializedValue = value; }
}
}
Rechercher des ScriptableObjects existants lors de l'exécution
Pour rechercher des ScriptableObjects actifs pendant l'exécution, vous pouvez utiliser Resources.FindObjectsOfTypeAll()
.
T[] instances = Resources.FindObjectsOfTypeAll<T>();
Où T
est le type de l'occurrence de ScriptableObject que vous recherchez. Actif signifie qu'il a été chargé en mémoire sous une forme quelconque auparavant.
Cette méthode est très lente, alors n'oubliez pas de mettre en cache la valeur de retour et d'éviter de l'appeler fréquemment. Le référencement direct de ScriptableObjects dans vos scripts devrait être votre option préférée.
Conseil: Vous pouvez gérer vos propres collections d'instances pour des recherches plus rapides. Demandez à vos ScriptableObjects de s’inscrire eux-mêmes à une collection partagée pendant
OnEnable()
.