Author Topic: EnumCompareMultiSet - help needed to complete it  (Read 609 times)

Broken Stylus

  • Beta Group
  • Hero Member
  • *
  • Posts: 708
EnumCompareMultiSet - help needed to complete it
« on: August 29, 2021, 10:21:24 AM »
I've been using Deek's StringCompareMultiSet and variants I modified from the original with great success.
I'm not coming up with a variant using FsmEnums but it does not work. The comparison doesn't manage to identify a match even when there is one.

My feeling here is that for some reason the CompoundArray is not working properly with the enums because it's a double "structure", with a Type and a Value or Variable ID/name.
The first FsmEnum is the one which will be compared to each enum in the entry ( compare[i] ) in the CompoundArray, the second will be modified by the associated value in case of a positive match by the defined value ( set[i] ).

Here's the code below. I have added temporary debuglog lines reporting what values are currently being used or compared.
As indicated in the notes, I also added a line that was missing and which now allows sending an event for zero matches.

Code: [Select]
// License: Attribution 4.0 International (CC BY 4.0)
/*--- __ECO__ __PLAYMAKER__ __ACTION__ ---*/
// Author: Deek
// Enum variant: Broken Stylus
// Correction to the original script: corrected the NoMatchEvent that was raised on a positive match; added MatchEvent for any positive match

using UnityEngine;  //for the debug lines

namespace HutongGames.PlayMaker.Actions

[Tooltip("Sets an Enum value based on the value of another Enum variable. Optionally sends a Match-Event and a No-Match-Event.")]
public class EnumCompareSetMulti : FsmStateAction
        public FsmEnum enumToCompare;

        public FsmEnum enumToSet;

        [CompoundArray("Enum Switches", "Compare To", "Set With")]
        public FsmEnum[] compare;
        public FsmEnum[] set;

        [Tooltip("Event to raise if a matching Enum value is found.")]
        public FsmEvent MatchEvent;

        [Tooltip("Event to raise if no matching Enum value is found.")]
        public FsmEvent NoMatchEvent;

        public FsmBool everyFrame;

        public override void Reset()
            enumToCompare = null;
            enumToSet = null;
            compare = new FsmEnum[0];
            set = new FsmEnum[0];
            MatchEvent = null;
            NoMatchEvent = null;
            everyFrame = false;

        public override void OnEnter()

            if (!everyFrame.Value) Finish();

        public override void OnUpdate()

        void DoEnumSwitch()
            if (enumToCompare.IsNone) return;

            bool hasFound = false;

            Debug.Log("Enum to compare : " + enumToCompare.Name + " ; Its value: " + enumToCompare.Value);

            for (int i = 0; i < compare.Length; i++)
                if (enumToCompare.Value == compare[i].Value)
                    enumToSet.Value = set[i].Value;
                    hasFound = true;
                Debug.Log("Checking for : " + compare[i].Value + " ; Set with following value if matching: " + set[i]);
                var equal = Equals(compare[i].Value, set[i].Value);


            if (MatchEvent != null && hasFound) Fsm.Event(MatchEvent);
            if (NoMatchEvent != null && !hasFound) Fsm.Event(NoMatchEvent);



There is also another issue but that's more related to pragamtism and efficiency.
Every time an entry is added in the array, it generates both blank Type and Value/Variable for each FsmEnum. This is so annoying and a big time waster because all enums in the CompoundArray should be of the types defined at the beginning of the action: the first Type being that of the FsmEnum that's being probed (enumToCompare), the second Type being that of the FsmEnum that is simply the one that will be modified if there's a match (enumToSet).

I wish I could Reset(), or set up/populate the CompoundArray by using something like "ThisEnum.Type" and apply it to each respective Enum instance in the array.
Perhaps with something like var, I don't know. Maybe a method would be needed there but it would have to be activated again everytime an entry is added (and perhaps also removed) to the array.
Is it possible to call a method from inside the OnReset() block? Would this work?