Nao
Nao

Reputation: 29

Modifying variables from another script

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 !

Upvotes: 0

Views: 832

Answers (2)

derHugo
derHugo

Reputation: 90862

Since your use case actually is executing a certain behavior every time a value gets set I would suggest to rather use Properties. There are two options depending on your needs some examples (see here for more examples)

// 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. I would combine it with a proper 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.

Upvotes: 2

rrswa
rrswa

Reputation: 1060

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.

Upvotes: 0

Related Questions