JEU VIDEO

Fiches pratiques

Maths

Vecteurs

  • Visualisé sous forme d'une flèche
  • Peut représenter :
    • Une translation (Déplacement relatif dans l'espace)
    • Un point dans l'espace (= Translation depuis point d'origine (0,0,0))
    • Une direction (direction) et une normal (magnitude)
  • Vecteur normalisé = vecteur d'amplitude 1.

Vecteurs

  • On peut additionner 2 vecteurs
  • Additioner un vecteur et un nombre n revient à ajouter n à chaqune des dimension
  • multiplier un vecteur et un nombre n revient à ajouter n à chaqune des dimension
  • La "normale" d'une surface est le vecteur perpendiculaire à cette surface
  • Le produit scalaire donne une nombre indiquant l'orientation des vecteurs
    - Pour les vecteurs normalisé, -1 = directions opposées, 0 = perpendiculaires, 1 = même direction
    - Vector3.Dot

Cercle trigonométrique

  • Angle exprimé en radians ou degrés
  • 2π Rad = 360 deg
  • π Rad = 180 deg
  • 1 Rad = 180 / π deg,
    var deg = rad * Mathf.Rad2Deg
  • 1 deg = π / 180 rad,
    var rad = deg * Mathf.Deg2Rad

Programmation

Minimalisme

Types génériques en C#

// Fonction
public static T rand<T>(T a, T b) {
    return Random.value > 0.5f ? a : b;
}

int entier = rand ( 10 , 22 );
double dbl = rand ( 3.14 , 1.618 );
string str = rand ( "3.14" , "42" );
// Struct
public struct Tuple<T,U> {
    public T left;
    public U right;
}
// Class
public class ListOfTuple<T,U> {
    public List<Tuple<T,U>> collection = new List<Tuple<T,U>>();
}

Unity

Prefabs

  • Glisser/Déposer un objet d'une scène dans le projet pour faire un prefab
  • Glisser/Déposer un prefab sur la scène pour créer une instance liée
  • Mettre à jour prefab = update sur toutes les instances liés
  • Mettre à jour instance liée = possibilité d'apply
  • Seules les valeurs par défauts sont mises à jours, les valeurs spécifiques instance sont indiquées en gras dans l'interface

Collaboration, Prefabs, Scènes

  • Une scène par collaborateur (Très difficile à fusionner à la main)
  • Chaqun développe ses prefabs, scripts et sa scène de façon indépendante
  • 1 personne fait l'intégration dans la scène générale du jeu

Interactions entre scripts


private ScriptName scripteRef;

// Use this for initialization
void Start () {
    // Récupère une référence au script ScriptName attaché au même GameObject
    scripteRef = GetComponent ();
}

Hiérarchie - références et parents


public Transform otherGameObjectTransform;
public GameObject otherGameObject2;

private ScriptName scripteRef;
private ScriptName scripteRef2;

void Start () {
    // scripteRef attaché à otherGameObjectTransform
    scripteRef = otherGameObjectTransform.gameObject.GetComponent ();
    Transform parent = otherGameObjectTransform.parent;

    // scripteRef2 attaché à otherGameObject2
    scripteRef2 = otherGameObject2.GetComponent ();
    GameObject parent2 = otherGameObject2.transform.parent.gameObject;
}

Hiérarchie - Parcourir les enfants


// Use this for initialization
void Start () {
    IEnumerable<Transform> children = (IEnumerable<Transform>) this.transform;
    foreach (Transform child in children) {
        child.gameObject.GetComponent<ScriptName>(); // peut être null !
    }
    foreach (Transform child in this.transform) {
        child.gameObject.GetComponent<ScriptName>(); // peut être null !
    }
    foreach (ScriptName script in this.GetComponentsInChildren<ScriptName>()) {
        // script n'est pas null
    }
}

Audio

  • Audio Source = Haut parleur qui peut lire un son à la fois.
  • C'est un composant à attacher à un game objet, il sera spacialisé à l'endroit de l'objet.
  • Audio Clip = Clip audio qui peut être lu par un Audio source.
  • On peut changer le Audio Clip d'un Audio Source par script.
  • Le son est capturé par l'Audio Listener, positionné par défaut sur la caméra.

