2

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

通过不起作用我想说 www.SendWebRequest() 永远不会返回,我已经等了将近 10 分钟并且它没有返回,图像大约有 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);
        }
    }
}

我在检查器中的预制设置

如您所见,我的“IconeSimbolo”是附加该脚本的预制件中的 RawImage

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

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

4

1 回答 1

1

好吧,这很简单:该Update方法不在资产上执行,而仅在场景层次结构中处于活动状态并启用的/GameObject上执行MonoBehaviour

→ 预制件不会Update接到电话。

Unity 中启动的协与调用MoveNext一起执行( )Update

→ 所以你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到参数的末尾(当然假设调用脚本是 a 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.


一个一般性的旁注:为了方便和合作的原因(例如,请参阅此处),您应该习惯于所有方法、变量以及在您的评论中使用英文名称。

于 2019-07-05T06:02:24.483 回答