diff --git a/Runtime/Event/BehaviourEnabledObserver2.cs b/Runtime/Event/BehaviourEnabledObserver2.cs
new file mode 100644
index 00000000..fc8d7b53
--- /dev/null
+++ b/Runtime/Event/BehaviourEnabledObserver2.cs
@@ -0,0 +1,62 @@
+namespace Zinnia.Event
+{
+ using UnityEngine;
+ using UnityEngine.Events;
+ using Malimbe.BehaviourStateRequirementMethod;
+ using Malimbe.MemberClearanceMethod;
+ using Malimbe.PropertySerializationAttribute;
+ using Malimbe.XmlDocumentationAttribute;
+ using Zinnia.Data.Collection.List;
+ using Zinnia.Extension;
+ using Zinnia.Process;
+ using Zinnia.Rule;
+
+ ///
+ /// Emits an event once a list of s all are .
+ ///
+ public class BehaviourEnabledObserver2 : MonoBehaviour, IProcessable
+ {
+ ///
+ /// The s to observe.
+ ///
+ [Serialized]
+ [field: DocumentedByXml]
+ public BehaviourObservableList Behaviours { get; set; }
+
+ ///
+ /// The rule to match against the Behaviours.
+ ///
+ [Serialized, Cleared]
+ [field: DocumentedByXml]
+ public RuleContainer Rule { get; set; }
+
+ ///
+ /// Emitted when all are .
+ ///
+ [DocumentedByXml]
+ public UnityEvent ActiveAndEnabled = new UnityEvent();
+
+ ///
+ /// Checks whether all are and emits if they are.
+ ///
+ /// Whether all are active and enabled.
+ [RequiresBehaviourState]
+ public virtual void Process()
+ {
+ if (Behaviours == null || Behaviours.NonSubscribableElements.Count == 0)
+ {
+ return;
+ }
+
+ foreach (Behaviour behaviour in Behaviours.NonSubscribableElements)
+ {
+ if (!Rule.Accepts(behaviour))
+ {
+ return;
+ }
+ }
+
+ ActiveAndEnabled?.Invoke();
+ }
+ }
+}
diff --git a/Runtime/Event/BehaviourEnabledObserver2.cs.meta b/Runtime/Event/BehaviourEnabledObserver2.cs.meta
new file mode 100644
index 00000000..b6461b58
--- /dev/null
+++ b/Runtime/Event/BehaviourEnabledObserver2.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: fdc10351feed3fe46958637c21b253b2
+timeCreated: 1541932041
\ No newline at end of file
diff --git a/Runtime/Process/Moment/CoroutineMomentProcessor.cs b/Runtime/Process/Moment/CoroutineMomentProcessor.cs
new file mode 100644
index 00000000..edd92e93
--- /dev/null
+++ b/Runtime/Process/Moment/CoroutineMomentProcessor.cs
@@ -0,0 +1,136 @@
+namespace Zinnia.Process.Moment
+{
+ using UnityEngine;
+ using System.Collections;
+ using Malimbe.MemberChangeMethod;
+ using Malimbe.PropertySerializationAttribute;
+ using Malimbe.XmlDocumentationAttribute;
+ using Zinnia.Process.Moment.Collection;
+
+ ///
+ /// Iterates through a given collection and executes the method using Unity coroutine.
+ ///
+ public class CoroutineMomentProcessor : MonoBehaviour
+ {
+ ///
+ /// The amount of time to pause after each process iteration.
+ ///
+ [Serialized]
+ [field: DocumentedByXml]
+ public float Interval { get; set; } = 0.000011f;
+ ///
+ /// The maximum amount of time to perform the process before ending.
+ ///
+ [Serialized]
+ [field: DocumentedByXml]
+ public float MaximumRunTime { get; set; } = float.PositiveInfinity;
+
+ ///
+ /// A collection of to process.
+ ///
+ [Serialized]
+ [field: DocumentedByXml]
+ public MomentProcessObservableList Processes { get; set; }
+
+ ///
+ /// A reference to the started routine.
+ ///
+ protected Coroutine processRoutine;
+ ///
+ /// Delays the by seconds.
+ ///
+ protected WaitForSeconds delayYieldInstruction;
+ ///
+ /// The amount of time until the is cancelled.
+ ///
+ protected float timeUntilProcessIsCancelled;
+
+ ///
+ /// Initiates the process if no existing process is already running.
+ ///
+ public virtual void BeginProcess()
+ {
+ if (processRoutine == null)
+ {
+ processRoutine = StartCoroutine(ProcessRoutine());
+ }
+ }
+
+ ///
+ /// Cancels any running process.
+ ///
+ public virtual void EndProcess()
+ {
+ if (processRoutine == null)
+ {
+ return;
+ }
+
+ StopCoroutine(processRoutine);
+ processRoutine = null;
+ }
+
+ protected virtual void OnEnable()
+ {
+ OnAfterCheckDelayChange();
+ OnAfterMaximumRunTimeChange();
+ BeginProcess();
+ }
+
+ protected virtual void OnDisable()
+ {
+ EndProcess();
+ }
+
+ ///
+ /// Calls on every frame.
+ ///
+ /// An Enumerator to manage the running of the Coroutine.
+ protected virtual IEnumerator ProcessRoutine()
+ {
+ timeUntilProcessIsCancelled = Time.time + MaximumRunTime;
+ while (Time.time < timeUntilProcessIsCancelled)
+ {
+ Process();
+ yield return delayYieldInstruction;
+ }
+ processRoutine = null;
+ }
+
+ ///
+ /// Iterates through the given and calls on each one.
+ ///
+ protected virtual void Process()
+ {
+ if (Processes == null)
+ {
+ return;
+ }
+
+ foreach (MomentProcess currentProcess in Processes.NonSubscribableElements)
+ {
+ currentProcess.Process();
+ }
+ }
+
+
+ ///
+ /// Called after has been changed.
+ ///
+ [CalledAfterChangeOf(nameof(Interval))]
+ protected virtual void OnAfterCheckDelayChange()
+ {
+ delayYieldInstruction = new WaitForSeconds(Interval);
+ }
+
+ ///
+ /// Called after has been changed.
+ ///
+ [CalledAfterChangeOf(nameof(MaximumRunTime))]
+ protected virtual void OnAfterMaximumRunTimeChange()
+ {
+ float remainingRunTime = timeUntilProcessIsCancelled - Time.time;
+ timeUntilProcessIsCancelled = MaximumRunTime - remainingRunTime;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Runtime/Process/Moment/CoroutineMomentProcessor.cs.meta b/Runtime/Process/Moment/CoroutineMomentProcessor.cs.meta
new file mode 100644
index 00000000..80f42e3f
--- /dev/null
+++ b/Runtime/Process/Moment/CoroutineMomentProcessor.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f209ac37ba2d16b4ea6027fffe5726f1
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/Rule/IsActiveAndEnabledRule.cs b/Runtime/Rule/IsActiveAndEnabledRule.cs
new file mode 100644
index 00000000..d46378b3
--- /dev/null
+++ b/Runtime/Rule/IsActiveAndEnabledRule.cs
@@ -0,0 +1,19 @@
+namespace Zinnia.Rule
+{
+ using UnityEngine;
+ using Malimbe.BehaviourStateRequirementMethod;
+
+ ///
+ /// Determines whether a is active in the scene hierarchy.
+ ///
+ public class IsActiveAndEnabledRule : MonoBehaviour, IRule
+ {
+ ///
+ [RequiresBehaviourState]
+ public bool Accepts(object target)
+ {
+ Behaviour behaviour = target as Behaviour;
+ return behaviour != null && behaviour.isActiveAndEnabled;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Runtime/Rule/IsActiveAndEnabledRule.cs.meta b/Runtime/Rule/IsActiveAndEnabledRule.cs.meta
new file mode 100644
index 00000000..e51af6f2
--- /dev/null
+++ b/Runtime/Rule/IsActiveAndEnabledRule.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 59a718228167ba54288f4fc37e9d1e98
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: