Ideas to keep my code efficient?

I’m trying to create a generic function to calculate damage from ranged attacks. The attacker can be either the player’s or the enemies unit. Either way I want to access the rangedToHit from the attacker and the evasion, armorRating and hitPoint’s from the unit being attacked. I was hoping to load two transform variables, victim and culprit with the scripts based on whether the attacker is the player or enemy which would simplify the rest of the function. However, since I am trying to define and load the variables in an if statement, I can’t access them outside of it. Can anyone think of an efficient way to handle this without having to have an if statement and duplicate logic in each switch case?

//Used to calculate the damage from a spell or ranged attack
    void CalculateRangedDamage(string attackname, GameObject target, GameObject attacker)
    {
        //get a random number between 1 and 100
        int a = Random.Range(1, 100);

        if (attacker.tag == "Enemy")
        {
            playerScript victim;
            enemyScript culprit;
            culprit = attacker.GetComponent<enemyScript>();
            victim = target.GetComponent<playerScript>();
        }
        else if (attacker.tag == "Player")
        {
            playerMove culprit;
            enemyMove victim;
            victim = attacker.GetComponent<enemyScript>();
            culprit = target.GetComponent<playerScript>();
        }
        else
        {
            Debug.Error("Attacker is invalid in CalculateRangedDamage.")
        }

        switch (attackname) //Check the passed in spell
        {
            case "flamesphere" :
                if (a <= culprit.rangedToHit)
                    //Do calculation

            case "crossbow: :
                if (a <= culprit.rangedToHit)
                    //Do calculation

Why don’t you try creating the variable in the main scope of the function CalculateRangedDamage?

Like this →
//Used to calculate the damage from a spell or ranged attack
void CalculateRangedDamage(string attackname, GameObject target, GameObject attacker)
{
//get a random number between 1 and 100
int a = Random.Range(1, 100);

         playerScript victim;
         enemyScript culprit;

         if (attacker.tag == "Enemy")
         {
             culprit = attacker.GetComponent<enemyScript>();
             victim = target.GetComponent<playerScript>();
         }
         else if (attacker.tag == "Player")
         {
             victim = attacker.GetComponent<enemyScript>();
             culprit = target.GetComponent<playerScript>();
         }
         else
         {
             Debug.Error("Attacker is invalid in CalculateRangedDamage.")
         }
 
         switch (attackname) //Check the passed in spell
         {
             case "flamesphere" :
                 if (a <= culprit.rangedToHit)
                     //Do calculation
 
             case "crossbow: :
                 if (a <= culprit.rangedToHit)
                     //Do calculation

Of course, you will have to do a null check before accessing the two variables elsewhere, but at least this way, you dont have to repeat the code in each switch case.