是否有一种无需先获取脚本即可获取和更改公共变量的方法?

时间:2019-12-17 21:57:08

标签: c# unity3d

我有一个可以激活其他对象的按钮。在这种情况下,它是一个物理按钮,可以通过用玩家GameObject触摸它来激活。它使用此脚本来激活其他对象:

    public GameObject[] ThingsToActivate = { };

    void Update()
    {
        if (activated)
        {
            foreach (var Object in ThingsToActivate)
            {
                Object.GetComponent<foo>().Active = true;
            }
        }
    }

这对 pretty 很好,但这意味着您放入ThingsToActivate数组中的所有内容都必须具有一个名为foo的脚本。我想将此按钮放在资产商店上,但我希望它非常易于使用。我想这样做,以便您可以将脚本命名为任意名称,只要它具有public bool Active变量即可。

有没有简单的方法来执行此操作,例如搜索所有专门针对该变量的脚本,或者某种解决方法?

3 个答案:

答案 0 :(得分:2)

要获取所有类型的所有组件,请使用GetComponents<Component>()

要检查组件是否具有称为“活动”的属性,请使用GetType().GetProperty("Active")。如果它返回PropertyInfo实例,则可以使用其SetValue方法进行设置。

if (activated)
{
    foreach (GameObject object in ThingsToActivate)
    {
        foreach (Component component in object.GetComponents<Component>())
        {
            var prop = component.GetType().GetProperty("Active");
            if (prop != null) prop.SetValue(component, true);
        }
    }
}

答案 1 :(得分:1)

您可以使用反射:

foreach (var Object in ThingsToActivate)
{
      var prop = Object.GetComponent<foo>().GetType().GetPropery("Active");
      if(prop != null && prop.PropertyType == typeof(bool)
          prop.SetValue(Object.GetComponent<foo>(), true);
}

答案 2 :(得分:0)

这是哪种按钮?为什么每个想要使用它的人都不可能从某个Type继承?

我不会在这里明确使用反射!

作为用户/开发人员,我真的不想使用您的按钮资产,然后想知道为什么它还会更改我自己的某些自定义组件中的字段,而这些组件最终具有称为Active的字段/属性;)


我宁愿建议使用必须继承的专用父类,例如

public abstract class YourButtonListener : MonoBehaviour
{
    // I would even use a property here
    // you'll see below why
    public virtual bool Active { get; set;}
}

并将其用作类型,因此是的,明确强制您的用户/开发人员将其明确用作类型

public YourButtonListener[] ThingsToActivate;

foreach(var listener in ThingsToActivate)
{
    listener.Active = true;
}

然后我作为开发人员知道我只需要继承这种类型

public class MyListener : YourButtonListener
{
    // Now since I used a virtual property above
    // I can either keep it ad a simple 
    // standard setter and getter 
    // or I can implement an own additional functionality like e.g.
    private bool _active;
    public override bool Active
    {
        get => _active;
        set
        {
            _active = value;

            // Here I can put whatever I like to happen when this is set
            Debug.Log("I just got " + (value ? "activated" : "deactivated"));
        }
    }
}

其他一般注意事项:

  • 请勿在{{1​​}}中使用GetComponent存储引用并重复使用。

    在大多数情况下,只需将字段设置为正确的类型,就根本不需要Update。此外,这会强制所有引用的GameObject实际上都装有这样的组件,并阻止开发人员(偶然地?)引用Inspector中的其他内容。

  • 请勿将GetComponent用于轮询Update值。而是重组代码以处理更多事件驱动的事件,例如通过使用类似

    的方法
    bool

在智能手机上输入文字,但我希望这个想法能弄清楚