Search Unity

More efficient way to selecting weapon attack

Discussion in 'Scripting' started by Emolk, Dec 3, 2019.

  1. Emolk

    Emolk

    Joined:
    Feb 11, 2014
    Posts:
    241
    So i have weapons in my game, and each weapon does a specific function or attack (no melee weapons yet). I have an Attacks.cs script shown below. Player's can place items into different hotbars, and the attack function is selected based on the items added. This is done through a bunch of if statements which is equal to the number of weapons in the game. I was wondering if there is a more efficient way of selecting weapon instead of hundreds of IF statements? As you can see below, the weapon name returns a function in 'attackSelection' which selects the attack. This is only done when the Player actually selects a different attack to be used, so isn't run very often. I'd imagine when i reach 100+ weapons, those IF statements won't look pretty but i can't think of a better way to do it. Any ideas?

    Attacks.cs below, a cut down version of the 550 line script with two attacks 'ArcaneBlast' and 'SniperBlast' to demonstrate how attacks work.

    Code (CSharp):
    1. public void updateSelection(){
    2.         selected = GetComponent<PlayerHotBar>().selected;
    3.         selectedOff = GetComponent<PlayerHotBar>().selectedOff;
    4.  
    5.         attackFunction = attackSelection(selected);
    6.         attackFunctionOff = attackSelection(selectedOff);
    7.     }
    8.  
    9.     void Update(){
    10.         mana = player.GetComponent<PlayerStats>().mana;
    11.  
    12.         try
    13.         {
    14.             if (Input.GetButton("Main") && !EventSystem.current.IsPointerOverGameObject()){
    15.             attackFunction();
    16.             }
    17.             if (Input.GetButton("Alt") && !EventSystem.current.IsPointerOverGameObject()){
    18.                 attackFunctionOff();
    19.             }
    20.         }
    21.         catch
    22.         {
    23.            
    24.             Debug.Log("No attack selected");
    25.         }
    26.  
    27.         if (Input.GetKeyDown(KeyCode.Q)&& (mana > magicBallCost)) {
    28.             player.GetComponent<PlayerStats>().loseMana(magicBallCost);
    29.             spawnMagicBall();
    30.         }
    31.  
    32.         if(currentZombies.Count > 0){
    33.             currentZombies.RemoveAll(GameObject => GameObject == null);
    34.         }
    35.     }
    36.  
    37.     AttackMethod attackSelection(Equipment Equipped){
    38.  
    39.         if(Equipped != null){
    40.  
    41.                 if(Equipped.name == "Wand_Stream"){
    42.                     return Electric_Ball;        
    43.                 }
    44.  
    45.                 else if(Equipped.name ==  "Launcher"){
    46.                     return missile_Homing;
    47.                 }
    48.  
    49.                 else if(Equipped.name == "Staff_Lightning"){
    50.                     return Lightning_Ball;
    51.                 }
    52.  
    53.                 else if(Equipped.name == "Staff_Explosion"){
    54.                     return Explosion;
    55.                 }
    56.  
    57.                 else if (Equipped.name == "Staff_Holy"){
    58.                     return karma;
    59.                 }
    60.  
    61.                 else if (Equipped.name == "Staff_Vine"){
    62.                     return ArcaneBlast;
    63.                 }
    64.  
    65.                 else if (Equipped.name == "Staff_Undead"){
    66.                     return ZombieAlly;
    67.                 }
    68.                 else if(Equipped.name == "Launcher_Seeker"){
    69.                     return missile_Seeker;
    70.                 }
    71.                 else if(Equipped.name == "SpawnEgg"){
    72.                     return throwEgg;
    73.                 }
    74.                 else if(Equipped.name == "Staff_Sword"){
    75.                     return clusterBombFire;
    76.                 }
    77.         }
    78.         return doNothing;
    79.     }
    80.  
    81.     void doNothing(){
    82.     }
    83.  
    84.     void ArcaneBlast(){
    85.         if(arcaneBlastOffCD == true){
    86.             Vector3 sp = Camera.main.WorldToScreenPoint(transform.position);
    87.             Vector3 dir = (Input.mousePosition - sp).normalized;
    88.  
    89.             GameObject objectInstance = Instantiate(arcaneBlast,
    90.             gameObject.transform.position, Quaternion.Euler(new Vector3(0, 0, 0)));
    91.  
    92.             objectInstance.GetComponent<Rigidbody2D>().AddForce(dir * 300f);
    93.  
    94.             arcaneBlastOffCD = false;
    95.             WaitAndDo(arcaneBlastAS, () => arcaneBlastOffCD = true);
    96.         }
    97.     }
    98.  
    99.     void SniperBlast(){
    100.         if(sniperBlastOffCD == true){
    101.             Vector3 sp = Camera.main.WorldToScreenPoint(transform.position);
    102.             Vector3 dir = (Input.mousePosition - sp).normalized;
    103.  
    104.             GameObject objectInstance = Instantiate(sniperBlast,
    105.             gameObject.transform.position, Quaternion.Euler(new Vector3(0, 0, 0)));
    106.  
    107.             // Points missile at mouse pos
    108.  
    109.             float rot_z = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
    110.             objectInstance.transform.rotation = Quaternion.Euler(0f, 0f, rot_z - 90);
    111.  
    112.             objectInstance.GetComponent<Rigidbody2D>().AddForce(dir * sniperBlastForce);
    113.  
    114.             sniperBlastOffCD = false;
    115.             WaitAndDo(sniperBlastAS, () => sniperBlastOffCD = true);
    116.         }
    117.     }
     
  2. AlexN2805

    AlexN2805

    Joined:
    Nov 27, 2019
    Posts:
    33
    My suggestion would be to add the weaponeffect to the equipment. This way you can call a generic "Equipped.doWeaponEffect()" without having to cycle through all possible options. This would require you to refactor some code, but it the end it will be more workable than having 100s upon 100s of if-statements.
     
  3. Emolk

    Emolk

    Joined:
    Feb 11, 2014
    Posts:
    241
    Do you mean create a script for each attack? How would that work with scriptable objects?