I need a method to dynamically call different functions from a huge pile of functions.
.
A small example part of my problem;
There are passive defensive skills which automatically activate when the player about to takes damage.
Problem is there are hundreds of skills and only a couple of it active at a time.
I don’t want to call every single function and check if they are currently active,
.
For example, let’s say I have Functions as;
SuperBlock, Avoid, ThornMail, CounterAttack, X, Y, Z, SuperArmor … etc
.
And only “SuperBlock” is activated for the player so I only need to call SuperBlock function.
.
So basically I am trying to avoid doing this;
bool SuperBlockIsActive = true;
bool AvoidIsActive = false;
bool ThornMailIsActive = false;
bool CounterAttackIsActive = false;
public void DefensiveSkills(int damage, string attackType)
{
if (SuperBlockIsActive)
{
SuperBlock (damage, attackType);
}
if (AvoidIsActive)
{
Avoid (attackType);
}
if (ThornMailIsActive )
{
ThornMail (damage, attackType);
}
if (CounterAttackIsActive )
{
CounterAttack (damage, attackType);
}
}
....
I tried to solve this problem with “Invoke” function but because I need to pass parameters I couldn’t achieve what I needed.
What I did was creating a list of active function names and calling them with Invoke.
private List<string> ActiveDefensiveSkills = new List<string>();
private void StartTurn()
{
foreach (string function in ActiveDefensiveSkills)
{
Invoke(function, 0f);
}
}
I need to call functions with parameters like damage, attackType, etc.
I also tried using global variables but because the compiler does not wait for Invoke and continue the code, it doesn’t work either.
.
How can I solve this problem?
Is there even a way?
.
Edit:
I decided to share the whole idea just to be more clear so you don’t need to read the rest if you are not interested in my code, I am doing a turn-based game and some attack directly hurt the player (Like getting attacked with a sword) and some attacks give damage each turn (Like burn damage for 3 turns).
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Conditions
{
public string attackName;
public int attackDamage;
public string attackType;
public int attackTurn;
public int attackPenetration;
public void NewCondition(string aName, int aDamage, string aType, int aTurn, int aPenetration)
{
attackName = aName;
attackDamage = aDamage;
attackType = aType;
attackTurn = aTurn;
attackPenetration = aPenetration;
}
}
public class Player : MonoBehaviour
{
[Header("[Current]")]
[SerializeField] private int currentHealth = 0;
[Header("[Basic]")]
[SerializeField] private int maxHealth = 100;
[Header("[Defensive]")]
[SerializeField] private int armor = 0;
[SerializeField] private int magicResistance = 0;
[SerializeField] private float blockChance = 0f;
[Header("[ActiveSkills]")]
[SerializeField] private List<string> ActiveDefensiveSkills = new List<string>(); //Trigger when get attacked
[SerializeField] private List<Conditions> ActiveConditions = new List<Conditions>(); //List of active Conditions
//---MainFunctions----
private void StartTurn()
{
//Activated at the beginning of Player's each turn
foreach (Conditions condition in ActiveConditions)
{
Defense(condition.attackDamage, condition.attackType, condition.attackPenetration);
condition.attackTurn--;
if (condition.attackTurn <= 0) ActiveConditions.Remove(condition);
}
}
public void GetAttacked (string attackName, int attackDamage, string attackType, int attackTurn, int attackPenetration)
{
//Enemy calls this function and everything starts from here, after applying the first damage if the attack is turn-based then it gets added to conditions.
Defense(attackDamage, attackType, attackPenetration);
if (attackTurn > 1)
{
attackTurn--;
Conditions condition = new Conditions();
condition.NewCondition(attackName, attackDamage, attackType, attackTurn, attackPenetration);
ActiveConditions.Add(condition);
}
}
private void Defense(int attackDamage, string attackType, int attackPenetration)
{
//Function called when the player takes damage
//This is where I have a problem, I want to call only active defensive skills (their name is stored in "ActiveDefensiveSkills")
foreach (string function in ActiveDefensiveSkills)
{
// attackDamage = function(int attackDamage, string attackType, int attackPenetration); i want to do something like this
}
TakeDamage(attackDamage);
}
private void TakeDamage(int damage)
{
//Implement the damage
Debug.Log("You took " + damage + " dmg");
if (currentHealth - damage <= 0)
{
currentHealth = 0;
Death();
}
else
{
currentHealth -= damage;
}
}
private void Death()
{
Debug.Log("You Died");
}
//---SkillFunctions---
private int Block(int attackDamage, string attackType, int attackTurn, int attackPenetration)
{
//Player can block the some of the incoming damage
if (blockChance >= Random.Range(1, 101))
{
Debug.Log("Damage blocked");
return attackDamage / 2;
}
else return attackDamage;
}
private int Resistance(int attackDamage, string attackType, int attackTurn, int attackPenetration)
{
//Decrease the incoming damage
int result = armor - attackPenetration;
if (result < 0) result = 0;
return attackDamage - result >= 0 ? attackDamage - result : 0;
}
private int LastStand(int attackDamage, string attackType, int attackTurn, int attackPenetration)
{
//Player health will not drop under 1
return currentHealth - attackDamage >= 1 ? attackDamage : 0;
}
private int Invulnerability(int attackDamage, string attackType, int attackTurn, int attackPenetration)
{
//Player become invulnerable to any kind of attacks
return 0;
}
}