Question: I'm currently creating a C# script for Unity containing many variables, and I want these to be changeable from other scripts. 

To do so, I've currently written a function which asks the name of the variable (as a string) and then uses a switchcase for each variable.

```
public string charName;

public int currentHP;
public int maxHP = 100;

public int strength;
public int defense;

public void ChangeValue(string valueToChange, int howMuch)
{
    switch (valueToChange)
    {
        case "currentHP":
            currentHP += howMuch;
            break;

        case "maxHP":
            maxHP += howMuch;
            break;

        case "strength":
            strength += howMuch;
            break;

        case "defense":
            defense += howMuch;
            break;
    }
}

```

Would there be a more efficient way of doing this ? The switch case seems really inefficient, I'd need to modify it everytime I want to add a new variable to the script.

The perfect thing for me would be to ask the variable as an argument, but I can't figure out a way to do it.

Thank you for your time !

Answer: 
Since your use case actually is executing a certain behavior every time a value gets set I would suggest to rather use [Properties](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties). There are two options depending on your needs some examples (see [here for more examples](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/using-properties))

```
// Auto property which doesn't have any behavior
// read and write able
public string charName { get; set; }

// read only property
public int currentHP { get; private set; }

// read only property with a backing field
private int _maxHP = 100;
public int maxHP
{
    get { return _maxHP; }
}

// same as before but as expression body
private int _strength;
public int strength { get => _strength; }

// finally a property with additional behaviour 
// e.g. for the setter make sure the value is never negative 
private int _defense;
public int defense
{
    get { return _defense; }
    set { _defense = Mathf.Max(0, value); }
}

```

As you can see properties kind of replace getter and setter methods and in some cases even take the role of a field (Auto-Properties). In both the getter and the setter you can implement additional behavior. As soon as you do you have to use backing fields.

You can use and access them just like fields for example

```
someInstance.defense += 40;

```

executes both, first the getter in order to know the current value of `_defense`, then it adds `40` and uses the setter to write the result back to `_defense`.

---

As alternative and closer to your original approach is as said a [`Dictionary`](https://learn.microsoft.com/dotnet/api/system.collections.generic.dictionary-2). I would combine it with a proper [`enum`](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/enum) like e.g.

```
public enum ValueType
{
    MaxHP,
    Strength,
    Defense,
    CurrentHP
}

private Dictionary<ValueType, int> Values = new Dictionary<Value, int>
{
    {ValueType.MaxHP, 100},
    {ValueType.Strength, 0 },
    {ValueType.Defense, 0 },
    {ValueType.CurrentHP, 0 }
};

public void ChangeValue(ValueType valueType, int value)
{
    Values[valueType] += value;

    // do additional stuff
}

```

This has a minimal overhead of adding the values to be controlled by that method to both, the `enum` and the `Dictionary`.
You can directly change the values of variables from another script if they are public.

Suppose you have a player object:

```
class Player : MonoBehaviour {
    public int currentHP;
    public int maxHP = 100;
}

```

You can access these values from another class as follows

```
class Enemy : MonoBehaviour {

    public Player player;

    void Start() {
        player.currentHP -= 10;
    }

}

```

You just have to assign `player` in the Unity Editor by dragging and dropping it onto, in this case, the `Enemy` script.