UnityWebRequest 从不 returns 附加到预制件的脚本

UnityWebRequest never returns on script attached to a prefab

我有一个从服务器下载图像的 IEnumerator 函数,在未附加到预制件的脚本上,它可以工作,但在附加到预制件的脚本上,它不起作用。

因为不起作用我想说 www.SendWebRequest() 从来没有 returns,我已经等了将近 10 分钟但它不起作用 returns,图像大约有 200kb , 所以问题不在于图像大小。

我已经检查过 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);
        }
    }
}

My prefab setup in the inspector

如您所见,我的 "IconeSimbolo" 是附加此脚本的预制件中的 RawImage

我希望我的 "IconeSimbolo" 纹理更改为服务器上的图像,但它永远不会改变。

我在另一个脚本上有相同的代码,在检查器上有相同的设置,在另一个预制件上一切正常,但在这个上却不行

嗯,这很简单:Update 方法不会在资产上执行,而只会在 GameObject/MonoBehaviour 上执行,这些资产 在场景中处于活动状态并已启用层次结构

→预制件未收到 Update 次调用。

开始Coroutines in Unity are executed (MoveNext) together with the Update call (or better said after it - see the Order of Execution for Event Functions)

→所以你的 IEnumerator 开始并且实际上应该发送 return 请求...... 但是 你永远不会调用 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,以便在您的 IEnumerator.

上调用 MoveNext

一般旁注:出于合作的方便和原因(例如,参见此处),您应该习惯于在所有方法、变量和注释中使用英文名称。