====== Trin 6: Genbrug i en kiste ======
[[trin5_spiller|← Forrige: Vis spillerens inventory]] | [[start|Forside]] | [[trin7_opsamling|Næste: Opsamling og udvidelser →]]
Nu kommer belønningen for adskillelsen af data og UI: Du giver en kiste et inventory og viser det ved siden af spillerens, uden at skrive ny inventory-logik.
===== Opskriften på en ejer =====
Alt, hvad en ejer skal gøre, er:
- Have en ''Inventory''-node som barn.
- Have et script, der finder den og gør den tilgængelig.
- Have sine egne start-items og sit eget ''Slot Count'' i Inspector.
Spilleren gør netop det. Kisten gør det samme.
===== Opret Chest-scenen =====
- Opret en ny scene med **Node** som rod. Omdøb den til ''Chest''.
- Tilføj en ''Inventory''-node som barn, som du gjorde med spilleren.
- Gem som ''Scenes/Chest.tscn''.
- Markér ''Inventory'', og sæt **Start Items** til tre af dine items, helst nogle andre end spillerens.
Træet skal se sådan ud:
Chest (Node)
└── Inventory (Inventory)
Højreklik på ''Chest'', vælg **Attach Script**, og sæt stien til ''Scripts/Game/Chest.cs''. Erstat indholdet med:
using Godot;
// Kisten er en anden ejer af præcis samme Inventory-komponent.
public partial class Chest : Node
{
public Inventory Inventory { get; private set; }
public override void _Ready()
{
Inventory = GetNode("Inventory");
}
}
Koden er næsten identisk med ''Player.cs''. Det er helt i orden: En spiller og en kiste er to forskellige slags ejere, som senere kan få hver sin opførsel (spilleren kan bevæge sig, og kisten kan åbnes), mens inventory-delen er den samme. Hvis du vil undgå gentagelsen, kan du senere lave en fælles basisklasse. Det gør vi ikke her for at holde det enkelt.
===== Sæt kisten og et ekstra UI ind i Main =====
Åbn ''Main.tscn'':
- Træk ''Scenes/Chest.tscn'' ind på ''Main''. Den hedder nu ''Chest''.
- Træk ''Scenes/InventoryUI.tscn'' ind på ''HBoxContainer'', så den står ved siden af ''PlayerInventoryUI''. Omdøb den til ''ChestInventoryUI''.
- Højreklik på ''ChestInventoryUI'', og vælg **Access as Unique Name**.
Træet skal nu se sådan ud:
Main (Node)
├── Player (Player.tscn)
├── Chest (Chest.tscn)
└── UI (CanvasLayer)
└── CenterContainer
└── HBoxContainer
├── %PlayerInventoryUI (InventoryUI.tscn)
└── %ChestInventoryUI (InventoryUI.tscn)
Opdater ''Main.cs'':
using Godot;
// Main samler det hele: den fortæller hvert UI, hvilket inventory det skal vise.
public partial class Main : Node
{
public override void _Ready()
{
Player player = GetNode("Player");
Chest chest = GetNode("Chest");
// "%" finder en node med "Access as Unique Name", uanset hvor den ligger i scenen.
InventoryUI playerUi = GetNode("%PlayerInventoryUI");
InventoryUI chestUi = GetNode("%ChestInventoryUI");
// Samme UI-scene, to forskellige inventories.
playerUi.SetInventory(player.Inventory);
chestUi.SetInventory(chest.Inventory);
}
}
Der er ikke ændret noget i ''Inventory'', ''InventoryUI'' eller ''SlotUI''. Vi har kun tilføjet en ejer og en ekstra instans af den samme UI-scene.
===== Kør spillet =====
Tryk på **Build** og **Run Project** (''F5''). Du ser to 3x3 inventories ved siden af hinanden. Det venstre viser spillerens items, og det højre viser kistens.
===== Hvorfor virker det? =====
* ''Inventory'' ved ikke, hvem der ejer den. Den holder bare slots. Det er derfor, den kan sidde under både en spiller og en kiste.
* ''InventoryUI'' ved ikke, hvilket inventory den viser, før ''SetInventory'' kaldes. Hver instans får sin egen reference og sine egne slots.
* Alt, hvad der er forskelligt mellem spiller og kiste (indhold og antal slots), står i Inspector som data. Ingen kode skal ændres.
Skal en fjende, en butik eller en skuffe også have et inventory, gør du det samme: en node med en ''Inventory'' som barn, og et UI, der får inventoryet at vide.
===== Eksperimenter =====
* Sæt kistens **Slot Count** til 6. Kistens UI får 3 kolonner og 2 rækker, mens spillerens stadig er 3x3.
* Instantiér ''Chest.tscn'' en ekstra gang i ''Main'', og tænk over, hvad der skal til for at vise den. (Svar: endnu en ''InventoryUI'' og endnu et kald til ''SetInventory''.)
===== Tjekliste =====
* To inventories vises side om side med hvert sit indhold.
* Du ændrede ikke koden i ''Inventory'', ''InventoryUI'' eller ''SlotUI''.
[[trin7_opsamling|Næste: Opsamling og udvidelser →]]