Créer un système de détection d'item sur Unity
Pourquoi ce projet ? La réalisation de ce projet a pour but d’apprendre et expérimenter le C# sous Unity. Je voulais comprendre l’héritage …
Lire l'articlePour mon système d’inventaire, je ne savais pas trop où commencer. Je savais juste qu’il fallait récupérer les informations des items ramassés, puis de les trier.
J’ai conçu ce petit croquis de ce que cela pourrait donner :
Après avoir conçu mon chef-d’œuvre, je me suis lancée petit à petit dans mon inventaire.
Suite à la conception du système de détection en parallèle, je prévois mon système d’inventaire. Pour cela, je commence par créer des items puis je les catégorises. C’est à ce moment-là que je comprends le principe de l’héritage !
Je vous montre ça ! L’héritage est comme un arbre généalogique ou encore un arbre technologique. Le script mère va être la base de tous ses enfants, ces derniers vont tous hériter du script mère.
Petit exemple : un véhicule, ça peut aussi bien être une voiture qu’un avion. Et pourtant ce n’est pas la même chose. Mais tous les deux sont des véhicules. Une voiture va hériter de véhicule tout comme un avion.
Les items, c’est la même chose. Mon script Item va être une abstract ce qui signifie comme quoi, on ne peut pas avoir d’objet Item, car c’est Abstrait. Item sera mon script mère de tous les enfants héritant d’Item
Ces enfants auront : Un nom / une description / un nombre d’item / un nombre maximum stockable dans l’inventaire / une image / une fonction DropItem()
.
public abstract class Item : MonoBehaviour
{
public string name;
public string description;
public int amount;
public int amountStockableMax;
public Sprite icon;
public virtual void DropItem()
{
Debug.Log("Drop mon item");
}
}
La magie arrive ! Chaque class est un enfant du script Item, mais chacun à ses propres fonctionnalités. Une potion peut s’utiliser alors qu’une arme peut s’équiper.
public abstract class Ressource : Item
{
}
public abstract class Potion : Item
{
public virtual void Use()
{
Debug.Log("Je bois une potion");
}
}
public abstract class Weapon : Item
{
int damage;
public int strength { private get; set; }
public int get_damage() { return damage; }
public virtual void Equip()
{
Debug.Log($"Tu as équipé une arme");
}
}
public abstract class Equipement : Item
{
public virtual void Equip()
{
Debug.Log("Je suis entrain de m'équiper");
}
}
Le virtual permet de réécrire la méthode dans un script enfant de celui-ci.
Une fois que j’ai fini avec les items, j’ai conçu des slots comportant un script “InventoryItem” Ce script, que va-t-il faire ?
// Nombre d'items dans le slot
[SerializeField] private int amountItem;
// Image de l'item affiché
[SerializeField] private Image itemImg;
// Texte d'affichage du nombre d'item
[SerializeField] private TextMeshProUGUI itemNumberTxt;
// Type d'item
[SerializeField] private Item item;
Ce script permet juste de stoker et de renvoyer les données qu’ils contiennent à “Inventory”.
Je vais vous expliquer ce que fait le script “Inventory”.
Ce script s’occupe de la gestion de l’ensemble de l’inventaire. Il va trier et gérer les items dans les différents slots “inventoryItem”.
Je vous mets un petit croquis :
Ce qui est en violet représente le bois que nous ramassons, le script “Inventory” va se charger de récupérer les informations qu’on lui donne à propos de l’item ramassé. représenté en Vert et en Rouge).
Le système sait qu’il peut mettre 100 items maximum dans un slot avec cette ressource. Or cette dernière comporte 225 bois.
Il va procéder à une soustraction pour chaque slot jusqu’à qu’il ne possède plus d’item :
Item = 225
(Nombre d’item ramassés)
Extra = Item - (NbItemMax - Slot.ItemAmount) = 225 - (100 - 0)
{
// 75 - (100 - 75) = 50
// On soustrait le nombre d'item que nous avons récupérés avec le nombre maximum de stockage de ce dernier puis avec le nombre d'item que possède le slot où nous souhaitons le ranger.
extraItem = _item.amount - (_item.amountStockableMax - _inventoryItem.GetAmountItem());
Debug.Log("extraItem : " + extraItem);
// Si nous ne possédons plus d'item alors nous ajoutons le reste et il n'y a pas/plus d'extra d'item
if(extraItem <= 0)
{
_inventoryItem.AddItem(_item.icon,_item.amount);
extraItem = 0;
}
// Si nous avons un extra alors nous ajoutons le nombre d'item ramassés soustrait par l'extra.
// Puis nous déposons le nombre d'extra dans l'item correspondant.
// Ensuite, nous recommençons à chercher un autre slot avec RangeItem()
if (extraItem > 0)
{
// 75 - 50 = 25
_inventoryItem.AddItem(_item.icon,_item.amount - extraItem);
_item.amount = extraItem;
RangeItem(_item);
}
}
La méthode RangeItem()
sert à ranger les items dans la liste de Slots tout en faisant des vérifications.
public void RangeItem(Item _item)
{
foreach (var myInventoryItem in inventoryItems)
{
Debug.Log($"On récupere un item dans l'inventaire ");
if (myInventoryItem.GetItem() != null &&
myInventoryItem.GetAmountItem() != _item.amountStockableMax &&
myInventoryItem.GetItem().name == _item.name)
{
Debug.Log("Ajout d'un item deja existant !");
//myInventoryItem.AddItem(_item.icon,_item.amount);
VerificationAmountItem(myInventoryItem, _item);
break;
}
if (myInventoryItem.GetItem() == null)
{
Debug.Log("Nouvel item !" + _item);
myInventoryItem.SetItem(_item);
//myInventoryItem.AddItem(_item.icon,_item.amount);
VerificationAmountItem(myInventoryItem, _item);
return;
}
}
}
J’ai passé énormément de temps dessus, j’ai dû recommencer plusieurs fois le code et son architecture. Maintenant, je suis très satisfait du résultat.
Ensuite, je vais vous montrer comment fonctionne le système de choix sur les Items. Chaque Slot va contenir “InventoryItemUI” qui contient les panels d’affichage et qui se charge de les placer. Les panneaux d’affichage vont s’actionner lorsque le joueur passe dessus. La description et le panel de choix s’ouvre lorsqu’il clique.
OnPointerEnter et OnPointerDown
Pour afficher les bonnes actions, il faut vérifier l’item et pour cela, j’ai fais “ChoiceActionItem” se chargeant de regarder le slot que j’ai cliqué (grâce au InventoryItemUI).
J’ai longuement réfléchi sur comment j’allais mettre en place un système de vérification le plus logique par rapport à mon système. Une armée de “if” ne serait pas l’ideal ! Donc pour cela, j’ai utilisé les Switch pour regarder de quel type était l’Item dans le Slot correspondant.
void CheckType()
{
switch (item)
{
case Weapon weapon:
weapon.Equip();
Debug.Log($"Vous avez pris une arme !");
break;
case Ressource resource:
Debug.Log($"Vous avez pris une ressource !");
break;
case Equipement equipement:
equipement.Equip();
Debug.Log($"Vous avez pris une equipement !");
break;
case Potion potion:
potion.Use();
Debug.Log($"Vous avez pris une potion !");
break;
default:
Debug.Log($"Vous n'avez rien pris ...");
break;
}
}
Si l’Item est de tel type, alors, nous faisons telle action, c’est aussi simple que ça ! Bien sûr, avec ceci, j’ai dû paramétrer des boutons par rapport à leurs actions : Drop, Use, Equip etc…
Après cette belle aventure du rangement des Slots avec les actions allant avec, il fallait partir à la conquête du Drag And Drop et du Split des Items dans l’inventaire !
Pourquoi ce projet ? La réalisation de ce projet a pour but d’apprendre et expérimenter le C# sous Unity. Je voulais comprendre l’héritage …
Lire l'articleVous souhaitez afficher vos photos de manières originales sur votre site internet ? Voyons ensemble comment réaliser cet effet polaroid entièrement en …
Lire l'article