PlayMaker Updates & Downloads > Share New Actions

Authoring Custom Actions

(1/3) > >>

Lane:
There are often questions about making your own custom actions. You'll need a basic understanding of C# typically as this is what we use in all of the official actions but you could author them in any of the supported Unity languages if you have a better understanding of them.

You should take a look at the Wiki section for writing custom actions:
Writing Custom Actions (Wiki)

It includes a JS example, a lot of good information, tips and core ideas.

Here is an example of the UI Hints / Action Attributes (Wiki) and how to use them:

--- Code: ---// (c) Copyright HutongGames, LLC 2010-2015. All rights reserved.

using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Input)]
[Tooltip("UI Hint Examples.")]
public class UIHintExamples : FsmStateAction
{
[RequiredField] // this is a required field, you have to put something in it.
[CheckForComponent(typeof(Rigidbody))] // tells the ui to look for a type of component, like a Rigidbody.
[Tooltip("The GameObject you want.")] // basic tooltip for hover descriptions.
public FsmOwnerDefault gameObject; // FsmOwnerDefault uses the owner GameObject as the variable.

[ActionSection("  UI Hints")]

[UIHint(UIHint.Layer)] // Use on an integer field for a Layer popup button.
public FsmInt layerSingle; // Not an array, single choice.

[UIHint(UIHint.Layer)]
public FsmInt[] layerMulti; // As an array, this allows for multiple layer choices.

[ActionSection("Behavior")]

[UIHint(UIHint.Behaviour)]
[Tooltip("The name of the Behaviour.")] // See Enable Behavior
public FsmString behaviour;

[ActionSection("Coroutine")]

[UIHint(UIHint.Coroutine)]
[Tooltip("The name of the coroutine method.")] // See StartCoroutine
public FunctionCall functionCall;

[ActionSection("Script")]

[UIHint(UIHint.Script)]
[Tooltip("The name of the script.")] // See AddScript
public FsmString someString;

[ActionSection("Tags")]

[UIHint(UIHint.Tag)]
public FsmString someTagSingle; // See SetTag

[UIHint(UIHint.Tag)]
public FsmString[] someTagMultiple;

[ActionSection("Text Area")]

[UIHint(UIHint.TextArea)]
public FsmString textArea;

[ActionSection("Description Area")]

[UIHint(UIHint.Description)] // Use on a string field to format the text in a large readonly info box.
public string descriptionArea;

[ActionSection("Comment Area")]

[UIHint(UIHint.Comment)]
public FsmString commentArea;

[ActionSection("Basic Variables")]

[UIHint(UIHint.Variable)] // Use on an Fsm Variable field (FsmFloat, FsmInt, FsmBool...)
public FsmFloat numbers;

[UIHint(UIHint.Variable)]
public FsmBool boolean;

[ActionSection("Animation Hint")]

[UIHint(UIHint.Animation)]
public FsmString animation;

public override void Reset() // the Reset area defines the default values for your action variables.
{
gameObject = null;
someTagSingle = null;
someTagMultiple = new FsmString[2];
textArea = "Regular text area";
commentArea = "Stuff, comment stuff.";
descriptionArea = "lorum ipsum bippity bop doo dah lorum ipsum bippity bop doo dah lorum ipsum bippity bop doo dah lorum ipsum bippity bop doo dah lorum ipsum bippity bop doo dah lorum ipsum bippity bop doo dah";
layerSingle = null;
layerMulti = new FsmInt[3];
numbers = 14.3f;
boolean = true;
animation = null;

}

public override void Awake()
{

}

public override void OnEnter()
{

}

public override void OnFixedUpdate()
{

}

void DoLook()
{

}
}
}
--- End code ---


If you have other questions regarding writing custom actions or suggestions about new formatting attributes, feel free to post them!

Deek:
Templates for creating custom actions
As this seems to be the best place to share them and the Custom Action Wizard still creates pretty lagluster starting points, here are some templates (not to be confused with FSM-Templates) for writing custom actions, that contain pretty much everything you need to start off when creating a new custom action.

File-Description & -Links:

* Template.cs - The minimum to create a new action
* TemplateAdvanced.cs - Derives from FsmStateActionAdvanced to automatically supply the option to choose an update type and adds the required comments that would be needed to share the action on the Ecosystem (you would still need access to the appropriate repository to commit the action to the Ecosystem)
* Editor\TemplateInspector.cs - If you want to change the look and functionality of an action, you can create a custom inspector with this (needs to be in a folder called "Editor" anywhere in your Assets folder, preferably near your base action)
Note: Remember that any Editor-Script cannot be executed in your build, so these are mainly for added functionality when the user sets up the action. That's why you also have to reference variables from the base script, because Unity only saves the values of those during runtime.
* ExampleOverview.cs - A collection of further userful examples on things like compound arrays, enums and attributes to modify/style actions
Instructions:   [o]Wherever you see the word "Template" in them, you should replace it with the name of your custom action.
   [o]You should change the ActionCategory to something that fits your action type or give it an own name if none of the available ones are fitting.
   [o]When creating a new variable, just copy over the tooltip and variable declaration of one that is already there and only copy the "[RequiredField]" attribute if that variable really needs to be set from the user of your action.

Previews:






Even though the afore-mentioned wiki entry already contains a good overview on how to create certain custom action fields and its process, it doesn't provide a fast way of creating a new one like copying these templates over.

If you have suggestions on what should or shouldn't be in there, let me know.

Edit:
|16.12.17|
- Optimized TemplateInspector so that it only gets the reference to the action in OnEnable() instead of OnGUI() and added example on how to only draw single fields from the base script instead of drawing the whole inspector
- Added additional note to the TemplateInspector description
|23.12.17|
- Added the ExampleOverview and moved a few lines from TemplateAdvanced to that
|31.12.17|
- Added further OnPreprocess examples to ExampleOverview
- Removed the attachments, the in-line ExampleOverview-Preview and changed the script location from Gist to my main GitHub repository, so that I only have to update the scripts in one location when I change something
- reverted reference to action back to OnGUI() in TemplateInspector, because of a PlayMaker bug where it applied the cached action-reference to every open instance of that action, meaning that when the action was also selected in the Action Browser and I tried to get the action's owner, it constantly returned a Null-Reference-Exception because it also tried to get the owner of the action in the Asset Browser; also when two of the same actions where in one state and when changing values in one of them, it also applied them to the other instance (at least the values from the custom inspector) | having the action reference in OnGUI() works flawlessly now

djaydino:
Hi,
Indeed the Custom Action Wizard should need an update,
i never use it myself.
Usually i get an existing action and remove most of it and then start with that.

I will check out your templates :) (bookmarked them)

I am also thing to play around building a advanced wizard for this (Added to my Trello) , but it think it wont be this year anymore :)

Deek:
I also always copied over content from other actions that served a similar purpose, but that isn't the best coding habit and could lead to taking over bugs that one doesn't notice at first.
That's why I thought it would be good to have a somewhat blank slate in terms of functionality when creating a new action.

If you do create a more extensive wizard and are open to suggestions, I'd suggest having the option to add any amount of FsmVariables with the ability to choose its type, adding a tooltip and specify if it's required. Having at least one variable would also create the Reset() method that gets feeded with a default value for the defined variables (this I can imagine to be more on the difficult sides to implement).

djaydino:
Hi,
I was thinking in that direction yes.
Also for example if every frame is needed, to be able to select that.
And maybe for certain update types.

And i am open to suggestions of course :)

Navigation

[0] Message Index

[#] Next page

Go to full version