UnityWebRequest никогда не возвращается на сценарий, прикрепленный к сборному - PullRequest
2 голосов
/ 04 июля 2019

У меня есть функция IEnumerator, которая загружает изображение с сервера, по сценарию, не прикрепленному к prefabs, работает, но по сценарию, прикрепленному к prefabs, не работает.

По не работает я хочу сказать, что www.SendWebRequest () никогда не возвращается, я ждал почти 10 минут и он не возвращается, изображение имеет около 200 КБ, поэтому проблема не в размере изображения.

Я уже проверил, правильно ли указан URL, попытался изменить изображение, попытался переписать функцию, но ничего не работает, это моя функция:

public void Set(string NomeIcone, string NomeAnalise, string idzinho, string descricaozinha, string NomeCapa)
{
    Name.text = NomeAnalise;
    ID = idzinho;
    Descricao = descricaozinha;
    Capa = NomeCapa;
    StartCoroutine(LoadLogo(NomeIcone));
}

public IEnumerator LoadLogo(string nomeArquivo)
{
    string url = PathIcone + nomeArquivo;
    print(url);

    using (UnityWebRequest www = UnityWebRequestTexture.GetTexture(url))
    {
        yield return www.SendWebRequest();

        if (www.error == null)
        {
            Texture2D tex = new Texture2D(1, 1);
            tex = DownloadHandlerTexture.GetContent(www);
            Icon.texture = tex;
            RawImage Foto = Icon.GetComponentInChildren<RawImage>();
            Foto.SetNativeSize();
            float altura = 100 * Foto.rectTransform.rect.height / Foto.rectTransform.rect.width;
            Foto.rectTransform.sizeDelta = new Vector2(100, altura);
        }
    }
}

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

Как видите, мой "IconeSimbolo" - это RawImage в префабе, к которому прикреплен этот скрипт

Я ожидаю, что моя текстура IconeSimbolo изменится на изображение на сервере, но оно никогда не изменится.

У меня такой же код на другом скрипте с такой же настройкой на инспекторе, на этом другом сборном все работает нормально, но на этом нет

1 Ответ

1 голос
/ 05 июля 2019

Ну, это довольно просто: метод Update не выполняется для ресурсов, а только для GameObject / MonoBehaviour, которые активны и включены в иерархии сцен

& RightArrow; Префабы не получают Update звонков.

Запущено Сопрограммы в Unity выполняются (MoveNext) вместе с вызовом Update (или лучше сказать после it - см. Порядок выполнения для события Функции )

& RightArrow; Итак, ваш IEnumerator начинается и фактически должен отправлять и возвращать запрос ... , но вы никогда не наберете MoveNext, так что он никогда не поймет, что запрос уже завершен.


Где-то вы вызываете метод Set. Так что в качестве обходного пути вы можете позволить некоторым GameObject / MonoBehaviour выполнить IEnumerator для вас, например,

public void Set(string NomeIcone, string NomeAnalise, string idzinho, string descricaozinha, string NomeCapa, MonoBehaviour responsibleBehaviour)
{
    Name.text = NomeAnalise;
    ID = idzinho;
    Descricao = descricaozinha;
    Capa = NomeCapa;

    // This now starts the coroutine instead on the passed 
    // responsibleBehaviour and uses that ones Update calls in order to
    // move on with the IEnumerator
    responsibleBehaviour.StartCoroutine(LoadLogo(NomeIcone));
}

и в вызывающем скрипте просто добавьте this в конец параметров (при условии, конечно, что вызывающий скрипт - MonoBehaviour)

prefab.Set(someNomeIcone, someNomeAnalise, someIdzinho, someDescricaozinha, someNomeCapa, this);

В качестве альтернативы, поскольку вы в любом случае сделали LoadLogo public, вы также можете напрямую использовать другой IEnumerator, чтобы выполнить его следующим образом:

public IEnumerator LoadLogo(string NomeIcone, string NomeAnalise, string idzinho, string descricaozinha, string NomeCapa)
{
    Name.text = NomeAnalise;
    ID = idzinho;
    Descricao = descricaozinha;
    Capa = NomeCapa;

    string url = PathIcone + NomeIcone;
    print(url);

    using (UnityWebRequest www = UnityWebRequestTexture.GetTexture(url))
    {
        yield return www.SendWebRequest();

        if (www.error == null)
        {
            Texture2D tex = new Texture2D(1, 1);
            tex = DownloadHandlerTexture.GetContent(www);
            Icon.texture = tex;
            RawImage Foto = Icon.GetComponentInChildren<RawImage>();
            Foto.SetNativeSize();
            float altura = 100 * Foto.rectTransform.rect.height / Foto.rectTransform.rect.width;
            Foto.rectTransform.sizeDelta = new Vector2(100, altura);
        }
    }
}

и затем запустите его на GameObject в сцене, например. как

public class SomeBehaviourInScene : MonoBehaviour
{
    // reference the Prefab here
    public YourPrefabScript prefab;

    // wherever you want to call this
    public void LoadPrefabLogo()
    {
        StartCoroutine(LoadPrefabLogoRoutine());
    }

    // If you want this to be called automatically
    // on app start this could also be a 
    //private IEnumerator Start()
    private IEnumerator LoadPrefabLogoRoutine()
    {
        // this also executes the LoadLogo and at 
        // the same time waits until it is finished
        yield return prefab.LoadLogo(/* Your parameters here */);

        Debug.Log("Finished");
    }
}

Или, если речь идет о EditorScript, вы можете зарегистрироваться на EditorApplication.update для вызова MoveNext на вашем IEnumerator.


Общая информация: Для удобства и в целях сотрудничества (например, см. Здесь) вы должны привыкнуть использовать английские имена для всех методов, переменных, а также в ваших комментариях.

...