Le cambouis - Finissons par un peu plus de vie (3/3)

UnityUnity 3Djeux videotutorialC#
Julien LAPA - 23/01/2023 à 11:35:540 commentaire

Est-ce du bruit que j’entends.

 

Pour plus de facilité, j’ai isolé les pistes audio du pack d’asset. Nous allons intégrer les pistes au bon moment du jeu.



Vous souvenez-vous du script de mort ? On lui a rajouter une AudioSource. L’AudioSource est le composant essentiel de l’ajout de son. On lui renseigne un clip qui pourrait être joué et il devient alors possible de le configurer. Est-ce qu’on doit le jouer dès le début ? Est-ce qu’il est muet pour le moment ? Quel est sa hauteur ?... C’est cette AudioSource que l’on va manipuler dans le script et jouer à la fin de la mort.


using UnityEngine;


public class DieLittleBird : MonoBehaviour {


	private Collider2D _collider;
	// Use this for initialization
	void Start () {
		_collider = GetComponent<Collider2D>();
	}
	
	void OnCollisionEnter2D(Collision2D collision)
    {
		if (collision.gameObject.tag == "Flappy")
        {
			collision.gameObject.SetActive(false);
			Time.timeScale = 0;
        }
    }
}



En y réfléchissant bien, pour que l’oiseau meure, il faut qu’il heurte quelque chose : le sol, ou un obstacle. Il faut donc ajouter une deuxième AudioSource avec le bruit d’une collision.


using UnityEngine;


public class DieLittleBird : MonoBehaviour {


	private Collider2D _collider;
	[SerializeField]
	private AudioSource _audioSourceDie, _audioSourceHit;
	// Use this for initialization
	void Start () {
		_collider = GetComponent<Collider2D>();
	}
	
	void OnCollisionEnter2D(Collision2D collision)
    {
		if (collision.gameObject.tag == "Flappy")
        {
			_audioSourceHit.Play();
			collision.gameObject.SetActive(false);
			Time.timeScale = 0;
			_audioSourceDie.Play();
        }
    }
}


Nous avons quelque chose de plutôt sympathique désormais.

Et si on ajoutait un retour quand l’utilisateur gagne un point ?



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


public class AddPoint : MonoBehaviour {


	private AudioSource _audioSource;
	void Start() { 
		_audioSource = GetComponent<AudioSource>();
	}
	void OnTriggerEnter2D(Collider2D other) 
	if(other.gameObject.tag == "Flappy")
        {
			_audioSource.Play();
			PointCount.Count++;
        }
	}
}


Parfait. Il ne nous manque plus qu’à ajouter du son lorsque le petit oiseau bat des ailes.



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


public class FlyLittleBird : MonoBehaviour
{


    [SerializeField]
    private float ForceIntensity;
    private AudioSource _audioSource;


    //private components and variables
    private Rigidbody2D _rb;


    void Start()
    {
        _rb = GetComponent<Rigidbody2D>();
        _audioSource = GetComponent<AudioSource>();
    }


    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            _audioSource.Play();
            _rb.velocity = Vector3.zero;
            _rb.AddForce(ForceIntensity * Vector3.up);
        }
    }
}


Ici les sons sont relativement simples. La démarche est donc toujours la même dans nos scripts mais il est possible d’avoir des musiques d’ambiance, etc. Ce qu’il faut bien garder à l’esprit, notamment dans les jeux 3D, c’est que les sons sont émis dans un point de l’espace et qu’ils ont une portée maximale.


Game Art


Il est désormais temps de rajouter quelques paysages et surtout un sol sur lequel peut s’écraser notre oiseau. Si vos différentes images se superposent mal, pensez à modifier leur profondeur pour une meilleur cohérence.



Nous avions créé un texte pour pouvoir afficher le score. Il est temps d’utiliser les graphismes à notre disposition pour que ce soit plus dans l’esprit Flappy Bird.



Au niveau de l’interface, j’ai changé le texte par 5 images, qui permettront d’atteindre en théorie un score de 99 999. Il se pourrait qu’un joueur aille au-delà, mais il est très peu probable que cela arrive et si c’est le cas, je pense qu’il serait bon pour lui de s’arrêter :-). Blague mise à part, voyons de quoi est composé ce script d’affichage de nombres.


using UnityEngine;
using UnityEngine.UI;


