Переменная сценария не найдена - PullRequest
0 голосов
/ 18 апреля 2019

Я знаю, что это одна из самых простых вещей, которые вы можете сделать в C #, но что бы я ни делал, всегда есть ошибка. Я делаю пользовательский интерфейс, где вы можете нажать и изменить размер сетки (моего строительного механика). Его значение по умолчанию 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()
    {

    }
}

1 Ответ

3 голосов
/ 18 апреля 2019

Вместо создания новой локальной переменной

float yourGridSize = 10f;

вам необходимо получить доступ к значению ссылки на этот экземпляр, например

groundPlacementController.yourGridSize = 10.0f;

Просто чтобы быть уверенным

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

вызывается в скрипте с именем GridChanger ... возможно ли, что оба компонента присоединены к одному и тому же GameObject?

В этом случае вы могли бы просто выполнить

var groundPlacementController = GetComponent<GroundPlacementController>();

Мы только что выяснили, что проблема в том, что у вас есть этот компонент несколько раз на одном и том же GameObject.

В общем, Unity на самом деле не создана для того, чтобы один и тот же компонент был несколькораз на том же объекте.Как вы заметили, например, в комментариях GetComponent всегда получит только первый компонент этого типа.Также, если вы хотите сослаться на них в UnityEvents (например, onClick компонента Button), вы всегда можете получить доступ только к первой встрече компонента.Правильная настройка будет иметь один дочерний GameObject для каждого экземпляра этого типа.

Однако есть обходные пути для этого.

Вы можете, например, использовать GetComponentsInChildren дляполучить все компоненты этого типа для этого GameObject или любого из его дочерних элементов (рекурсивно)

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

Примечания:

  • Для public вам не нужно добавлять [SerializeField], так как public поля сериализуются автоматически.
  • вы должны удалить пустые события MonoBehaviour, такие как Update.Даже если они пусты, их вызывает Unity, что приводит к ненужным накладным расходам.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...