Créer une lampe à interrupteur

Light_bulb

Dans un jeu, la lumière c’est très important. Peu importe le nombre de polygones que vous utiliserez pour vos modèles et décors, si la lumière est mauvaise ou mal gérée, votre scène n’aura pas ce petit quelque chose qui fait dire « woa ».

Exemple d’une scène sans, et avec une gestion des lumières :

sans_lumiere
Scène sans lumière
avec_lumiere
Scène avec lumière + textures Specular

Convaincu du bien fondé de mes arguments ? Parfait. Maintenant, attaquons.

Pour ce tutoriel, commençons à traiter de la lumière avec un élément d’interaction simple : un interrupteur… qui allume un plafonnier ou une lampe quelconque. Une fois le fonctionnement mis en place il vous sera facile de l’adapter à toutes les sources de lumière que vous voulez !

Disclaimer

Cet article a été originalement écrit le 18/04/2014 sur mon précédent blog. Certaines informations présentées ici peuvent donc ne plus fonctionner telles quelles.

Mise en place

Démarrons notre mise en scène. L’idée est d’avoir une scène volontairement sombre, pour que le joueur soit amené à allumer la lumière. Principe simple, qui peut amener différents éléments de gameplay, surprise, etc.

l faut donc commencer par régler l’occlusion ambiante sur une couleur assez sombre. Ainsi l’éclairage global de la scène sera faible et donnera du sens aux lampes qu’il faudra allumer ! Pour se faire, il faut aller dans :

Edit > Render Settings

… et régler la couleur Ambiant Light sur quelque chose de foncé, ce qui est le cas par défaut :

renderSettings

Voilà pour le réglage de la scène. Encore une fois, restons simple. Un pseudo plafond, et un bouton (mis en évidence en bleu) pour l’activer. Utilisez une lumière de type SpotLight et orientez là comme bon vous semble. Notez que vous pouvez utiliser d’autres types de lumière pour ce tutoriel.

scene

 

Création de l’interrupteur

C’est là que ça devient intéressant : lions tout ça ensemble ! Nous allons avoir besoin d’un seul script. Oui, un seul !

public class LightSwitch : MonoBehaviour
{
    public GameObject Light;

    private bool _state;

    void Start ()
    {
        _state = true; // ON state by default
    }
 
    void Update ()
    {
 
    }
}

Voilà la base de notre script. Un GameObject exposé qui sera notre source lumineuse, et un drapeau d’état interne pour gérer le ON / OFF. Passons à l’activation / désactivation de l’interrupteur. Partons sur un fonctionnement simple : le joueur (en vue FPS) devra cliquer sur le bouton pour allumer la lumière. Mais il ne pourra l’activer que s’il est à côté. Question de réalisme ! Il nous faut donc détecter la présente du joueur à proximité du bouton. On va donc utiliser un SphereCollider en mode Trigger. Ajoutez ce composant à votre bouton pour avoir une sphère de détection pas trop grande, mais pas trop petite non plus :

collider

Dans le script nous avons maintenant le moyen de détecter le joueur. On va ajouter les méthodes OnTriggerEnter et OnTriggerExit qui vont mettre à jour un drapeau de présente du joueur à proximité :

public class LightSwitch : MonoBehaviour
{
    public GameObject Light;

    private bool _state;
    private bool _playerIsNear;

    void Start ()
    {
        _state = true; // ON state by default
        _playerIsNear = false;
    }
 
    void Update ()
    {
 
    }

    void OnTriggerEnter(Collider collider)
    {
        _playerIsNear = true;
    }

    void OnTriggerExit(Collider collider)
    {
        _playerIsNear = false;
    }
}

Hop. Nous voilà en mesure de détecter si le joueur est à côté du bouton… ou non ! Il faut maintenant détecter le clic du joueur dans le cas où il est à proximité. Pour se faire on va utiliser un rayon. C’est pas évident à utiliser au début, mais ça fait très bien son travail ! Dans la méthode Update, rajoutez donc ce code :

if (_playerIsNear)
{
    var rayHit = new RaycastHit();
    var screenCenter = new Vector3(Screen.width / 2, Screen.height / 2);
    Ray ray = Camera.main.ScreenPointToRay(screenCenter);
    Physics.Raycast(ray, out rayHit, 1000);

    if (Input.GetMouseButton(0))
    {
        if (rayHit.collider != null && rayHit.collider.gameObject.GetComponent<lightswitch>() != null)
        {
            // Trigger the switch
            _state = !_state;
        }
    }
}

Si le joueur est proche du bouton, qu’il clique et que la souris est sur le bouton, on change l’état du bouton. Simple non ? Dans ce cas de figure, on part du principe que la souris est bloquée au centre de l’écran. On pourrait également passer directement par Input.mousePosition pour avoir cette valeur, ce qui revient ici au même.

Le travail est presque terminé, il nous faut maintenant brancher la lumière sur ce bouton. Dans l’éditeur, affectez la source de lumière créée plus haut en paramètre de ce script dans Light. Ensuite, activez / désactivez le GameObject en fonction de l’état. Quelque chose comme ça :

Light.SetActive(_state);

Voilà le script complet :

public class LightSwitch : MonoBehaviour
{
    public GameObject Light;

    private bool _state;
    private bool _playerIsNear;

    void Start ()
    {
        _state = true; // ON state by default
        _playerIsNear = false;
    }
 
    void Update ()
    {
        if (_playerIsNear)
        {
            var rayHit = new RaycastHit();
            var screenCenter = new Vector3(Screen.width / 2, Screen.height / 2);
            Ray ray = Camera.main.ScreenPointToRay(screenCenter);
            Physics.Raycast(ray, out rayHit, 1000);

            if (Input.GetMouseButton(0) || InputUpdater.CurrentDevice.Action2.WasPressed)
            {
                if (rayHit.collider != null && rayHit.collider.gameObject.GetComponent<lightswitch>() != null)
                {
                
                    // Trigger the switch
                    _state = !_state;

                    Light.SetActive(_state);
                }
            }
        }
    }

    void OnTriggerEnter(Collider collider)
    {
        _playerIsNear = true;
    }

    void OnTriggerExit(Collider collider)
    {
        _playerIsNear = false;
    }
}

Il ne vous reste plus qu’à habiller votre lampe, votre bouton… et en mettre partout dans vos niveaux !

Crédits image : Wikimedia

Advertisements

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s