unity3d - 未找到跨脚本变量
问题描述
我知道这是你可以在 C# 中做的最简单的事情之一,但无论我做什么总是有错误。我正在制作一个 UI,您可以在其中单击并更改网格大小(我的建筑技工的)。它的默认值为 at 2.5
,我想访问yourGridSize
位于脚本上的变量GroundPlacementController
。试图访问它的脚本称为GridChangerScript
. 我得到的唯一错误是,GridChangerScript
每当我调用变量时,它都会说它无法识别它。
继承人GroundPlacementController
(缩短)
using UnityEngine;
using UnityEngine.AI;
public class GroundPlacementController : MonoBehaviour
{
[SerializeField]
public float yourGridSize = 2.5f;
还有这里GridChangerScript
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GridChanger : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
GameObject gridChanger = GameObject.Find("GridChanger");
GroundPlacementController groundPlacementController = gridChanger.GetComponent<GroundPlacementController>();
float yourGridSize = 10f;
}
// Update is called once per frame
void Update()
{
}
}
解决方案
而不是创建一个新的局部变量
float yourGridSize = 10f;
您必须访问该实例引用的值,例如
groundPlacementController.yourGridSize = 10.0f;
只是要确定
GameObject gridChanger = GameObject.Find("GridChanger");
在名为GridChanger
... 的脚本中调用是否有可能两个组件都附加到同一个游戏对象?
在这种情况下,您可以这样做
var groundPlacementController = GetComponent<GroundPlacementController>();
我们刚刚发现问题还在于您在同一GameObject
.
一般来说,Unity 并不是为了在同一个对象上多次使用相同的组件而设计的。正如您在评论中注意到的那样,GetComponent
总是只会获得该类型的第一个组件。此外,如果您想在 UnityEvents(例如组件)中引用它们,onClick
您Button
始终只能访问组件的第一次遇到。正确的设置是为该类型的每个实例设置一个子 GameObject。
但是,有一些解决方法。
例如,您可以使用GetComponentsInChildren
在该游戏对象或其任何子对象上获取该类型的所有组件(递归)
GameObject gridChanger = GameObject.Find("GridChanger");
// Optionally you can pass in a true to also find inactive or disabled components
GroundPlacementController[] groundPlacementControllers = gridChanger.GetComponentsInChildren<GroundPlacementController>();
或者,如果这些是您可以使用的整个场景中唯一出现的该类型FindObjectsOfType
(仅活动和可结束组件)
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;
}
笔记:
- 对于 a
public
您不需要添加[SerializeField]
,因为public
字段会自动序列化。 - 你应该删除空的 MonoBehaviour 事件,比如你的
Update
. 即使它们是空的,它们也会被 Unity 调用,从而导致不必要的开销。
推荐阅读
- python - 如何使用熊猫数据框实现以下输出?
- docker - Docker swarm 服务日志输出停止
- c# - 初始化时未调用EntityFramework核心`OnConfiguring`
- excel - 具有 3 个相互链接的命令按钮的 vba 宏
- angular - 在 Azure DevOps 上将 typescript 代码编译到 npm 并作为依赖项添加到 Angular 项目中
- oauth - 接受来自多个授权服务器的令牌
- json - 使用 spark scala 扁平化嵌套 json 创建 2 列同名并在 Phoenix 中给出重复错误
- bash - 通过 Jenkins 的 shell 脚本在远程服务器中执行 bash 脚本
- laravel - 如果 db 字段为空,则隐藏 Laravel API 资源中的属性
- ios - 无法将值类型转换为预期的参数类型错误?