Scripts, callbacks et champs
Un script est une classe C# du dossier des scripts FL# du monde, listée dans Flux Sharp Sources de la NW World Config. Le composant FL# Script la pose sur un objet de la scène : un composant par script, autant que tu veux sur un même objet.
Ce qui fait un script
- Une classe qui dérive de
FluxScript, ni abstraite ni générique, publique (ou imbriquée dans une classe sans être privée). Une classe abstraite ou générique peut servir de base à tes scripts. - Un constructeur public sans paramètres : c'est la scène qui crée le script. Sans lui,
fluxcs'arrête avecFL# script MonMonde.Porte needs a public constructor without parameters: the scene creates it. - Des callbacks écrits
protected override.void Update()écrit comme dans Unity ne serait jamais appelé, alorsfluxcle refuse :error CS0114: 'Porte.Update()' hides inherited member 'FluxScript.Update()'.
using NodeWorld.Flux;
namespace MonMonde
{
public class Toupie : FluxScript
{
public float degresParSeconde = 45f;
protected override void Update()
{
transform.Rotate(new Vector3(0f, degresParSeconde * Time.deltaTime, 0f));
}
}
}Les callbacks
Dans l'ordre du MonoBehaviour de Unity :
| Callback | Quand |
|---|---|
Awake() | Le script est créé, ses champs déjà réglés par la scène. Tous les scripts de la scène sont créés et réglés avant le premier Awake : un champ peut donc désigner un script créé après lui. Awake tourne aussi sur un objet inactif. |
OnEnable() | Son objet devient actif dans la hiérarchie, et juste après Awake quand il est actif au chargement. |
Start() | Avant son premier Update. |
FixedUpdate() | À chaque pas de la physique (Time.fixedDeltaTime). |
Update() | À chaque image. |
LateUpdate() | À chaque image, après tous les Update, les coroutines et les suites des async. |
OnBeforeRender() | Juste avant que l'image soit dessinée (un miroir y fait le rendu de son reflet). |
OnDisable() | Son objet devient inactif : plus de Start, Update, LateUpdate, FixedUpdate ni OnBeforeRender jusqu'à ce qu'il redevienne actif. |
OnDestroy() | Son objet est détruit, ou le monde se décharge. |
enabled = false arrête les Update, LateUpdate, FixedUpdate et OnBeforeRender du script ; ses événements arrivent toujours.
Les événements ont leurs pages : utiliser et attraper des objets dans interaction et commandes, les triggers et les collisions dans physique, les joueurs qui arrivent, partent et réapparaissent dans joueurs, le propriétaire et l'état synchronisé dans objets et valeurs synchronisés, les messages dans événements réseau.
Les champs réglés par la scène
Le composant FL# Script règle les champs publics du script avant Awake. Clique sur Read the scripts : le SDK compile une fois les scripts du monde, liste leurs classes dans Script et affiche les champs de celle que tu choisis. Un champ auquel tu ne touches pas indique script default (la valeur que lui donne ton code) ; Set lui donne une valeur de la scène, Reset la retire.
Un champ est réglé par la scène quand c'est un champ d'instance public, ni static, ni const, ni readonly, d'un de ces types, ou un tableau à une dimension de l'un d'eux :
| Sorte | Types |
|---|---|
| Valeurs | bool, int, long, float, double, string, une enum |
| Vecteurs | Vector2, Vector3, Vector4, Quaternion, Color |
| Objets | GameObject, et une autre classe de script FL# du monde |
| Composants | Transform, RectTransform, Rigidbody, Collider, BoxCollider, SphereCollider, Renderer, LineRenderer, TrailRenderer, MeshFilter, Camera, Light, AudioSource, ParticleSystem, Animator, LODGroup, ReflectionProbe, ParentConstraint, Volume, Canvas, CanvasGroup, Text, Image, Button, Slider, Toggle, Dropdown, InputField, ScrollRect, Scrollbar |
| Assets | AudioClip, Material, Texture, Sprite, Mesh |
Un champ d'un autre type garde la valeur que lui donne ton code. Une valeur enregistrée dans la scène qui ne va plus au champ (tu as changé son type dans le script) est laissée de côté, et le journal le dit : 'Porte': the value of MonMonde.Porte.angleOuvert is a String, the field is a float: not set.
Où tourne un script
Le jeu de chaque joueur fait tourner les scripts du monde pour lui-même, et le serveur les fait tourner aussi, sur sa propre copie de la scène. World.isServer dit où tourne le code.
| Jeux des joueurs | Serveur | |
|---|---|---|
| Un script sans attribut | oui | oui |
[ClientOnly] | oui | non |
[ServerOnly] | non | oui |
Une classe ne peut pas avoir les deux attributs (fluxc : cannot be [ClientOnly] and [ServerOnly]). Le serveur n'a ni physique, ni rendu, ni joueur local, ni commandes : marque [ClientOnly] un script qui ne fait que dessiner, jouer du son ou lire le joueur, et vois ce qui tourne sur le serveur.
En Play mode, les scripts tournent une fois, comme dans le jeu d'un joueur, avec toi seul dans la salle : tu es le maître, et les scripts [ServerOnly] ne sont pas créés.
Des scripts qui se servent l'un de l'autre
GetScript<T>()donne le script de classeTdu même objet (le premier), ounull;gameObject.GetScripts<T>()les donne tous ;gameObject.GetScriptsInChildren<T>()ceux de l'objet et de ses enfants.- Un champ du type d'une autre classe de script (
public Tableau tableau;) se règle depuis la scène : dépose l'objet qui porte ce script.
Quand un script échoue
Une exception qui sort d'un callback arrête ce script seul : il ne reçoit plus de callbacks et ses coroutines s'arrêtent. Les autres scripts continuent. Le journal dit lequel, où et pourquoi :
[FL# Taverne] FL# script MonMonde.Porte on Porte stopped in Update: System.InvalidOperationException: <son message>Un appel que le jeu refuse (une mauvaise valeur, une chose que ton monde n'a pas le droit de faire) ne fait rien, renvoie 0, false ou null, et le script continue ; le journal le dit une fois : FL# host refused a script call (ignored, the scripts go on): <raison>. Où lire ces lignes : les journaux de tes scripts.