[ExecuteInEditMode]

L'annotation [ExecuteInEditMode] permet d'exécuter un script en mode édition. Ex: Track, Ex: DepthSortByY

UI - Bouton qui déclenche une action générique

  • Attacher un composant collider2D à une GameObject de la scène pour intercepter le click.
  • Attention au positionnement Z, que rien n'obstrue le bouton depuis la caméra.
  • Ajouter un script OnClick tel que : OnClick.cs

Barre de vie

  • GameObject parent pour positionner le tout
    • GameObject BackgroundScaler pour étendre la barre vide
      • SpriteRenderer BackgroundSprite avec décalage de 0.5 vers la droite pour décaler le point d'origine du scaling
    • GameObject ForegroundScaler pour étendre la barre pleine
      • SpriteRenderer ForegroundSprite avec décalage de 0.5 vers la droite pour décaler le point d'origine du scaling
  • Ajouter un script pour piloter la taille des éléments visuels (Ex: LifebarController.cs)

Exécuter une action étendue sur plusieurs frames / durées

  • One time :
    StartCoroutine (DoShake ());
  • loop :
    IEnumerator DoShake () {
        Quaternion originalRotation = this.transform.rotation;
        int durationInFrames = 20;
        for (int i = 0; i < durationInFrames; i++) {
            this.transform.rotation = Quaternion.Euler (0, 0, 360f / durationInFrames);
            yield return null; // wait next frame before continuing
        }
        this.transform.rotation = originalRotation;
    }

Dev Tricks

Intéractions Globales

A coder soi même
  • EventManager.TriggerEvent("Shake");
  • EventManager.StartListening ("Shake", this.OnShake);
  • EventManager.StopListening ("Shake", this.OnShake);
EventManager.cs
Shake.cs

Animation avec Tweening

Tracking avec offset et stiffness

  • A faire soi même
  • Offset = déclage fixe par rapport à la cible
  • Stiffness = Rigidité, Force avec laquelle le trackeur colle sa cible
    0 ne suit pas du tout, 1 ne se détache jamais
  • Pour un tracking parfait, placer l'élément trackeur en tant qu'enfant de l'élément tracké, ex: barre de vie enfant de l'objet caméra
Track.cs

Depth Ordered By Y

  • Lorsqu'on a une profondeur simulée vers le fond (ex: 2D isométrique) un objet plus près devrait toujours apparaitre par dessus un objet plus loin en fonction de sa position Y.
  • Faire un script qui positionne la position de rendu dans le layer en fonction de Y.
  • DepthSortByY

SnapToGrid

  • Lorsqu'on veut aligner des éléments arbitrairement sur une ligne, arrondir les coordonnées de l'élément dans le référentiel de la grille.
  • SnapToGrid.cs

Génération procédurale

Random.InitState(1);
Debug.Log(Random.Range(-10, 10)); // always 4
Debug.Log(Random.value); // always 0.7742628
Debug.Log(Random.ColorHSV()); // always RGBA(0.344, 0.321, 0.594, 1.000)
Debug.Log(Random.rotation.eulerAngles.z); // always 253.6533

Random.InitState(1);
Debug.Log(Random.Range(-10, 10)); // always 4
Debug.Log(Random.value); // always 0.7742628
Debug.Log(Random.ColorHSV()); // always RGBA(0.344, 0.321, 0.594, 1.000)
Debug.Log(Random.rotation.eulerAngles.z); // always 253.6533

Random.InitState(2);
Debug.Log(Random.Range(-10, 10)); // always -4
Debug.Log(Random.value); // always 0.0996678
Debug.Log(Random.ColorHSV()); // always RGBA(0.329, 0.235, 0.319, 1.000)
Debug.Log(Random.rotation.eulerAngles.z); // always 206.4019

Random.InitState(System.Environment.TickCount); // unpredictable
                    

Génération procédurale - Inspirations

Dessin dynamique

  • DrawableQuad Folder
  • Placer des GameObject de façon incrémentale
  • Autre ? Dépends de ce qu'on veut faire

Fighting games