- Home /
Using Master Function to Call Abilities
I'm making a MOBA game that follows the lock-step model and needs a centralized function to send over key variables to identify abilities. To organize the abilities of characters, I'd ilke to be able to call an ability with a master function. I expect to have upwards 20 abilities so I need a way to send across a parameter to the master function which the master function will use to execute the ability identified by the parameter. Every single ability sent over the network will be stored in a custom struct that has a delegate representing the ability to be executed later. My main problem is identifying the ability with some kind of editor-inputed variable (like a string or int). To solve this, I think I need some way to initialize all the method variables (delegates, I guess) pre-runtime and store those in a dictionary.
A clearer explanation:
void Update()
{
if (Input.GetKey(Keycode.Space))
{
CallAbility("Fireball");//Executes the method that calls abilities
}
}
CallAbility(string AbilityName)
{
//Executes the method of the ability identified by AbilityName
}
DoFireball() //This method is identified by "Fireball"
{
Instantiate (LeFireball);
}
This will result in shooting a fireball on the start frame.
In short, I need an ability manager - a centralized function I can call when I need to execute an ability.
Update: Revealed more context for the issue.
Answer by jpthek9 · Jan 07, 2015 at 08:53 PM
Invoke ("AbilityName")
That was all I needed :p
Special thanks to InvincibleCat for reminding me of that method.
I'll definitely look into purchasing your asset. Can I do something like write a spacecraft's profile (health, shield, attack, description, etc.) with it? I noticed in the image that there was the player's stats in a single box. Can I do something like that with my own variables/struct?
Like in the first image? It's basically a $$anonymous$$onoBehavior. I can test for you if you need anything specific.
Oh, it's okay. I just looked into your asset a bit further and it's perfect! One thing I really need for my project is easy ability editing in the inspector.
Thanks :) I hope it will help you as much as it helps me ;)
Answer by InvincibleCat · Jan 07, 2015 at 07:35 PM
I would use an enum that can be set in the editor:
public enum E_Ability
{
FireBall,
SoccerBall
}
//editable in the inspector
public E_Ability Ability = E_Ability.FireBall;
public Action DoAbility = null;
private void Start()
{
SetAbility();
}
public void SetAbility()
{
switch (Ability)
{
case (E_Ability.FireBall):
{
DoAbility = DoFireBall;
break;
}
case (E_Ability.SoccerBall):
{
DoAbility = DoSoccerBall;
break;
}
}
}
private void DoFireBall()
{
}
private void DoSoccerBall()
{
}
So each time you will call DoAbility(), it will call the good function regarding to the enum.
Cheers ;)
You can still update the switch method ;) I don't really like that kind of solution but you can still use $$anonymous$$ethod.Invoke("$$anonymous$$ethodName") With Generic Inspector -> https://www.assetstore.unity3d.com/en/#!/content/25485 You can link a collection to an enum and the collection can be a popup of method names (so really easy to use)
But I'm not sure I really get what you need. If it's like your character need on start to use a specific skill, you should have an abstract class ($$anonymous$$onobehaviour) with DoSkill method and then each of your skills will derive from your abstract class. Just add the component you need and call the function. Is that makes any sense?
So this
You can still update the switch method ;) I don't really like that kind of solution but you can still use $$anonymous$$ethod.Invoke("$$anonymous$$ethodName") With Generic Inspector -> https://www.assetstore.unity3d.com/en/#!/content/25485 You can link a collection to an enum and the collection can be a popup of method names (so really easy to use)
Should work.
Not really code heavy. You will have you enum E_AbilityTypes for example to declare all your different abilities. Then you will have a collection of string that contains the methods to call. All you will need to do with Generic Inspector is:
public enum E_AbilityTypes
{
AbilityOne = 0,
AbilityTwo = 1,
AbilityThree = 2,
//etc...
}
[$$anonymous$$nEnumCollection(typeof(E_AbilityTypes))]
[$$anonymous$$n$$anonymous$$ethodNames("self")]
public string[] Ability$$anonymous$$ethods = null;
Then when you will need to call the method. You will just need to do something like:
E_AbilityTypes myAbility;
string method = Ability$$anonymous$$ethods[myAbility];
Invoke(method);
InvincibleCat, you are a GENIAS!!!
I will just store the string in my struct and invoke it when the time comes. Invoke = ability manger. No need for fancy delegates.
Answer by tanoshimi · Jan 07, 2015 at 07:27 PM
Sounds like you want to use delegates.
I watched Unity's tutorial and I'm still not completely sure how I can rig up a system like this with delegates. Do you $$anonymous$$d explaining?
you could do something like the following (bear in $$anonymous$$d that I am rather new to delegates myself, there may be a better way of doing this example):
public delegate void AbilityDelegate();
AbilityDelegate abilityDelegate = DoFireball;
void Start () {
abilityDelegate();
Debug.Log("=======================");
abilityDelegate = DoIceball;
abilityDelegate();
Debug.Log("=======================");
abilityDelegate = DoFireball;
abilityDelegate += DoIceball;
abilityDelegate();
Debug.Log("=======================");
abilityDelegate -= DoFireball;
abilityDelegate();
Debug.Log("=======================");
}
public static void DoFireball(){
Debug.Log("creating fireball");
}
public static void DoIceball(){
Debug.Log("creating iceball");
}
Scribe
Thanks for the suggestion. I want to clarify that calling the ability in the Start method is only for context. In the game, it will actually be called from a UI button and the parameter there from where my partner will take over (he's designing the ability system and UI).
I need methods to be identified by a string of integer. I've been thinking of several ways:
Somehow convert a string to the method's name.
Use a dictionary with keys pointing to the method.
Use delegates which I'm still not totally sure how they work to make this happen.
All of which I'm missing key elements.
Didn't my solution works??? (Action is basically a delegate)
I just restructured my game when I ran into an issue similar to the one you are talking about. First off, I would make a SkillsClass. It would have Skill 1-n, where n is the number of skills placed on hotbar/gui. I would then make a script for each of your skills that extend the SkillsClass and attach them directly to the skillObjects that get instantiated. Execute skills from the GUI based on where the skills are. Hope that makes sense. This way though, the GUI just has to call something like,
InstantiateSkill(skillHotbarIndex){ Instantiate(getSkillObjectFromHotBarIndexArray(Index)); }
Of course the background array would need to be the same length as total number of skill slots on hotbar. If that makes sense.