public class DisplayNumber : MonoBehaviour {
	[HideInInspector]
	public bool display;
	[HideInInspector]
	public string currentNumber;
	[SerializeField]
	private Sprite zero,one,two,three,four,five,six,seven,eight,nine;
	public Image _image;
	void Start () {
		_image = GetComponent<Image>();
	}
	
	// Update is called once per frame
	void Update () {
		_image.enabled = display;
        switch (currentNumber)
        {
			case "0":
				_image.sprite = zero;
				break;
			case "1":
				_image.sprite = one;
				break;
			case "2":
				_image.sprite = two;
				break;
			case "3":
				_image.sprite = three;
				break;
			case "4":
				_image.sprite = four;
				break;
			case "5":
				_image.sprite = five;
				break;
			case "6":
				_image.sprite = six;
				break;
			case "7":
				_image.sprite = seven;
				break;
			case "8":
				_image.sprite = eight;
				break;
			case "9":
				_image.sprite = nine;
				break;
		}
    }
}


Ce script va servir à afficher unitairement un nombre compris entre 0 et 9. Il va prendre en compte le nombre actuel que l’on souhaite afficher avec la petite subtilité d’avoir la possibilité de ne pas afficher un nombre. Cette possibilité réside surtout dans l’affichage où il serait peu utile d’afficher 00001 pour le score 1. Ainsi on décide quand une unité doit être affichée et ce qu’elle doit afficher.

 

Maintenant que chaque unité a la possibilité d’afficher un nombre quel qu’il soit, on va s’afférer à traiter le score actuel pour indiquer quelle est la valeur que doit afficher chaque unité.


using UnityEngine;


public class DisplayScore : MonoBehaviour
{
    [SerializeField]
    private DisplayNumber unit, decade, hundred, thousands, tensOfThousands;
    void Update()
    {
        string count = PointCount.Count.ToString();
        switch (count.Length)
        {
            case 1:
                unit.display = true;
                decade.display = false;
                hundred.display = false;
                thousands.display = false;
                tensOfThousands.display = false;
                unit.currentNumber = count[0].ToString();
                break;
            case 2:
                unit.display = true;
                decade.display = true;
                hundred.display = false;
                thousands.display = false;
                tensOfThousands.display = false;
                unit.currentNumber = count[1].ToString();
                decade.currentNumber = count[0].ToString();
                break;
            case 3:
                unit.display = true;
                decade.display = true;
                hundred.display = true;
                thousands.display = false;
                tensOfThousands.display = false;
                unit.currentNumber = count[2].ToString();
                decade.currentNumber = count[1].ToString();
                hundred.currentNumber = count[0].ToString();
                break;
            case 4:
                unit.display = true;
                decade.display = true;
                hundred.display = true;
                thousands.display = true;
                tensOfThousands.display = false;
                unit.currentNumber = count[3].ToString();
                decade.currentNumber = count[2].ToString();
                hundred.currentNumber = count[1].ToString();
                thousands.currentNumber = count[0].ToString();
                break;
            case 5:
                unit.display = true;
                decade.display = true;
                hundred.display = true;
                thousands.display = true;
                tensOfThousands.display = true;
                unit.currentNumber = count[4].ToString();
                decade.currentNumber = count[3].ToString();
                hundred.currentNumber = count[2].ToString();
                thousands.currentNumber = count[1].ToString();
                tensOfThousands.currentNumber = count[0].ToString();
                break;
        }
    }
}


Même si le script est assez volumineux et semble se répéter le fonctionnement est relativement simple : on calcul la taille du nombre pour connaitre le nombre de chiffres présents dans celui-ci et on affiche en fonction de la présence ou non d'un chiffre.


Pour finir...


En soit, le "jeu" n'est pas fini. Il resterait la possibilité d'ajouter des animation, des interfaces pour rejouer, afficher les scores des parties passées ou même innover en rajoutant des fonctionnalités. Cependant le but de cette série n'était pas de créer un jeu ou une application totalement, mais bien de présenter certains des composants natif d'Unity. Je vous invite à le poursuivre afin de continuer à prendre en main le moteur. Pour ceux qui seraient intéréssés d'en apprendre plus, n'hésitez pas à suivre les articles des dieux du code ;)


Commentaires :

Aucun commentaires pour le moment


Laissez un commentaire :

Réalisé par
Expaceo