Custom Actions - Part 1

Note: this is a basic example of how to create a custom action. In this case we'll be doing a basic instantaneous action. You can create an empty cs script or start with a copy of the ActionTemplate.cs located in the Adventure creator/Scripts/ActionList folder.

The first step is to make sure the class name is correct. It needs to have the same name as your cs file (In this case ActionTestAction.cs) it's important to note there are two places where you need to set this (the class and the class constructor). You can set the name and description of your action inside the constructor. Using slashes '/' will create new submenus inside the category of your selection (which is by default Custom)

```
[System.Serializable]
	public class ActionTestAction : Action //rename your action here.
	{

		// Declare variables here
	    public string EvaluatedWord = "";
        public int CharacterId = 0;

	    private WhimManager whimManager;

        public ActionTestAction() //rename your action here too!
		{
			this.isDisplayed = true;
			category = ActionCategory.Custom; //change to another category here.
			title = "01 - Core Systems/01 - Test Action"; // name and categorize your action here.
			description = "Describe your action here.";
		}

```

Next is best to create the variables your logic is going to use, any variable which will be used to contain data received from the user should be declared at the class header (because it'll need to be visible to the whole script). Note that the variables will need to be public to be remembered by AC. also, you can set default values in here:

```
[System.Serializable]
	public class ActionTestAction : Action //rename your action here.
	{

		// Declare variables here
	    public string EvaluatedWord = ""; //default value is ""
            public int CharacterId = 0; //default value will be 0

	    private MyScript myScript;

```

Next make sure your user (or you, in this case) can provide input inside the action. To do this, head to the ShowGUI() Function. To provide input you will need to use EditorGUILayout methods. The full list of methods can be found here. Basically, you assign the product of a menu interaction as the contents of your variable. The EditorGUILayout creates a menu element which will edit some assigned value (in this case the exact same variables, because we want them to be overwritten). Also, most of these methods use the same two parameters, the first one is the text you want displayed in the new menu element, the other is the target variable to edit.

```
override public void ShowGUI ()
		{
            // Action-specific Inspector GUI code here
		    CharacterId = EditorGUILayout.IntField("Character Id Number: ", CharacterId);
		    EvaluatedWord = EditorGUILayout.TextField("Whim to evaluate: ", EvaluatedWord);

			//this should always be the last line.
            AfterRunningOption ();
		}

```

Here are some EditorGUILayout methods which are commonly used: Intfield, TextField, TextArea, Toggle (for booleans), FloatField, EnumPopup. Most of these methods have special Delayed versions which will not accept a value until the user hits the enter button, this is useful in cases where you want to make sure the user is sure of their change before overwriting the original data.

Then, finally, we go to the Run() function and add our actual logic. In this hypothetical action we're finding a script manager (supposed to have only one instance) and then we run a method from the script, giving it the appropriate parameters. Then we close the function. AC actions have the ability to rerun like coroutines (but this will be covered by another article). In this case we just want the action to be instantaneous, so we return 0f.

```
override public float Run ()
		{
            //your action:

            myScript = FindObjectOfType<MyScript>();
            myScript.EvaluateIdea(EvaluatedWord, CharacterId);

            //This is an instantaneous action, so returning 0f.
            return 0f;
        }

```

And the whole script:

```
using UnityEngine;
using System.Collections;
#if UNITY_EDITOR
using UnityEditor;
#endif

  namespace AC
  {

  	[System.Serializable]
  	public class ActionTestAction : Action //rename your action here.
	{

		// Declare variables here
	    public string EvaluatedWord = ""; //default value is ""
            public int CharacterId = 0; //default value will be 0

	    private MyScript myScript;

        public ActionTestAction() //rename your action here too!
		{
			this.isDisplayed = true;
			category = ActionCategory.Custom;//change to another category here.
			title = "01 - Core Systems/01 - Test Action"; // name and categorize your action here.
			description = "Describe your action here.";
		}

		override public float Run ()
		{
            //your action:

            myScript = FindObjectOfType<MyScript>();
            myScript.EvaluateIdea(EvaluatedWord, CharacterId);

            //This is an instantaneous action, so returning 0f.
            return 0f;
        }

  #if UNITY_EDITOR

		override public void ShowGUI ()
		{
            // Action-specific Inspector GUI code here
		    CharacterId = EditorGUILayout.IntField("Character Id Number: ", CharacterId);
		    EvaluatedWord = EditorGUILayout.TextField("Whim to evaluate: ", EvaluatedWord);

			//this should always be the last line.
            AfterRunningOption ();
		}

		public override string SetLabel ()
		{
			// Return a string used to describe the specific action's job.

			string labelAdd = "Describe what your action does in here.";
			return labelAdd;
		}

		#endif

	}

}

```

-Tip and script provided by user Alverik-