Apparently, a type of free-to-play mobile games, where player can spend points to continue reading a story are becoming popular.
This extension shows an example of a custom engine service, which tracks a global g_points
custom variable, reducing it each time a print command is executed. When points are equal or below zero, a notification is shown to the player, game is saved and title menu is shown. When player has enough points (eg, via an in-app purchase or some other game mechanic), they'll be able to load from the last quick save and continue reading.
Code: Select all
using Naninovel;
using Naninovel.Commands;
using Naninovel.UI;
using UniRx.Async;
[InitializeAtRuntime]
public class PointsManager : IEngineService
{
private IScriptPlayer scriptPlayer;
private ICustomVariableManager variableManager;
private IStateManager stateManager;
private IUIManager uiManager;
public UniTask InitializeServiceAsync ()
{
// Get references to the services we'll need later.
scriptPlayer = Engine.GetService<IScriptPlayer>();
variableManager = Engine.GetService<ICustomVariableManager>();
stateManager = Engine.GetService<IStateManager>();
uiManager = Engine.GetService<IUIManager>();
// Register our monitoring method to be invoked before a command is executed.
scriptPlayer.AddPreExecutionTask(HandleCommandExecuted);
return UniTask.CompletedTask;
}
public void ResetService () { }
public void DestroyService ()
{
// Un-register the monitoring method when the service is destroyed.
scriptPlayer?.RemovePreExecutionTask(HandleCommandExecuted);
}
private async UniTask HandleCommandExecuted (Command command)
{
// We care only about the print commands.
if (!(command is PrintText)) return;
// Get custom global variable that tracks the points.
// Don't forget to add it to the predefined variables configuration menu.
variableManager.TryGetVariableValue<int>("g_points", out var points);
if (points <= 0) // In case we're out of points:
{
// Notify the player and wait until they dismiss the notification.
var confirmationUI = uiManager.GetUI<IConfirmationUI>();
await confirmationUI.NotifyAsync("You're out of points and can't continue reading.");
// Save the game and return to the title menu.
await stateManager.QuickSaveAsync();
await new ExitToTitle().ExecuteAsync();
}
else // In case we have enough points:
{
// Consume one point and save the variable.
points -= 1;
variableManager.TrySetVariableValue("g_points", points);
}
}
}
To test the above code, just copy-paste it to a new C# script.
Don't forget to add g_points
to the predefined variables list and assign the initial value.
To track current value of the variable while playing, use var
console command: