Bonjour,
j'ai fait
ceci (vidéo), je ne sais pas si c'est ce dont tu as besoin. Les scripts sont bien sûr perfectibles, notamment l'affichage mériterait l'utilisation de délégués.
Sur la vidéo, il y a 2 types d'objectif, clé rouge ou clé bleu. C'est extensible grâce à ce script :
► Afficher le texte
Code : Tout sélectionner
public class Objectives
{
public enum ObjectiveType { redKey, blueKey }
}
Un objectif est un gameObject avec un Collider en mode trigger et un script, qui permet de choisir le type d'objectif et la couleur de l'objectif (ne sert strictement à rien mais c'est joli
) :
► Afficher le texte
Code : Tout sélectionner
using UnityEngine;
public class Objective : MonoBehaviour
{
[SerializeField] private Objectives.ObjectiveType family;
[SerializeField] private Color colorObjective;
private void Awake ()
{
GetComponent<Renderer> ().material.color = colorObjective;
}
public Objectives.ObjectiveType GetObjectiveType () => family;
}
La zone de collecte est également un gameObject, avec un collider en mode trigger et un script. On paramètre le type d'objectif à collecter, la couleur de la zone (le matériel est en mode transparent) et les deux champs texte de l'UI. On pourrait y ajouter le nombre d'objectifs à déposer pour déclencher quelque chose (victoire, changement de niveau, son, ...), ou réactiver les objectifs en les déplaçant dans la zone :
► Afficher le texte
Code : Tout sélectionner
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class CollectZone : MonoBehaviour
{
[SerializeField] private Objectives.ObjectiveType zoneObjective;
[SerializeField] private Color colorZone;
[SerializeField] private TMP_Text zoneObjectivesNumber;
[SerializeField] private TMP_Text playerObjectivesNumber;
private List<GameObject> zoneCollectedObjectives = new List<GameObject> ();
private void Awake ()
{
GetComponent<Renderer> ().material.color = colorZone;
zoneObjectivesNumber.text = "En zone 0";
}
private void OnTriggerEnter (Collider _collider)
{
// Si le joueur pénètre dans la zone, on regarde s'il possède des objectifs à collecter.
if (_collider.CompareTag ("Player"))
{
PlayerObjectives player = _collider.GetComponent<PlayerObjectives> ();
if (player != null)
{
List<GameObject> playerCollectedObjectives = player.GetCollectedObjectives ();
// Ajoute à la liste de la zone les objectifs requis par la zone.
foreach (GameObject item in playerCollectedObjectives)
{
if (item.GetComponent<Objective> ().GetObjectiveType () == zoneObjective)
{
zoneCollectedObjectives.Add (item);
zoneObjectivesNumber.text = $"En zone {playerCollectedObjectives.Count.ToString ()}";
}
}
// Supprime de la liste du joueur les objectifs déposés dans la zone.
foreach (GameObject item in zoneCollectedObjectives)
{
playerCollectedObjectives.Remove (item);
}
playerObjectivesNumber.text = $"Joueur {player.GetCollectedObjectives ().Count.ToString ()}";
}
}
}
}
Le joueur a un script de mouvement classique et un script pour collecter les objectifs. Il possède également un rigidbody (ne pas oublier les contraintes Freeze Rotation sur X et Z) et un collider en mode collision.
► Afficher le texte
Code : Tout sélectionner
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class PlayerObjectives : MonoBehaviour
{
[SerializeField] private TMP_Text playerObjectivesNumber;
private List<GameObject> objectives = new List<GameObject> ();
private void Awake ()
{
playerObjectivesNumber.text = $"Joueur 0";
}
private void OnTriggerEnter (Collider _collider)
{
// Si l'objet touché est un objectif, on le collecte.
Objective objective = _collider.GetComponent<Objective> ();
if (objective != null)
{
objectives.Add (objective.gameObject);
objective.gameObject.SetActive (false);
playerObjectivesNumber.text = $"Joueur {objectives.Count.ToString ()}";
}
}
public List<GameObject> GetCollectedObjectives () => objectives;
}