playMaker

Author Topic: Authoring Custom Actions  (Read 33767 times)

Lane

  • Administrator
  • Hero Member
  • *****
  • Posts: 2511
  • Mender of the past
    • Cleverous
Authoring Custom Actions
« on: March 06, 2015, 11:22:17 AM »
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: [Select]
// (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()
{

}
}
}


If you have other questions regarding writing custom actions or suggestions about new formatting attributes, feel free to post them!
Products by Cleverous
|| Vault Core : Database
|| Vault Inventory : Multiplayer Inventory
|| Vault Attributes : Character Stats
|| That Hurt! : Dmg Floaties
|| Quinn : 3D

Deek

  • Full Member
  • ***
  • Posts: 133
Re: Authoring Custom Actions
« Reply #1 on: December 15, 2017, 09:13:39 AM »
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:   
  • Wherever you see the word "Template" in them, you should replace it with the name of your custom action.
  • 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.
  • 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
« Last Edit: December 30, 2017, 06:58:04 PM by Deek »

djaydino

  • Administrator
  • Hero Member
  • *****
  • Posts: 7620
    • jinxtergames
Re: Authoring Custom Actions
« Reply #2 on: December 15, 2017, 09:29:07 AM »
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

  • Full Member
  • ***
  • Posts: 133
Re: Authoring Custom Actions
« Reply #3 on: December 15, 2017, 10:09:46 AM »
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

  • Administrator
  • Hero Member
  • *****
  • Posts: 7620
    • jinxtergames
Re: Authoring Custom Actions
« Reply #4 on: December 15, 2017, 10:52:54 AM »
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 :)

...

  • Beta Group
  • Hero Member
  • *
  • Posts: 1294
Re: Authoring Custom Actions
« Reply #5 on: December 15, 2017, 12:01:25 PM »
Damn man, this is great.

...

  • Beta Group
  • Hero Member
  • *
  • Posts: 1294
Re: Authoring Custom Actions
« Reply #6 on: December 15, 2017, 06:11:47 PM »
I've been thinking a lot about action templates and i have an idea. I think of making a drag and drop custom action maker with dragging elements which actually contains the code as building blocks. Gotta check if unity or vs are capable of something like this. Basically something like Scratch.
« Last Edit: December 16, 2017, 05:25:36 AM by krmko »

Deek

  • Full Member
  • ***
  • Posts: 133
Re: Authoring Custom Actions
« Reply #7 on: December 16, 2017, 10:55:27 AM »
That would be very neat and there seem to be various ways to create/generate c# code at runtime, like  CodeDOM, Roslyn, T4 Text Templates (apparently not supported by Unity), or just having several static classes/dlls that get integrated when needed, though it seems a bit over-ambitious and quite the time sucker.
But if you're determined to do this, I would be absolutely looking forward to it and also interested in seeing your progress on this (you might lead a little dev diary in the "Work In Progress..."-section or somewhere else, where you could also get feedback from others on what to improve or can ask for help when you get stuck somewhere).

GUI-wise it shouldn't prove much of a problem, but I see a few more other possible obstacles on that endeavour:
- in actions you only see the variables, not the functionality behind it, so you would need two ways to customize, one for adding variables and one for adding the functionality behind it
- the code blocks would have to interact with each others flawlessly, making it also difficult to add to them, as that could break functionality on other parts, and since they get added at runtime and likely are supposed to be combined with any other code block it makes debugging even more difficult

Just trying to show some difficulties that you could encouter, but you should definitely try it.

...

  • Beta Group
  • Hero Member
  • *
  • Posts: 1294
Re: Authoring Custom Actions
« Reply #8 on: December 16, 2017, 01:48:54 PM »
Thanks for the kind words and ecouragement. I'll start messing around with Nottorus to see how the Playmaker API works, though as far as i have seen it's nothing complicated, but integrating that into a flawless, easy going system will be tough :)
« Last Edit: December 16, 2017, 03:23:25 PM by krmko »

djaydino

  • Administrator
  • Hero Member
  • *****
  • Posts: 7620
    • jinxtergames
Re: Authoring Custom Actions
« Reply #9 on: December 17, 2017, 06:50:36 AM »
Hi,
For the action wizard i don't think this is the way to go, maybe for a separate add-on this would be good.

i just want to expand the option on the current version.
Like :
  • Adding the "/*--- __ECO__ __PLAYMAKER__ __ACTION__ ---*/"
  • Adding author
  • Adding an url option (forum topic for example)
  • Have a option to add "Every Frame"
  • Add "update"type" options which would also add OnPreprocess
  • Maybe pre-add variables and automatically add them to Reset()

And add some comment in the code to explain what to do where.

tcmeric

  • Beta Group
  • Hero Member
  • *
  • Posts: 768
Re: Authoring Custom Actions
« Reply #10 on: December 17, 2017, 10:42:44 AM »
djaydino. I would also suggest being able to add some examples of playmaker specific code.
Such as

[RequiredField]
[CheckForComponent(typeof(VRTK_Pointer))]
[ActionSection("Settings")]
[ObjectType(typeof(QueryTriggerInteraction))]
public FsmEnum
etc.

or

enablePointer = new FsmBool {UseVariable = true};

I know how to code, but often forget these playmaker specific things. Being able to start a template with 3 action sections (even empty ones), or the option to check for a component on the first variable (GO), that would be handy.

In general, I agree with your approach. It doesnt need to be overly complicated.

Right now I just copy and paste my past scripts, empty and re-code.

djaydino

  • Administrator
  • Hero Member
  • *****
  • Posts: 7620
    • jinxtergames
Re: Authoring Custom Actions
« Reply #11 on: December 18, 2017, 04:59:41 AM »
Hi,
@tcmeric
Some good points there.

When i am back home, i will ask Alex if i can get access to the wizard so i don't need to make it from scratch (and mainly to keep similar visuals)

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15594
  • Official Playmaker Support
Re: Authoring Custom Actions
« Reply #12 on: February 01, 2018, 01:07:07 AM »
Hi,

 Yes, At some point we need to push for this. I too would enjoy a wizard that construct the structure of an action and you jsut fill in the blank after, but all methods, naming, public variable definition and attributes should all be presented in a clear manner where you have access to all the wonders intuitively. This and setting up the preprocessor or using the fsmStatActionAdvanced for accessing fixed and late update everyframe option. caching of component being targeted, etc etc.

Bye,

 Jean