Hello,
From time to time I’ve found myself in this position:
switch (parentClicked.name){
case "Damage":
for (int i = 0; i < availableWeapons.Count; i++) {
if (weaponSpriteName == availableWeapons *.weaponName)*
calculatedValue = CalculateUpgrade ( availableWeapons .damage, availableWeapons .damageLevel);
* }*
* break;*
* case “Accuracy”:*
* for (int i = 0; i < availableWeapons.Count; i++) {*
_ if (weaponSpriteName == availableWeapons .weaponName)
calculatedValue = CalculateUpgrade ( availableWeapons .accuracy, availableWeapons .accuracyLevel);
* }
break;*_
* case “AmmoQuantity”:*
* for (int i = 0; i < availableWeapons.Count; i++) {*
_ if (weaponSpriteName == availableWeapons .weaponName)
calculatedValue = CalculateUpgrade ( availableWeapons .ammoQuantity, availableWeapons .ammoLevel);
* }
break;*_
* case “RateOfFire”:*
* for (int i = 0; i < availableWeapons.Count; i++) {*
_ if (weaponSpriteName == availableWeapons .weaponName)
calculatedValue = CalculateUpgrade ( availableWeapons .rateOfFire, availableWeapons .rateOfFireLevel);
* }
break;
}*
Basically using the switch statement with the for state too much. And this is just an example. That for statement in the switch statement is much bigger sometimes.
But, i can’t, or i don’t know a way around to only use a function like this:
public void TestFunction (float upgradeParameter, float upgradeLevel){_
* for (int i = 0; i < availableWeapons.Count; i++) {*
_ if (weaponSpriteName == availableWeapons .weaponName)
calculatedValue = CalculateUpgrade ( availableWeapons .upgradeParameter, availableWeapons .upgradeLevel);
* }
}
And in the switch statement i would pass the parameters to the TestFuction (float upgradeParameter, float upgradeLevel)._
But this doesn’t work because availableWeapons _.upgradeParameter and availableWeapons *.upgradeLevelobviously don’t exist in the availableWeapons[].
Can anyone please enlighten me on this simple matter of avoiding too much switches or too much fors?_
In a first step you could simplify it like this:
float upgradeParameter = 0.0f;
float upgradeLevel = 0.0f;
Weapon weapon = FindWeapon( parentClicked.name );
if( weapon )
{
switch (parentClicked.name)
{
case "Damage":
upgradeParameter = weapon.damage;
upgradeLevel = weapon.damageLevel;
break;
case "Accuracy":
upgradeParameter = weapon.accuracy;
upgradeLevel = weapon.accuracyLevel;
break;
case "AmmoQuantity":
upgradeParameter = weapon.ammoQuantity;
upgradeLevel = weapon.ammoLevel;
break;
case "RateOfFire":
upgradeParameter = weapon.rateOfFire;
upgradeLevel = weaponrateOfFireLevel;
break;
}
calculatedValue = upgradeParameter ( value, upgradeLevel );
}
// ****
Weapon FindWeapon( string name )
{
for (int i = 0; i < availableWeapons.Count; i++)
{
if (name == availableWeapons *.weaponName)*
return availableWeapons ;
}
return null;
}
If that same switch would occur more than once, you could move that into weapon class.
Hi @Subject-Gabz,
The for-loop can be simplified by doing it once in advance to get the target weapon. (I’m assuming you’re always targeting one weapon at a time).
That way you would end up with this:
// ..........
public void Example()
{
ExampleWeapon targetWeapon = null;
for( int i = 0; i < availableWeapons.Count; i++ )
{
if( weaponSpriteName == availableWeapons[ i ].weaponName )
{
targetWeapon = availableWeapons[ i ];
}
}
if( targetWeapon != null )
{
switch( parentClicked.name )
{
case "Damage":
calculatedValue = CalculateUpgrade( targetWeapon.damage, targetWeapon.damageLevel );
break;
case "Accuracy":
calculatedValue = CalculateUpgrade( targetWeapon.accuracy, targetWeapon.accuracyLevel );
break;
case "AmmoQuantity":
calculatedValue = CalculateUpgrade( targetWeapon.ammoQuantity, targetWeapon.ammoLevel );
break;
case "RateOfFire":
calculatedValue = CalculateUpgrade( targetWeapon.rateOfFire, targetWeapon.rateOfFireLevel );
break;
}
}
}
// ..........
Personally, since you’re using WeaponStat.value + WeaponStat.level variables a lot, I would refactor it into this, by adding a WeaponStat class to your Weapon class. This WeaponStat would have the CalculateUpgrade method built-in:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Simplify : MonoBehaviour
{
private List<ExampleWeapon> availableWeapons = new List<ExampleWeapon>();
private string weaponSpriteName;
private Transform parentClicked;
private float calculatedValue;
public void Example()
{
ExampleWeapon targetWeapon = null;
// Get target weapon.
for( int i = 0; i < availableWeapons.Count; i++ )
{
if( weaponSpriteName == availableWeapons[ i ].weaponName )
{
targetWeapon = availableWeapons[ i ];
}
}
// Only proceed if a weapon was found.
if ( targetWeapon != null )
{
// Calculate upgrade.
switch( parentClicked.name )
{
case "Damage":
calculatedValue = targetWeapon.damage.CalculateUpgrade();
break;
case "Accuracy":
calculatedValue = targetWeapon.accuracy.CalculateUpgrade();
break;
case "AmmoQuantity":
calculatedValue = targetWeapon.ammoQuantity.CalculateUpgrade();
break;
case "RateOfFire":
calculatedValue = targetWeapon.rateOfFire.CalculateUpgrade();
break;
}
}
}
}
// Applied your code styling here. (normally I'd use Damage or m_damage)
public class ExampleWeapon
{
public string weaponName;
public WeaponStat damage;
public WeaponStat accuracy;
public WeaponStat ammoQuantity;
public WeaponStat rateOfFire;
}
public class WeaponStat
{
public float value;
public float level;
public float CalculateUpgrade()
{
// Just an example.
return value * (level + 1);
}
}
You could then add / edit variables to your needs whilst keeping it more compact.
You’re also detecting the variable you wish to edit via Parent Name. There’s so more gain to be had there, but that’s a bit more complicated, haha.
I hope that helps, if it did, please accept this answer, it’d be much appreciated!
If you need any more details, let me know! 
Best of luck!
Cheers,
ThePersister