I made an Action on my side before seen yours.
My needs wasn't the same and I saw yours after, so I integrated your code to mine because it could be usefull.
The purpose of my Action was to add FSM template at runtime with system events activated. because with a simple Action to add the FSM Template, it works in Editor Playmode but not in Build. With my Action it works fine.
I have just tested MouseEvents because it's what I needed for my project for the moment but I have implemented the other Events for later needs, I think the problem will be like for the MouseEvent and the solution too.
I share it, if you want to take a look and update your Action.
Custom Action Editor: Editor/AddFSMTemplateToGameObjectEditor.cs// action created by Jeremy Sebagh - 20200720
// modified by Jeremy Sebagh - 20200725
using UnityEngine;
using UnityEditor;
using HutongGames.PlayMaker.Actions;
using HutongGames.PlayMakerEditor;
[CustomActionEditor(typeof(AddFSMTemplateToGameObject))]
public class AddFSMTemplateToGameObjectEditor : CustomActionEditor
{
public override void OnEnable()
{
}
public override bool OnGUI()
{
var isDirty = false;
var action = target as AddFSMTemplateToGameObject;
GUILayout.Label("Select the GameObject and the FSM Template to Add:", EditorStyles.boldLabel);
EditField("_GameObject");
EditField("_FSMTemplate");
GUILayout.Space(3);
EditField("_FSMName");
GUILayout.Space(3);
EditField("_StoreComponent");
GUILayout.Space(5);
GUILayout.Label("Access to Optionals setup", EditorStyles.boldLabel);
EditField("_EnableOptions");
if (action._EnableOptions.Value)
{
GUILayout.Space(3);
EditField("active");
EditField("unique");
EditField("replace");
EditField("variableNames");
EditField("variables");
EditField("existsEventTarget");
EditField("existsSendEvent");
EditField("doNotDestroy");
EditField("replaceEventTarget");
EditField("replaceSendEvent");
}
GUILayout.Space(5);
GUILayout.Label("Access to Events Overrides to allow system events during build runtime", EditorStyles.boldLabel);
EditField("_EnableRuntimeEventsOverride");
if (action._EnableRuntimeEventsOverride.Value)
{
GUILayout.Space(3);
EditField("_MouseEvents");
EditField("_ApplicationEvents");
EditField("_TriggerEnter");
EditField("_TriggerExit");
EditField("_TriggerStay");
EditField("_CollisionEnter");
EditField("_CollisionExit");
EditField("_CollisionStay");
EditField("_LateUpdate");
EditField("_FixedUpdate");
}
return isDirty || GUI.changed;
}
}
Action: AddFSMTemplateToGameObject.cs// action created by Jeremy Sebagh - 20200720
// modified by Jeremy Sebagh - 20200725
// added stuff from action by Krileon: https://hutonggames.com/playmakerforum/index.php?topic=5819.msg28493#msg28493
using UnityEngine;
using System.Collections.Generic;
namespace HutongGames.PlayMaker.Actions
{
[ActionCategory("0MyCustomActions")]
[Tooltip("Add a FSM Template to a GameObject")]
public class AddFSMTemplateToGameObject : FsmStateAction
{
[RequiredField]
[CheckForComponent(typeof(GameObject))]
[Tooltip("GameObject")]
public FsmOwnerDefault _GameObject;
[RequiredField]
[CheckForComponent(typeof(FsmTemplate))]
[Tooltip("FSM Template")]
public FsmTemplate _FSMTemplate;
[Tooltip("Enable Options")]
public FsmBool _EnableOptions;
[Tooltip("FSM Name")]
public FsmString _FSMName;
[Tooltip("Store Component")]
[ObjectType(typeof(PlayMakerFSM)), UIHint(UIHint.Variable)]
public FsmObject _StoreComponent;
// =====================================
// Code from Krileon Action
// =====================================
public FsmBool active;
public FsmBool unique;
public FsmBool replace;
[CompoundArray("Variables", "Name", "Variable")]
[RequiredField]
public FsmString[] variableNames;
[RequiredField]
public FsmVar[] variables;
// [ObjectType(typeof(PlayMakerFSM)), UIHint(UIHint.Variable)]
// public FsmObject storeComponent;
[ActionSection("Exists Event")]
public FsmEventTarget existsEventTarget;
public FsmString existsSendEvent;
[ActionSection("Replace Event")]
public FsmBool doNotDestroy;
public FsmEventTarget replaceEventTarget;
public FsmString replaceSendEvent;
// =====================================
// End Code from Krileon Action
// =====================================
private GameObject previousGo;
private List<PlayMakerFSM> fsms;
[Tooltip("Enable Events Override")]
public FsmBool _EnableRuntimeEventsOverride;
[Tooltip("Mouse Events")]
public FsmBool _MouseEvents;
[Tooltip("Application Events")]
public FsmBool _ApplicationEvents;
[Tooltip("Trigger Enter")]
public FsmBool _TriggerEnter;
[Tooltip("Trigger Exit")]
public FsmBool _TriggerExit;
[Tooltip("Trigger Stay")]
public FsmBool _TriggerStay;
[Tooltip("Collision Enter")]
public FsmBool _CollisionEnter;
[Tooltip("Collision Exit")]
public FsmBool _CollisionExit;
[Tooltip("Collision Stay")]
public FsmBool _CollisionStay;
[Tooltip("Collision Stay")]
public FsmBool _LateUpdate;
[Tooltip("Collision Stay")]
public FsmBool _FixedUpdate;
public override void Reset()
{
_GameObject = null;
_FSMTemplate = null;
_EnableOptions = null;
_FSMName = null;
_StoreComponent = null;
_EnableRuntimeEventsOverride = null;
_MouseEvents = false;
_ApplicationEvents = false;
_TriggerEnter = false;
_TriggerExit = false;
_TriggerStay = false;
_CollisionEnter = false;
_CollisionExit = false;
_CollisionStay = false;
_LateUpdate = false;
_FixedUpdate = false;
// =====================================
// Code from Krileon Action
// =====================================
active = new FsmBool { Value = true };
unique = new FsmBool { Value = false };
replace = new FsmBool { Value = false };
variableNames = new FsmString[0];
variables = new FsmVar[0];
existsEventTarget = null;
existsSendEvent = null;
doNotDestroy = new FsmBool { Value = false };
replaceEventTarget = null;
replaceSendEvent = null;
// =====================================
// End Code from Krileon Action
// =====================================
}
public override void OnEnter()
{
GameObject gameObject = Fsm.GetOwnerDefaultTarget(_GameObject);
if (gameObject == null)
{
Finish();
return;
}
PlayMakerFSM FSMTemplate = null;
if (_EnableOptions.Value)
{
// ==============================================================
// Modified Code from Krileon Action (only some variable names)
// ==============================================================
bool exists = false;
if ((!unique.Value) || replace.Value)
{
if (gameObject != previousGo)
{
fsms = new List<PlayMakerFSM>();
fsms.AddRange(gameObject.GetComponents<PlayMakerFSM>());
previousGo = gameObject;
}
if (fsms.Count > 0) foreach (PlayMakerFSM fsm in fsms)
{
if (((_FSMName.Value != "") && (fsm.FsmName == _FSMName.Value)) || ((fsm.FsmTemplate != null) && (fsm.FsmTemplate.name == _FSMTemplate.name)))
{
if (replace.Value)
{
if (replaceSendEvent.Value != "")
{
Fsm.Event(replaceEventTarget, replaceSendEvent.Value);
}
if (!doNotDestroy.Value)
{
Object.Destroy(fsm);
}
}
else
{
_StoreComponent.Value = fsm;
exists = true;
}
}
}
}
if (!exists)
{
FSMTemplate = gameObject.AddComponent<PlayMakerFSM>();
if (_FSMName.Value != "")
{
FSMTemplate.FsmName = _FSMName.Value;
}
if ((!active.Value) || (variableNames.Length > 0))
{
FSMTemplate.enabled = false;
}
FSMTemplate.SetFsmTemplate(_FSMTemplate);
if (variableNames.Length > 0)
{
if (variableNames.Length > 0) for (int i = 0; i < variableNames.Length; i++)
{
if (!variableNames[i].IsNone)
{
NamedVariable target = FSMTemplate.Fsm.Variables.GetVariable(variableNames[i].Value);
if (target != null)
{
variables[i].ApplyValueTo(target);
}
}
}
if (active.Value && (!FSMTemplate.enabled))
{
FSMTemplate.enabled = true;
}
}
if ((!unique.Value) || replace.Value)
{
fsms.Add(FSMTemplate);
}
_StoreComponent.Value = FSMTemplate;
}
else
{
if (existsSendEvent.Value != "")
{
Fsm.Event(existsEventTarget, existsSendEvent.Value);
}
}
// =====================================
// End Modified Code from Krileon Action
// =====================================
}
else
{
FSMTemplate = gameObject.AddComponent<PlayMakerFSM>();
FSMTemplate.SetFsmTemplate(_FSMTemplate);
FSMTemplate.FsmName = _FSMName.Value;
_StoreComponent.Value = FSMTemplate;
}
if (_EnableRuntimeEventsOverride.Value)
{
bool exists = false;
if (_MouseEvents.Value)
{
exists = false;
FSMTemplate.Fsm.MouseEvents = _MouseEvents.Value;
PlayMakerMouseEvents thisMouseEvent;
if (gameObject.GetComponent<PlayMakerMouseEvents>() != null)
{
List<PlayMakerMouseEvents> CheckMouseEvents = new List<PlayMakerMouseEvents>();
CheckMouseEvents.AddRange(gameObject.GetComponents<PlayMakerMouseEvents>());
foreach (PlayMakerMouseEvents MouseEvent in CheckMouseEvents)
{
if (MouseEvent.TargetFSMs.Contains(FSMTemplate))
{
exists = true;
break;
}
}
if (!exists) { thisMouseEvent = gameObject.GetComponent<PlayMakerMouseEvents>(); } else { thisMouseEvent = null; }
}
else
{
thisMouseEvent = gameObject.AddComponent<PlayMakerMouseEvents>();
}
if (thisMouseEvent) thisMouseEvent.TargetFSMs.Add(FSMTemplate);
}
if (_ApplicationEvents.Value)
{
exists = false;
FSMTemplate.Fsm.HandleApplicationEvents = _ApplicationEvents.Value;
PlayMakerApplicationEvents thisApplicationEvent;
if (gameObject.GetComponent<PlayMakerApplicationEvents>() != null)
{
List<PlayMakerApplicationEvents> CheckApplicationEvents = new List<PlayMakerApplicationEvents>();
CheckApplicationEvents.AddRange(gameObject.GetComponents<PlayMakerApplicationEvents>());
foreach (PlayMakerApplicationEvents ApplicationEvent in CheckApplicationEvents)
{
if (ApplicationEvent.TargetFSMs.Contains(FSMTemplate))
{
exists = true;
break;
}
}
if (!exists) { thisApplicationEvent = gameObject.GetComponent<PlayMakerApplicationEvents>(); } else { thisApplicationEvent = null; }
}
else
{
thisApplicationEvent = gameObject.AddComponent<PlayMakerApplicationEvents>();
}
if (thisApplicationEvent) thisApplicationEvent.TargetFSMs.Add(FSMTemplate);
}
if (_TriggerEnter.Value)
{
exists = false;
FSMTemplate.Fsm.HandleTriggerEnter = _TriggerEnter.Value;
PlayMakerTriggerEnter thisTriggerEnter;
if (gameObject.GetComponent<PlayMakerTriggerEnter>() != null)
{
List<PlayMakerTriggerEnter> CheckTriggerEnter = new List<PlayMakerTriggerEnter>();
CheckTriggerEnter.AddRange(gameObject.GetComponents<PlayMakerTriggerEnter>());
foreach (PlayMakerTriggerEnter TriggerEnter in CheckTriggerEnter)
{
if (TriggerEnter.TargetFSMs.Contains(FSMTemplate))
{
exists = true;
break;
}
}
if (!exists) { thisTriggerEnter = gameObject.GetComponent<PlayMakerTriggerEnter>(); } else { thisTriggerEnter = null; }
}
else
{
thisTriggerEnter = gameObject.AddComponent<PlayMakerTriggerEnter>();
}
if (thisTriggerEnter) thisTriggerEnter.TargetFSMs.Add(FSMTemplate);
}
if (_TriggerExit.Value)
{
exists = false;
FSMTemplate.Fsm.HandleTriggerExit = _TriggerExit.Value;
PlayMakerTriggerExit thisTriggerExit;
if (gameObject.GetComponent<PlayMakerTriggerExit>() != null)
{
List<PlayMakerTriggerExit> CheckTriggerExit = new List<PlayMakerTriggerExit>();
CheckTriggerExit.AddRange(gameObject.GetComponents<PlayMakerTriggerExit>());
foreach (PlayMakerTriggerExit TriggerExit in CheckTriggerExit)
{
if (TriggerExit.TargetFSMs.Contains(FSMTemplate))
{
exists = true;
break;
}
}
if (!exists) { thisTriggerExit = gameObject.GetComponent<PlayMakerTriggerExit>(); } else { thisTriggerExit = null; }
}
else
{
thisTriggerExit = gameObject.AddComponent<PlayMakerTriggerExit>();
}
if (thisTriggerExit) thisTriggerExit.TargetFSMs.Add(FSMTemplate);
}
if (_TriggerStay.Value)
{
exists = false;
FSMTemplate.Fsm.HandleTriggerStay = _TriggerStay.Value;
PlayMakerTriggerStay thisTriggerStay;
if (gameObject.GetComponent<PlayMakerTriggerStay>() != null)
{
List<PlayMakerTriggerStay> CheckTriggerStay = new List<PlayMakerTriggerStay>();
CheckTriggerStay.AddRange(gameObject.GetComponents<PlayMakerTriggerStay>());
foreach (PlayMakerTriggerStay TriggerStay in CheckTriggerStay)
{
if (TriggerStay.TargetFSMs.Contains(FSMTemplate))
{
exists = true;
break;
}
}
if (!exists) { thisTriggerStay = gameObject.GetComponent<PlayMakerTriggerStay>(); } else { thisTriggerStay = null; }
}
else
{
thisTriggerStay = gameObject.AddComponent<PlayMakerTriggerStay>();
}
if (thisTriggerStay) thisTriggerStay.TargetFSMs.Add(FSMTemplate);
}
if (_CollisionEnter.Value)
{
exists = false;
FSMTemplate.Fsm.HandleCollisionEnter = _CollisionEnter.Value;
PlayMakerCollisionEnter thisCollisionEnter;
if (gameObject.GetComponent<PlayMakerCollisionEnter>() != null)
{
List<PlayMakerCollisionEnter> CheckCollisionEnter = new List<PlayMakerCollisionEnter>();
CheckCollisionEnter.AddRange(gameObject.GetComponents<PlayMakerCollisionEnter>());
foreach (PlayMakerCollisionEnter CollisionEnter in CheckCollisionEnter)
{
if (CollisionEnter.TargetFSMs.Contains(FSMTemplate))
{
exists = true;
break;
}
}
if (!exists) { thisCollisionEnter = gameObject.GetComponent<PlayMakerCollisionEnter>(); } else { thisCollisionEnter = null; }
}
else
{
thisCollisionEnter = gameObject.AddComponent<PlayMakerCollisionEnter>();
}
if (thisCollisionEnter) thisCollisionEnter.TargetFSMs.Add(FSMTemplate);
}
if (_CollisionExit.Value)
{
exists = false;
FSMTemplate.Fsm.HandleCollisionExit = _CollisionExit.Value;
PlayMakerCollisionExit thisCollisionExit;
if (gameObject.GetComponent<PlayMakerCollisionExit>() != null)
{
List<PlayMakerCollisionExit> CheckCollisionExit = new List<PlayMakerCollisionExit>();
CheckCollisionExit.AddRange(gameObject.GetComponents<PlayMakerCollisionExit>());
foreach (PlayMakerCollisionExit CollisionExit in CheckCollisionExit)
{
if (CollisionExit.TargetFSMs.Contains(FSMTemplate))
{
exists = true;
break;
}
}
if (!exists) { thisCollisionExit = gameObject.GetComponent<PlayMakerCollisionExit>(); } else { thisCollisionExit = null; }
}
else
{
thisCollisionExit = gameObject.AddComponent<PlayMakerCollisionExit>();
}
if (thisCollisionExit) thisCollisionExit.TargetFSMs.Add(FSMTemplate);
}
if (_CollisionStay.Value)
{
exists = false;
FSMTemplate.Fsm.HandleCollisionStay = _CollisionStay.Value;
PlayMakerCollisionStay thisCollisionStay;
if (gameObject.GetComponent<PlayMakerCollisionStay>() != null)
{
List<PlayMakerCollisionStay> CheckCollisionStay = new List<PlayMakerCollisionStay>();
CheckCollisionStay.AddRange(gameObject.GetComponents<PlayMakerCollisionStay>());
foreach (PlayMakerCollisionStay CollisionStay in CheckCollisionStay)
{
if (CollisionStay.TargetFSMs.Contains(FSMTemplate))
{
exists = true;
break;
}
}
if (!exists) { thisCollisionStay = gameObject.GetComponent<PlayMakerCollisionStay>(); } else { thisCollisionStay = null; }
}
else
{
thisCollisionStay = gameObject.AddComponent<PlayMakerCollisionStay>();
}
if (thisCollisionStay) thisCollisionStay.TargetFSMs.Add(FSMTemplate);
}
if (_LateUpdate.Value)
{
exists = false;
FSMTemplate.Fsm.HandleLateUpdate = _LateUpdate.Value;
PlayMakerLateUpdate thisLateUpdate;
if (gameObject.GetComponent<PlayMakerLateUpdate>() != null)
{
List<PlayMakerLateUpdate> CheckLateUpdate = new List<PlayMakerLateUpdate>();
CheckLateUpdate.AddRange(gameObject.GetComponents<PlayMakerLateUpdate>());
foreach (PlayMakerLateUpdate LateUpdate in CheckLateUpdate)
{
if (LateUpdate.TargetFSMs.Contains(FSMTemplate))
{
exists = true;
break;
}
}
if (!exists) { thisLateUpdate = gameObject.GetComponent<PlayMakerLateUpdate>(); } else { thisLateUpdate = null; }
}
else
{
thisLateUpdate = gameObject.AddComponent<PlayMakerLateUpdate>();
}
if (thisLateUpdate) thisLateUpdate.TargetFSMs.Add(FSMTemplate);
}
if (_FixedUpdate.Value)
{
exists = false;
FSMTemplate.Fsm.HandleFixedUpdate = _FixedUpdate.Value;
PlayMakerFixedUpdate thisFixedUpdate;
if (gameObject.GetComponent<PlayMakerFixedUpdate>() != null)
{
List<PlayMakerFixedUpdate> CheckFixedUpdate = new List<PlayMakerFixedUpdate>();
CheckFixedUpdate.AddRange(gameObject.GetComponents<PlayMakerFixedUpdate>());
foreach (PlayMakerFixedUpdate FixedUpdate in CheckFixedUpdate)
{
if (FixedUpdate.TargetFSMs.Contains(FSMTemplate))
{
exists = true;
break;
}
}
if (!exists) { thisFixedUpdate = gameObject.GetComponent<PlayMakerFixedUpdate>(); } else { thisFixedUpdate = null; }
}
else
{
thisFixedUpdate = gameObject.AddComponent<PlayMakerFixedUpdate>();
}
if (thisFixedUpdate) thisFixedUpdate.TargetFSMs.Add(FSMTemplate);
}
}
Finish();
}
}
}
edit: I posted it on the bad topic , it's corrected

edit2: Warning Correction
edit3: New Correction