BaseForEachAction
BaseForEachAction is an abstract base class for loop actions that run the state once for each item in a collection or for each iteration in a counted loop.
It provides the shared looping behavior used by actions such as ForEachListItem, ForEachChild, and Loop.
Core Functionality
The class provides:
Loop Start Behavior
BaseForEachAction marks the action as starting a loop:
This tells PlayMaker that the action will repeatedly run the state as part of a loop.
Current Index Output
The optional _currentIndex output stores the current loop index.
This value is updated before each iteration, so other actions in the same state can use it.
Reset On Exit
The _resetOnExitState option controls whether the loop progress is reset when the state exits.
This is useful when you want the loop to restart from the beginning every time the state is entered again.
Required Members
Inheritors must implement:
ItemCount returns how many items or iterations the loop should process.
EachAction(int index) sets up the data for the current iteration.
How It Works
BaseForEachAction advances one item per loop pass:
OnStart()checksItemCount- It stores the current index in
_currentIndex - It calls
EachAction(index)for the current item - It advances to the next item
- When the last item is reached, it stops the loop and calls
OnLoopFinished()
This means the derived action usually only needs to expose the current item for the rest of the state to use.
Optional Override
Inheritors can also override:
Use this if the action needs to do extra work when the loop completes.
Debug Info
In the Unity Editor, BaseForEachAction provides debug info showing the current progress:
For example:
Example
ForEachListItem is a typical example:
using System;
using System.Collections;
using JetBrains.Annotations;
using UnityEngine;
namespace HutongGames.PlayMaker.Actions
{
[Serializable, PublicAPI]
[ActionCategory(Category.Loop)]
[ActionDescription("Run actions in this state on each item in a list.")]
public class ForEachListItem : BaseForEachAction
{
[BaseType(typeof(IList))]
[Tooltip("The list variable.")]
[SerializeReference]
private IListVariableRef _list;
[MatchType(nameof(_list))]
[Tooltip("The current item retrieved from the list.")]
[SerializeReference, WriteOnly]
private IVariableRef _item;
protected override int ItemCount => _list.ListVariable?.Count ?? 0;
public override bool CanExecute() => CheckParameters(_list, _item);
public override void EachAction(int index) => _item.SetValue(_list.ListVariable[index]);
}
}
With this setup, the base class handles the loop flow and index tracking, and the derived action only needs to provide the item count and expose the current item for each iteration.