Charger vos niveaux avec des paramètres dans Unity3D

Unity3D est peut être un fantastique outil, il n’en reste pas moins perfectible sur certains points et l’une des choses qui peut paraître banale mais qui n’est pas évidente est de charger une scène avec des paramètres ! Alors par défaut ce n’est pas possible car la méthode LoadLevel(string sceneName) ne prend pas de paramètre (#stress) mais on peut palier à ce problème vraiment très facilement en créant un gestionnaire de scène. Il y a deux méthodes, soit on créé un script dérivant de MonoBehavior et on place un DontDestroyOnLoad dans la méthode Start(), soit on créé une classe statique. Je vais opter pour la deuxième solution qui est à mon sens beaucoup plus adaptée, car effectivement il n’est pas nécessaire d’ajouter ce gestionnaire sur un GameObject de la scène, on y accédera depuis n’importe quel fichier facilement.

Commencez par créer un nouveau script vide et appelez le LevelManager. Cette classe sera donc statique et comportera les méthodes suivantes :

  • SetParameter(string param, object value)
  • GetParameter(string param)
  • ClearParameters()
  • LoadLevel(string levelName, Dictionary<string, object> params)
  • LoadLevel(string levelName)

C’est une implémentation basique pour ce tutoriel, dans mon projet actuel par exemple j’ai en plus des méthodes LoadNextLevel() et LoadWaitScreen(). Les paramètres du niveau seront stockés dans un dictionnaire <string, object>. Pour des raisons de performance, si vous êtes sur de n’avoir à passer que des messages de type string entre vos niveaux, alors utilisez plutôt un dictionnaire <string, string>.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class LevelManager
{
    	private static Dictionary<string, object> _parameters = new Dictionary<string, object>();
	    public static object GetParameter(string key)
	    {
       		if (_parameters.ContainsKey(key))
			           return _parameters[key];
       		return null;
    	}

    	public static void SetParameter(string key, object value)
    	{
		        if (_parameters.ContainsKey(key))
            			_parameters[key] = value;
        		else
			           _parameters.Add(key, value);
    	}

	    public static void ClearParameters()
	    {
        		_parameters.Clear();
    	}

    	public static void LoadLevel(string level)
    	{
		        LoadLevel(level, null);
	    }

	    public static void LoadLevel(string level, Dictionary<string, object> params)
	    {
        if (params != null)
			            _parameters = params;
        		Application.LoadLevel(level);
	    }
}

Voilà donc l’implémentation basique du gestionnaire, désormais au lieu de charger un niveau avec la méthode Application.LoadLevel() vous utiliserez ce gestionnaire en passant avant les paramètres que vous voulez utiliser sur la scène suivante. Prenons un exemple relativement simple. Vous avez un niveau (une scène donc) qui peut être joué en mode Arcade ou Time Attack, par défaut c’est le mode Arcade qui est utilisé. Comment faire pour indiquer à la scène que vous voulez lancer le mode Time Attack ? Rien de plus simple avec le gestionnaire que nous avons écrit.

Dans le menu par exemple vous allez appeler votre niveau de jeu de la manière suivante :

void Update()
{
    if (Input.GetKeyDown(KeyCode.Enter))
    {
         LevelManager.SetParameter("LevelType", "TimeAttack");
         // Vous lancez le niveau 1
         LevelManager.LoadLevel("Level1");
    }
}

Ensuite dans votre code gérant votre niveau 1 vous devez avoir un script d’initialisation, rendez vous dedans et récupérez simplement les paramètres que vous avez indiquer juste avant.

public enum LevelType
{
    Arcade = 0, TimeAttack
}

private LevelType _levelType;

void Start()
{
    if (LevelManager.GetParameter("LevelType") == "Arcade")
        _levelType = LevelType.Arcade;
    else
        _levelType = LevelType.TimeAttack;
}

Et le tour est joué ! On a passé des paramètres facilement d’une scène à une autre. Vous pouvez enrichir ce gestionnaire avec des variables supplémentaires comme une collection de niveaux à charger, etc…