Forum rules - please read before posting.

How does OnUpdate() Function work with Adventure Creator.

edited August 2020 in Technical Q&A

I've gotten a good hang of AC however I'm not quite sure on how the OnUpdate() would work with AC Editor.

I'm making a small 2D escape type of game that has a 24 hour ingame time that changes after every action the player does. For example once the time is 20:00, the player can't do certain things and cannot go to certain places. Also Certain things will show up at a certain time in the game.

So something like this would need to always keep running in the background to check for variables such as Time to ensure what the player can do and cannot do. So how would this work with the Actionlist Editor, is it the action you create under Scene Cutscenes (On start, On load, On variable change)?

I've tried creating an actionlist for "on variable change" but that doesn't seem to work.

Comments

  • edited August 2020

    I'm not sure what specifically you're referring to with OnUpdate - there's no function named such in AC.

    But if you're looking to keep track of time, it's best to do so with an AC Global Variable whose value is set through script. Looping ActionLists in the background is possible, but if you want to do something continuously it's best to rely on a script.

    You could, for example, use an Integer variable to keep track of the number of minutes that have elapsed in the day. Checking the time would then be a case of using a Variable: Check Action. Here, 20:00 would be equivalent to 60*20 = 1200, so you could determine if it's past 8pm by checking it the variable > 1200.

    Or, you could create two separate Integer variables: one for the hour, the other for the minutes in that hour. Through script, you could then have an internal timer going that updates these variable values every X seconds.

    See the Manual's "Variable scripting" chapter for a guide on updating variable values through scrip, but here's a sample script. Create two Integer global variables named Hours and Minutes, then attach this script to an empty GameObject in your scene:

    using UnityEngine;
    using AC;
    
    public class Timer : MonoBehaviour
    {
    
        private GVar hourVariable;
        private GVar minuteVariable;
        private float timer;
        [SerializeField] [Range (0.01f, 1f)] private float timeScaler = 1f;
    
    
        private void Start ()
        {
            hourVariable = GlobalVariables.GetVariable ("Hours");
            minuteVariable = GlobalVariables.GetVariable ("Minutes");
            timer = 60f * timeScaler;
        }
    
    
        private void Update ()
        {
            timer -= Time.deltaTime;
            if (timer <= 0f)
            {
                timer = 60f * timeScaler;
                minuteVariable.IntegerValue ++;
    
                if (minuteVariable.IntegerValue >= 60)
                {
                    hourVariable.IntegerValue ++;
                    minuteVariable.IntegerValue = 0;
    
                    if (hourVariable.IntegerValue >= 24)
                    {
                        hourVariable.IntegerValue = 0;
                    }
                }
            }
        }
    
    }
    

    Set the "Time Scaler" slider in its Inspector to control how fast time updates relative to the real world. It'll reset every 24 hours, but you could further update it to involve days of the week, months etc.

  • Sorry if I didn't explain it properly. I've already gotten the Time Formula to work and all and have it saved as Global variable "Time"(Float type). And some Debug buttons that add minutes, hours to that time etc for testing purposes which also work.

    What I wanted to know is that how can you run checks in the background, for example whenever the Time variable is 28800 or more (which in my formula is equal to 08:00) then disable/hide certain sprites in the scene.

    I want this to always run and keep checking the Time variable to hide/unhide objects in the scene based on what time it is. When I use the Actionlist Editor, that requires you to interact in some way in order to execute stuff, whereas I want the actionlist to always be executing in the background.

    I hope this is clearer, if not then ill try to explain in another way

  • edited August 2020

    And Sorry I mean't Update() not OnUpdate().

    Maybe the AC doesn't have a way to run an Update() like actionlist?

  • edited August 2020

    It's easy to do on AC! I have an actionlist that runs whenever a scene is loaded to (1) check the time variable and arrange all objects in my scene before fading in, and (2) launch a second actionlist that loops with a 1s wait in the beginning (to avoid unnecessary updates). This actionlist runs in the background and handles the transitions when they happen within the scene.

  • @Rairun I've done something like that as well but it doesn't seem to work still. I must be missing something. Once you create the actionlist where do you put it?

  • edited August 2020

    If you need to have an ActionList run in the background on a loop, attach an Action List Starter component to a GameObject in the scene, link it to your ActionList asset and check both Run on start? and Run on load?.

    An ActionList can be looped in on itself (i.e. the last Action runs the first when completed), but there's nothing to prevent you also from alternatively running a regular Update loop through code - anything that an Action performs has a script equivalent.

    It's also possible for a custom Action to loop itself. An Action will keep running until its Run() function returns zero, so you could keep returning e.g. -1 (to wait just a single frame).

    The thing about a 24-hour clock situation, though, is that you want to keep performance good, and the best way to do that is avoid loops whenever possible. One way to do this is to instead rely on custom events, which trigger when key changes happen.

    For example, the OnVariableChange event is called when a variable's value is changed - so you can have a script that "listens" out for this, waiting for a specific variable - and then reacts accordingly.

    Sample script:

    using UnityEngine;
    using AC;
    
    public class RunAssetOnVariableChange : MonoBehaviour
    {
    
        private bool hasRunList;
        public ActionListAsset assetToRun;
        public int minValue = 10;
    
        private void OnEnable () { EventManager.OnVariableChange += OnVariableChange; }
        private void OnDisable () { EventManager.OnVariableChange -= OnVariableChange; }
    
        private void OnVariableChange (GVar variable)
        {
            if (variable.label == "Timer" &&
                !hasRunList &&
                variable.IntegerValue >= minValue)
            {
                assetToRun.Interact ();
                hasRunList = true;
            }
        }
    }
    
  • Awesome I finally made some good progress. Thank you

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.