Forum rules - please read before posting.

Energy Refill

Hello, may be you can help me with advice how to make an energy counter refill (+1 each minute till 100 max) even when the game is switched off (for mobile 3d). Thank you

Comments

  • You can create a global Float variable to represent the Energy, and then display it in a Slider element.

    A background ActionList asset can be made to increase its value over time. Begin with an Engine: Wait Action of 60 (seconds), and then run a Variable: Check Action to check if the Energy is less than 100. If it is, run a Variable: Set Action that uses the Increase By Value method to increase the Energy variable. Then loop back to the first Action to re-run it.

    To have the value be retained upon restarting the app, set the variable's Link to field to Options Data, which will cause its value to be stored as part of the profile, and not any individual save game.

    To have the variable appear to increase even when the game is off, you'll need to record the current time as a Global Integer Variable (also linked to Options Data), and then have a custom script check the difference on startup and add it to the Energy variable.

    Something along these lines should do it:

    using System;
    using UnityEngine;
    using AC;
    
    public class EnergyTimeCalculator : MonoBehaviour
    {
    
        public string energyVariableName = "Energy";
        public string timeVariableName = "Time";
        private bool hasInitialised;
    
        void OnEnable ()
        {
            EventManager.OnInitialiseScene += OnInitialiseScene;
            EventManager.OnVariableChange += OnVariableChange;
        }
    
        void OnDisable ()
        {
            EventManager.OnInitialiseScene -= OnInitialiseScene;
            EventManager.OnVariableChange -= OnVariableChange;
        }
    
        void OnVariableChange (GVar variable)
        {
            if (hasInitialised && variable.label == energyVariableName)
            {
                var currentTime = (int) (DateTime.Now.Subtract (new DateTime (1970, 1, 1))).TotalSeconds;
                GlobalVariables.GetVariable (timeVariableName).IntegerValue = currentTime;
            }
        }
    
        void OnInitialiseScene ()
        {
            var energyVariable = GlobalVariables.GetVariable (energyVariableName);
            var timeVariable = GlobalVariables.GetVariable (timeVariableName);
    
            var lastTime = timeVariable.IntegerValue;
            var currentTime = (int) (DateTime.Now.Subtract (new DateTime (1970, 1, 1))).TotalSeconds;
            int difference = currentTime - lastTime;
    
            int energyValue = energyVariable.IntegerValue;
            energyValue = Mathf.Clamp (energyValue + difference, 0, 100);
            energyVariable.IntegerValue = energyValue;
    
            timeVariable.IntegerValue = currentTime;
            hasInitialised = true;
        }
    
    }
    
  • Good afternoon. Now I have a script in the game, which is connected to an empty object on each stage, which saves the time of player's exit and after entering restores energy to the required number of idle units. There also runs Action List (through the script), which checks the energy in the game and if it is less than 100 it also does the same thing once a minute.

    All works correctly while the game is on, when I turn off and restart, then on one scene works correctly (there is no loading saves on it), and on the next rolls back restored to the value that was before leaving the game.

    The energy variable is connected to Option data. Variable values are loaded separately on stage 0. In the one where it does not work is loading autosave everything except variables.
    how do I fix this error?

    My Script
    using System;
    using UnityEngine;
    using AC;

    public class EnergyRestorer : MonoBehaviour
    {
    public string energyVariableName = "Energy"; // Имя переменной для энергии
    public string timeVariableName = "Time"; // Имя переменной для времени
    public ActionListAsset actionListToRun; // ActionList, который нужно запустить
    private int maxRestoreEnergy = 100; // Максимальное количество энергии, которое можно восстановить
    private bool hasInitialised = false;

    void OnEnable()
    {
        EventManager.OnInitialiseScene += OnInitialiseScene;
        EventManager.OnVariableChange += OnVariableChange;
    }
    
    void OnDisable()
    {
        EventManager.OnInitialiseScene -= OnInitialiseScene;
        EventManager.OnVariableChange -= OnVariableChange;
    }
    
    void Start()
    {
        InitialiseVariables();
    }
    
    void InitialiseVariables()
    {
        var energyVariable = GlobalVariables.GetVariable(energyVariableName);
        var timeVariable = GlobalVariables.GetVariable(timeVariableName);
    
        if (energyVariable == null || timeVariable == null)
        {
            Debug.LogError("Переменные не загружены!");
            return;
        }
    
        var lastTime = timeVariable.IntegerValue;
        var currentTime = (int)(DateTime.Now.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
    
        if (lastTime == 0)
        {
            timeVariable.IntegerValue = currentTime;
            lastTime = currentTime;
        }
    
        int difference = currentTime - lastTime;
        int restoredEnergy = difference / 60; // Количество энергии, восстановленное за время отсутствия игрока
    
        int energyValue = energyVariable.IntegerValue;
    
        // Восстановление энергии, но только до максимума 100 за время отсутствия
        if (energyValue < maxRestoreEnergy)
        {
            energyValue = Mathf.Min(energyValue + restoredEnergy, maxRestoreEnergy);
        }
    
        // Обновляем значение энергии в глобальной переменной
        energyVariable.IntegerValue = energyValue;
    
        // Обновляем текущее время
        timeVariable.IntegerValue = currentTime;
        hasInitialised = true;
    
        // Запуск ActionList один раз
        if (actionListToRun != null)
        {
            Debug.Log("Запуск ActionList: " + actionListToRun.name);
            actionListToRun.Interact();
        }
    }
    
    void OnVariableChange(GVar variable)
    {
        if (hasInitialised && variable.label == energyVariableName)
        {
            var currentTime = (int)(DateTime.Now.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
            GlobalVariables.GetVariable(timeVariableName).IntegerValue = currentTime;
        }
    }
    
    void OnInitialiseScene()
    {
        InitialiseVariables();
    }
    

    }

    Ot how to realise it somehow in another way.

  • What was the result of the stripped-down script I shared above? Share a full-screen screenshot of where/how the script is attached to your scene.

  • I've got he following game structure:
    0 - loading screen
    1 - TitleScene with play-button (here the variables are loaded)
    2. Levels-Menu (checking variables and show the open/closed levels)
    3. 3+ - game lelel ( - 20 energy to start the level)

    • I've created an empty object and attached your script(on the 2 (menu) scene);
    • then - global variables linked to Option Data // Time and Energy
    • made Action List with energycheck (run in background) which runs onStart Cutscene of the menu-scene(2)// checked "survive scene change" in Inspector

    Action List with Check Energy/ if less 100 +1 and loop

    But it works only when I run the scene for the first time - the second and more it doesn't work (the debug windows show)
    And the numbers are incorrect - it may add 5 energy in a second then goes back to saves
    And I don't know why - all my menus started to stay between scenes... Though nothing has changed except this energy additions. The even stay if I try to turn the off via action list

  • The problems are somehow connected to the process of loading from save. Because the Action List dosen't run when enter location for the second and more time

  • It might be worth splitting it into two scripts - one with the InitialiseVariables function, another with OnVariableChange. Have one with the former be in the first AC scene of the game (so that InitialiseVariables is only run once), and have the other be in your other scenes.

    Don't have an OnStart cutscene survive scene changes. Instead, move the Actions to an ActionList asset, and use the Events Editor to run it whenever you begin the scene (via the "Scene / Change / After" event). This will cause it to run whenever a new scene begins, regardless of whether you load a save-game or not.

  • That works and the Action list stays after scene change, the energy changes correctly,
    but the new number of energy isn't saved on changing the scene back-forward to the menu. Though the energy variable is linked to option data

  • You'll need to provide screenshots - I don't follow your meaning.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.