【问题标题】:Modifying variables from another script从另一个脚本修改变量
【发布时间】:2019-08-22 19:37:58
【问题描述】:

我目前正在为 Unity 创建一个包含许多变量的 C# 脚本,并且我希望这些可以从其他脚本中更改。

为此,我目前编写了一个函数,它询问变量的名称(作为字符串),然后为每个变量使用一个 switchcase。

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;
    }
}

会有更有效的方法吗? switch case 似乎效率很低,每次我想在脚本中添加新变量时都需要修改它。

对我来说最完美的方法是将变量作为参数询问,但我想不出办法。

感谢您的宝贵时间!

【问题讨论】:

  • 为什么不定义适当的interface 并公开它?
  • 既然都是公开的,为什么不直接访问这些字段呢?
  • 我稍后在修改变量时必须执行其他函数,这就是我无法直接访问它们的原因。我正在研究我不知道的接口,它们可能是我的问题的解决方案,谢谢!
  • 我不明白……还有什么功能?也许你想看看properties。在那里,您可以在设置属性时简单地添加一些检查或其他行为...example。否则我宁愿建议Dictionary<string, int> 使用正确的enum 而不是字符串会更有效
  • 属性非常适合我的需要!非常感谢!

标签: c# unity3d


【解决方案1】:

由于您的用例实际上是在每次设置值时执行某种行为,我建议宁愿使用Properties。根据您的需要有两个选项一些示例(请参阅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); }
}

正如您所见,属性取代了 getter 和 setter 方法,在某些情况下甚至充当字段的角色(自动属性)。在 getter 和 setter 中,您都可以实现其他行为。一旦你这样做了,你就必须使用支持字段。

您可以像使用字段一样使用和访问它们

someInstance.defense += 40;

执行两者,首先是 getter 以了解 _defense 的当前值,然后添加 40 并使用 setter 将结果写回 _defense


正如Dictionary 所说,作为替代方法并且更接近您的原始方法。我会将它与适当的enum 结合起来,例如

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
}

将要由该方法控制的值添加到enumDictionary 的开销最小。

【讨论】:

    【解决方案2】:

    如果变量是公开的,您可以直接从另一个脚本更改变量的值。

    假设你有一个播放器对象:

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

    您可以从另一个类中访问这些值,如下所示

    class Enemy : MonoBehaviour {
    
        public Player player;
    
        void Start() {
            player.currentHP -= 10;
        }
    
    }
    

    您只需在 Unity 编辑器中将 player 拖放到 Enemy 脚本上即可。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-09
      • 2022-10-23
      • 2017-11-07
      • 1970-01-01
      • 2022-07-16
      • 1970-01-01
      • 2011-02-08
      相关资源
      最近更新 更多