Using Revert Actions
Sometimes you may want to revert an action performed by a node once the tree has finished running. This can be useful for things like resetting a value or undoing a change that was made during the tree's execution.
Jungle provides a way to revert actions by defining a revert method on your nodes. These methods can then be registered with the tree and will be called when the tree stops or is finished running.
When are revert actions called?
- When the tree is stopped
- When the tree is finished running
Revert actions added via node scripts will still be called regardless of whether the node is running or not.
Code Reference
Trees contain two methods for managing revert actions: AddRevertAction
and RemoveRevertAction
.
These methods are children of the JungleTree
class and can be accessed from any tree instance.
AddRevertAction(Action)
public string AddRevertAction(Action action)
Adds an action to be invoked when the tree stops. The returned string is a unique identifier for the action that can be used to remove it.
RemoveRevertAction(string)
public void RemoveRevertAction(string actionUid)
Removes an action from the revert list.
Adding Revert Actions
Adding a revert action is as simple as defining a method and subscribing it to the tree's revert actions.
From a Jungle Node
All nodes contain a reference to the tree they are a part of.
using Jungle;
using UnityEngine;
public class MyNode : IdentityNode
{
protected override void OnStart()
{
// Subscribe "MyRevertAction" to the tree's revert actions
JungleTree.AddRevertAction(MyRevertAction);
}
private void MyRevertAction()
{
Debug.Log("Revert Action Called!");
}
protected override void OnUpdate() { }
}
You can also use lambda expressions to define revert actions.
JungleTree.AddRevertAction(() =>
{
Debug.Log("Revert Action Called!");
});
From a Script
You can also add revert actions from a script by accessing the tree instance from a JungleTree
reference.
using Jungle;
using UnityEngine;
public class MyMonoBehaviour : MonoBehaviour
{
[SerializeField]
private JungleTree myJungleTree;
private void Start()
{
// Subscribe "MyRevertAction" to the tree's revert actions
myJungleTree.AddRevertAction(MyRevertAction);
}
private void MyRevertAction()
{
Debug.Log("Revert Action Called!");
}
}
Removing Revert Actions
Revert actions can be removed by calling RemoveRevertAction
with the unique identifier returned when the action was
added.
using Jungle;
using UnityEngine;
public class MyNode : IdentityNode
{
private string _revertActionUid;
protected override void OnStart()
{
// Subscribe "MyRevertAction" to the tree's revert actions
_revertActionUid = JungleTree.AddRevertAction(MyRevertAction);
}
protected override void OnStop()
{
// Unsubscribe "MyRevertAction" from the tree's revert actions
JungleTree.RemoveRevertAction(_revertActionUid);
}
private void MyRevertAction()
{
Debug.Log("Revert Action Called!");
}
protected override void OnUpdate() { }
}
Example
Here's an example of a node that sets the position of a transform to y = 10 and adds a revert action to reset the position to its original value.
using Jungle;
using UnityEngine;
[IONode(
OutputPortType = typeof(Transform)
)]
public class SetPositionNode : IONode<Transform>
{
private Vector3 _originalPosition;
protected override void OnStart(Transform transform)
{
_originalPosition = transform.position;
// Set the position to y = 10
transform.position = new Vector3(0, 10, 0);
// Add a revert action to reset the position to the original position
JungleTree.AddRevertAction(() =>
{
transform.position = _originalPosition;
});
CallAndStop(transform);
}
protected override void OnUpdate() { }
}