GameSaveViewList<TSaveData, TSaveMetadata> renders the slot list for the GameSave system — load / overwrite / delete buttons, autosave/manual filter toggles, gamepad-friendly InputPrompts, and a ChoicePopup for confirmations. Subclass it for your save types and provide two slot-content slots (SlotOne, SlotTwo) per row.

The component requires both a UIDocument and a GameSaveView on the same GameObject ([RequireComponent] enforces this). The UXML must contain the named elements the abstract class queries:
| Element | Name | Purpose |
|---|---|---|
Button | NewSave | Create a new save slot. |
Toggle | ShowAuto | Filter: include autosaves. |
Toggle | ShowManual | Filter: include manual saves. |
InputPrompt | Load | Load selected slot. |
InputPrompt | Overwrite | Overwrite selected slot. |
InputPrompt | Delete | Delete selected slot. |
ListView | LoadList | Slot list. Items rendered from _listEntryTemplate. |
Also serialize a VisualTreeAsset _listEntryTemplate — Luna instantiates it per row and your SlotOne/SlotTwo overrides populate it.
namespace CupkekGames.Systems.UI;
[RequireComponent(typeof(UIDocument))]
[RequireComponent(typeof(GameSaveView))]
public abstract class GameSaveViewList<TSaveData, TSaveMetadata> : MonoBehaviour
where TSaveData : IGameSaveData, IData, new()
where TSaveMetadata : GameSaveMetadata| Method | Description |
|---|---|
GetSaveManager() | Return your GameSaveManager<TSaveData, TSaveMetadata> instance. |
IsInGame() | Return true if a save can be written from here. Disables NewSave/Overwrite when false. |
SlotOne(int index, GameSaveMetadataWithSlot<TSaveMetadata> metadata) | Build the left-hand row content. |
SlotTwo(int index, GameSaveMetadataWithSlot<TSaveMetadata> metadata) | Build the right-hand row content. |
OnLoadButtonClicked() | Load the selected slot. Use GetSelectedMetadata() to read the row. |
GetTooltipController() | Return the scene's TooltipController (used for delete/overwrite confirmation tooltips). |
| Property | Type | Description |
|---|---|---|
GameSaveManager | GameSaveManager<TSaveData, TSaveMetadata> | Resolved during Awake(). |
GameSaveView | GameSaveView | The sibling view component on the same GameObject. |
using UnityEngine.UIElements;
using UnityEngine;
using CupkekGames.Systems.UI;
using CupkekGames.Systems;
using System;
namespace CupkekGames.Luna.Demo.Game.Full
{
public class GameSaveViewListExample : GameSaveViewList<GameFullSaveData, GameFullSaveMetadata>
{
protected override GameSaveManager<GameFullSaveData, GameFullSaveMetadata> GetSaveManager()
=> ServiceLocator.Get<GameFullSaveManager>();
protected override bool IsInGame()
=> !SceneLoader.Instance.IsLoaded(1); // MainMenu scene index
protected override VisualElement SlotOne(int index, GameSaveMetadataWithSlot<GameFullSaveMetadata> meta)
{
VisualElement container = new();
container.AddToClassList("flex-row");
VisualElement left = new();
VisualElement right = new();
container.Add(left);
container.Add(right);
left.Add(new Label("Index: " + index));
left.Add(new Label("File: " + meta.SaveSlot));
right.Add(new Label(meta.Metadata.SaveDate.ToString()));
right.Add(new Label(meta.Metadata.IsAutosave ? "Autosave" : "Manual Save"));
container.Add(new Label("Save Version: " + meta.Metadata.SaveVersion));
return container;
}
protected override VisualElement SlotTwo(int index, GameSaveMetadataWithSlot<GameFullSaveMetadata> meta)
=> new Label("Gold: " + meta.Metadata.Gold);
protected override void OnLoadButtonClicked()
{
var meta = GetSelectedMetadata();
if (!meta.HasValue) return;
try
{
GameSaveManager.CurrentSave.Data = GameSaveManager.GetSave(meta.Value.SaveSlot);
}
catch (Exception e) { Debug.LogException(e, this); return; }
SceneLoader.Instance.LoadScene(2,
SceneTransitionDatabase.Instance.Transitions.GetValue("Fade"), true);
GameSaveView.ReturnClicked(); // unload prefab
}
protected override TooltipController GetTooltipController()
=> TooltipDatabaseExample.Instance.TooltipController;
}
}Settings
Theme
Light
Contrast
Material
Dark
Dim
Material Dark
System
Sidebar(Light & Contrast only)
Font Family
DM Sans
Wix
Inclusive Sans
AR One Sans
Direction