Skip to main content

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
info

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() { }
}
USING LAMBDA EXPRESSIONS

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() { }
}