Forum rules - please read before posting.

Custom action for timer

Hi all,

I wrote a custom action because we need an Engine: Wait, but that pauses when game is not in gameplay

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using AC;
using UnityEditor;

[System.Serializable]
public class ActionWaitDuringGameplay : Action
{
    public float timeToPause;
    public int parameterID = -1;
    public float timer = 0;
    public override ActionCategory Category { get { return ActionCategory.Engine; } }
    public override string Title { get { return "Wait During Gameplay"; } }
    public override string Description { get { return "Waits a set gameplay time before continuing."; } }

    public override void AssignValues(List<ActionParameter> parameters)
    {
        timeToPause = AssignFloat(parameters, parameterID, timeToPause);
    }


    public override float Run()
    {
        if (!isRunning)
        {
            isRunning = true;

            if (timeToPause < 0f)
            {
                return defaultPauseTime;
            }
            else
            {
                timer = timeToPause;
            }
            return defaultPauseTime;
        }
        else
        {
            if (timeToPause > 0f)
            {
                if (KickStarter.stateHandler.IsInGameplay())
                    timer-=Time.deltaTime;
                if (timer <= 0)
                {
                    isRunning = false;
                    return 0f;
                }
                else
                    return defaultPauseTime;
            }
            else
            {
                isRunning = false;
                return 0f;
            }
        }
    }


if UNITY_EDITOR

    public override void ShowGUI(List<ActionParameter> parameters)
    {
        parameterID = Action.ChooseParameterGUI("Wait time (s):", parameters, parameterID, ParameterType.Float);
        if (parameterID < 0)
        {
            timeToPause = EditorGUILayout.FloatField("Wait time (s):", timeToPause);
            if (timeToPause < 0f)
            {
                EditorGUILayout.HelpBox("A negative value will pause the ActionList by one frame.", MessageType.Info);
            }
        }
    }


    public override string SetLabel()
    {
        return timeToPause.ToString() + "s";
    }

endif


    /**
     * <summary>Creates a new instance of the 'Engine: Wait' Action with key variables already set.</summary>
     * <param name = "waitTime">The time to wait</param>
     * <returns>The generated Action</returns>
     */
    public static ActionWaitDuringGameplay CreateNew(float waitTime)
    {
        ActionWaitDuringGameplay newAction = CreateNew<ActionWaitDuringGameplay>();
        newAction.timeToPause = waitTime;
        return newAction;
    }

}

my issue is that if two gameobjects calling this action throught an action list asset at the same moment, the float timer variable syncs between them.How can I solve this?

Comments

  • I'm not clear on your setup - is this to say you have a single ActionList, called by two separate objects?

    So long as the ActionList asset has Can run multiple instances? checked, each running of it should be independent - otherwise, running it while it's already running will cause it to restart.

  • Hi Chris,

    yes the asset has can run multiple instances checked. In fact they run independently with they parameters, but when they comes together to this timer they sync up, regardless how much delay there are between their start.

    I debugged on visual studio the Run function.
    It looks like they use the same instance of ActionWaitDuringGameplay and the timer variable has the same value for both. And Delta time as been calculated twice in the frame for the same float.

    For example:

    I call the function with 7 sec wait.
    Wait 2 seconds.
    Timer how is 5 sec remaining.
    I call the action list asset with another object
    Timer for second is set to 7.
    Timer for first is set again to 7.
    Now they are synced and both their Run function reduce the same float timer by delta time.
    In 3,5 sec both timers are end.
  • Ok solved the problem.

    That was because ActionList.cs inside DownloadParameters function doesn't create different instances for actions inside actionlist asset that can run multiple instances.

    so I changed

    actions.Add(action);

    into

    actions.Add((assetFile.canRunMultipleInstances) ? Instantiate(action): action);

    now it's ok

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.