Indholdsfortegnelse
Resources i Inventory
I et RPG skal spilleren kunne samle våben, potions og armor op og beholde dem, når spilleren skifter scene.
Vi løser det ved at oprette en global `InventoryManager` som Autoload. Den eksisterer, så længe spillet kører, og kan tilgås fra alle scener.
1. Opret InventoryManager
Opret et C#-script med navnet `InventoryManager.cs`.
using Godot; using Godot.Collections; public partial class InventoryManager : Node { public Array<Item> Items { get; private set; } = new(); public void AddItem(Item item) { if (item == null) return; Items.Add(item); GD.Print($"Samlede op: {item.Name}"); } }
Hvad sker der?
- `Array<Item>` indeholder spillerens items.
- `AddItem()` tilføjer et item til inventory.
- `InventoryManager` indeholder kun data og logik for inventory – ikke selve brugergrænsefladen.
Bemærk, at `Item` er den fælles Resource-klasse fra den foregående øvelse. Både `WeaponItem` og `PotionItem` kan derfor tilføjes.
2. Gør InventoryManager global
For at inventory overlever sceneskift, skal `InventoryManager` oprettes som en Autoload.
- Åbn Project → Project Settings → Globals → Autoload. Menunavnet kan variere lidt mellem Godot-versioner.
- Vælg filen `InventoryManager.cs`.
- Angiv navnet `InventoryManager`.
- Aktivér Autoload. (markér checkbox 'Enabled')
Godot opretter nu en global instans af `InventoryManager`, som ikke bliver fjernet, når en almindelig scene skiftes ud.
Du kan tilgå den fra C# med:
GetNode<InventoryManager>("/root/InventoryManager");
3. Opret ItemPickup
Opret et script med navnet `ItemPickup.cs`. Det sættes på en `Area2D`, som spilleren kan gå ind i for at samle et item op.
using Godot; public partial class ItemPickup : Area2D { [Export] public Item Data { get; set; } public override void _Ready() { _sprite = GetNode<Sprite2D>("Sprite2D"); if (item != null) { _sprite.Texture = item.Icon; } BodyEntered += OnBodyEntered; } private void OnBodyEntered(Node2D other) { if (other is Player) { var inventory = GetNode<InventoryManager>("/root/InventoryManager"); inventory.AddItem(Data); QueueFree(); } } }
Bemærk: `Player` skal svare til navnet på jeres spillers C#-klasse.
4. Opsæt pickup-scenen
Opret følgende nodestruktur:
ItemPickup (Area2D) ├── Sprite2D └── CollisionShape2D
- Tilføj `ItemPickup.cs` til `Area2D`.
- Opret en `CollisionShape2D`, der dækker det område, spilleren skal ramme.
- Sørg for, at `Area2D` har `Monitoring` aktiveret.
- Forbind signalet `body_entered` til metoden `OnBodyEntered`.
- Tildel en konkret `Item`-resource til egenskaben `Data` i Inspector.
Du kan nu genbruge samme pickup-scene til eksempelvis `Sword.tres`, `HealthPotion.tres` og `IronArmor.tres`.
5. Test sceneskift
- Start spillet i en scene med et item.
- Gå hen til item'et, og saml det op.
- Skift til en anden scene.
- Undersøg `InventoryManager.Items`, eller udskriv indholdet i Output.
Tilføj eventuelt denne metode til `InventoryManager` for at teste indholdet:
public void PrintItems() { foreach (Item item in Items) { GD.Print(item.Name); } }
Kald metoden fra et passende sted i spillet, når du vil kontrollere inventory.
6. Hvorfor virker det?
En almindelig scene bliver fjernet, når spillet skifter til en anden scene. En Autoload-instans lever derimod videre, mens spillet kører.
Inventory ligger derfor ikke i den scene, spilleren forlader, men i en global instans.
Opgave
- Opret en `HealthPotion.tres` baseret på `PotionItem`.
- Placér en potion i én scene og et sværd i en anden.
- Saml begge items op.
- Skift mellem scenerne, og kontrollér, at inventory stadig indeholder begge items.
- Forklar, hvorfor `InventoryManager` skal være en Autoload, og hvorfor det er praktisk at lade inventory indeholde `Item` i stedet for kun `WeaponItem`.
Opsummering
- `Item` er basisklassen for alle items.
- `InventoryManager` holder styr på spillerens items.
- Autoload gør inventory tilgængeligt fra alle scener og bevarer det under sceneskift.
- Et save/load-system er nødvendigt, hvis inventory også skal overleve, at spillet lukkes.
