找不到跨脚本变量

时间:2019-04-18 13:37:08

标签: unity3d global-variables

我知道这是您可以在C#中做的最简单的事情之一,但是无论我做什么,总是会出错。我正在制作一个用户界面,您可以单击并更改(我的建筑机械师的)网格大小。它的默认值为ArrayList,我想访问脚本2.5上的变量yourGridSize。试图访问它的脚本称为GroundPlacementController。我遇到的唯一错误是在GridChangerScript中,每当我调用该变量时,它都会说它无法识别。

此处GridChangerScript(已缩短)

GroundPlacementController

还有这里using UnityEngine; using UnityEngine.AI; public class GroundPlacementController : MonoBehaviour { [SerializeField] public float yourGridSize = 2.5f;

GridChangerScript

1 个答案:

答案 0 :(得分:3)

代替创建新的局部变量

float yourGridSize = 10f;

您必须访问该实例引用的值,例如

groundPlacementController.yourGridSize = 10.0f;

请确保

GameObject gridChanger = GameObject.Find("GridChanger");

是在名为GridChanger的脚本中调用的...是否有可能将两个组件都附加到同一个GameObject?

在这种情况下,您可以做

var groundPlacementController = GetComponent<GroundPlacementController>();

我们刚刚发现问题还在于,您在同一GameObject上多次拥有该组件。

通常,Unity实际上并不是因为在同一对象上具有相同的组件多次。如您所见GetComponent中的注释将始终只获得该类型的第一个组件。另外,如果您想在UnityEvents中引用它们(例如onClick的{​​{1}}),则始终只能访问该组件的第一次接触。正确的设置是为该类型的每个实例创建一个子GameObject。

但是,有解决方法。

您可以例如使用GetComponentsInChildren获取该GameObject或其任何子级上的该类型的所有组件(递归)

Button

或者如果这些是整个场景中唯一出现的该类型事件,则可以使用FindObjectsOfType(仅适用于活动组件和终止组件)

GameObject gridChanger = GameObject.Find("GridChanger");

// Optionally you can pass in a true to also find inactive or disabled components
GroundPlacementController[] groundPlacementControllers = gridChanger.GetComponentsInChildren<GroundPlacementController>();

而不是设置所有的GroundPlacementController[] groundPlacementControllers = FindObjectsOfType<GroundPlacementController>(); 遍历它们

yourGridSize

更新

您还想先读出某些文字

foreach(var groundPlacementController in groundPlacementControllers)
{
    groundPlacementController.yourGridSize = 10.0f;
}

注释:

  • 对于GroundPlacementController[] groundPlacementControllers = FindObjectsOfType<GroundPlacementController>(); foreach(var groundPlacementController in groundPlacementControllers) { // get the childs text var childText = groundPlacementController.GetComponentInChildren<Text>(true); // Convert the text to float float textValue = float.TryParse(childText.text, out textValue ? textValue : 0.0f; groundPlacementController.yourGridSize = textValue; } ,您不需要添加public,因为[SerializeField]字段是自动序列化的。
  • 您应该删除空的MonoBehaviour事件,例如public。即使它们为空,它们也会被Unity调用,从而导致不必要的开销。