#i dont really understand what you mean,

1 messages · Page 1 of 1 (latest)

sturdy bloom
#

So I have a UI which lets user attack from left center or right. This is happening in the CombatBoard class and that should contain all the necessary setup data.

The buttons themselves won't be expoed to anyone else and the onClick binding I'm trying to do is required for just this class. Exposing external events to the plain button click wouldn't be much use without the class own filtration first.

At the same time using events to internally pass data within that class wouldn't be my top choice either.

#

Looks like I could expose a method with an int which would get converted to ECombatDirection (left, center and right) ... but that looks dirty too. I'll forget what 0, 1 and 2 are in reference to and fk this up somehow. So plain methods it is.

I'll setup 3 dedicated methods for the direction and just have the buttons directly bound to those.

still gorge
#

I would have a script that has the enum serialized on it, place that on each dir button, and have the script managing this UI sub to the event on each of these (via some list)
then on click it gets the enum and can do whatever

still gorge
#

and i ofc mean have a custom event that provides the enum to the subscriber on click.

twin pier
#

but not dynamically since the onclick event is just UnityAction delegate that doesn't accept parameters

sturdy bloom
#

I tried adding [Serializable] above the enum but it never showed up

still gorge
#

[SerializeField]...

twin pier
#

enum is serializable by default

sturdy bloom
#

Yeah I thought so since it's by value

still gorge
#

okay let me give an example incase you are confused about something

sturdy bloom
#

So the below is supposed to show up in the inspector just like the int does?

        {
            // Logic here
        }
still gorge
#
public enum Direction {Left, Right, Up, Down}

public class DirectionButton : MonoBehaviour
{
    public event Action<Direction> OnClick;

    [SerializeField]
    Direction direction;

    [SerializeField]
    Button button;

    private void Awake()
    {
        button.onClick.AddListener(() => OnClick?.Invoke(direction));
    }
}
twin pier
still gorge
#

Look at some point you have to move past using the UI and sub in code

#

my example above uses a "normal" event so you must subscribe with code

twin pier
#

rob's approach is solid

sturdy bloom
#

Sure but I would then have to subscribe to the same events within that same class... Would be useful if I wanted those events to fire for external classes but not for the same classes that invokes them

#

Which I understand is not clear with my question. I was keeping it very strictly scoped to finding some coding hack to get around the UnityAction limitations

twin pier
#

if you want to fire from external class, or just add a public method that fires the event

sturdy bloom
#

I want to keep it completely internal

#

So events in this case would be unecessary plumbing, There's already the onClick

still gorge
#
[SerializeField]
List<DirectionButton> directionButtons;

void Awake()
{
    foreach(var button in directionButtons)
    {
        button.OnClick += DirectionButtonClick;
    }
}

id do this, if you want to do some other weird design i wish you luck 🫡

twin pier
#

Yeah I don't see how it wouldn't be internal with this

sturdy bloom
#

Then I should read on UnityEvents 😅

#

I'll give them a peek, cheers

#

So to avoid going into a wall with this, on the class that goes on the button I called CombatSquare I can give it a UnityEvent<ECombatDirection>

I can subscribe in the Inspector itself to the CombatBoard or from the CombatBoard programmatically to each button and the ECombatDirection would get included in the call. So all I'd have to do is expose the expected direction that I set from the inspector?

twin pier
#

you just have to subscribe to the events in code

#

I don't see why a regular C# event wouldn't suffice here though

#

I don't understand what you are trying to do in the inspector though

sturdy bloom
#

Holy cow this is the ticket! And maybe I also missed a simpler way of settings things up as you're mentioning but I can even pass in a complex type, not by value only. So I can merge the attack and defense squares together

twin pier
#

Yeah, unity event parameters are very limited in the inspector. Only supports very few types and can only have one parameter.

#

I don't really use them in the inspector, and wire everything up through code

sturdy bloom
#
        public UnityEvent<CombatAction> activated;
        private void OnEnable() => button.onClick.AddListener(TriggerActivation);

        private void OnDisable() => button.onClick.RemoveListener(TriggerActivation);

        private void TriggerActivation() => activated?.Invoke(new CombatAction(_combatAction, direction));

That covers the square to pass in whether it's attack or defense and which direction I have setup for it.

And in the Board I just do:

        [SerializeField] private CombatSquare[] squares = new CombatSquare[6];

        private void OnEnable() => RegisterSquares(true);

        private void OnDisable() => RegisterSquares(false);

        private void TriggerAction(CombatAction action) => playerCombat.QueueActionInput(action);
        
        private void RegisterSquares(bool add)
        {
            foreach (CombatSquare square in squares)
            {
                if (add)
                    square.activated.AddListener(TriggerAction);
                else
                    square.activated.RemoveListener(TriggerAction);
            }
        }
twin pier
#

Yeah exactly, a normal C# event would work here too

sturdy bloom
#

🤔 Let my slow brain catch up to that 🤣

#

Fk you're right 🤦‍♂️

#

So I'll just ... do that then, no point for the inspector crap