#i dont really understand what you mean,
1 messages · Page 1 of 1 (latest)
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.
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
You can pass the enum directly
and i ofc mean have a custom event that provides the enum to the subscriber on click.
but not dynamically since the onclick event is just UnityAction delegate that doesn't accept parameters
I tried adding [Serializable] above the enum but it never showed up
[SerializeField]...
enum is serializable by default
Yeah I thought so since it's by value
okay let me give an example incase you are confused about something
So the below is supposed to show up in the inspector just like the int does?
{
// Logic here
}
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));
}
}
Nvm I guess you can't use enum directly with unity event in inspector, lame
Yeah, bit bothersome
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
rob's approach is solid
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
You could use UnityEvent instead in that case
if you want to fire from external class, or just add a public method that fires the event
I want to keep it completely internal
So events in this case would be unecessary plumbing, There's already the onClick
[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 🫡
Yeah I don't see how it wouldn't be internal with this
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?
I believe so yes
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
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
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
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);
}
}
Yeah exactly, a normal C# event would work here too