Building action bar by using variables to dynamically refer to functions

I’m currently building an action/spell bar much like what you’d find in MMOs or Diablolike games, in which the user can bind whatever skill they wish to each of 10 (in this case) buttons on the HUD. I’m planning on having a great many skills, so I was trying to figure out a way to use the same function that switches textures on the ability slots to refer to which function that button should call- for example clicking and dragging the lockpicking icon would set some string button1Action equal to “lockpicking”, and the only code inside the onbutton would be to call button1Action’s text as a function, in this case lockpicking(); . This way I could make one class with nothing but skill functions, and grab them from the HUD class.

Is this at all possible, or am I formulating my problem in an awkward way?

So I found a solution, but it feels very, very inefficient:

private string button1Skill;
private string button2Skill;
private string button3Skill;

Whenever the player changes what a button does I set that button’s string to the newly assigned skill’s name, then run

if(GUI.Button (new Rect((Screen.width/8),(Screen.height - 100),50,50), actionTexture1, “label”)){
gameObject.SendMessage(button1Skill);

It works, but I don’t like that I’m running sendmessage every time someone uses a skill- am I missing an obvious optimization somewhere?

Using SendMessage when someone uses a skill is a non-issue. Optimizing that will make zero difference. You can use delegates though if you want a different way. If you ever find yourself using repetitive variables like “button1Skill”, “button2Skill”, etc., that means you should be using an array of some kind.

–Eric

Oh that’s a great idea, making one buttonskilll array would also make it trivial to generate buttons and their strings iteratively, which opens up some customization options, thanks!

I’m just learning about delegates (they’re one of the things I stumbled upon while researching this problem), is there any clear-cut consensus regarding when it’s preferable to use delegates versus sendmessage, or does it all come down to preference and the eccentricities of your project?

Hmm this is weird, in rearranging things to iterate the icon generation I seem to have broke something- right now, I’m running the following:

private string[ ] buttonAction;

void OnGUI(){
DisplayActionBar ();
}

public void DisplayActionBar(){
for (int cnt = 0; cnt < 10; cnt++) {
buttonAction[cnt] = “NoSkill”;
if (GUI.Button (new Rect ((Screen.width / 8), (Screen.height - 100), 50, 50), blankActionTexture, “label”)) {
gameObject.SendMessage (buttonAction[cnt]);
}
}

}

This doesn’t pop an error, but when I run it, it tells me:

NullReferenceException: Object reference not set to an instance of an object
(wrapper stelemref) object:stelemref (object,intptr,object)
ActionBar.DisplayActionBar () (at Assets/Scripts/HUD Classes/ActionBar.cs:44)
ActionBar.OnGUI () (at Assets/Scripts/HUD Classes/ActionBar.cs:31)

Two scripts are being used- Action Bar, which is the tiny function that draws my bar and lets me drag drop icons, and ActionDatabase, which contains functions for each skill (and a debug function NoSkill that gets called if the player activates an empty skill box). Both scripts are attached to the same object, Is gameObject.sendmessage somehow not finding ActionDatabase?

Blah fixed it, I forgot to initialize buttonAction- it all works now, hurray! :slight_smile:

i’ve actually used something like this approach a bunch in all kinds of settings.

One thing that I also like doing is make a class to contain the arguments. This opens some interesting doors, like being able to pass around a command, or save it, etc.

Sorta looks like this:

class Command{
  public x Target;
  public int X, Y;
  public void Execute(){ ... }
}

Sometimes, I also split it out a level further and do something like:

class MoveCommand{
  public List<Command> GetAllValidCommands( x actor ){ ... }
}

I think the approach works pretty well, but it can also be overkill depending on how many commands you need.

Things this approach helps do well:

  • lends itself to writing decent ai scripts
  • you can use the “getallvalid” to provide highlights or target prompts.