首页 > 解决方案 > 在 Editor Window 插件中使用 WWW 和 UnityWebRequest

问题描述

在 Unity 中,我有一个自定义窗口,我正在尝试从 Amazon S3 加载图像并将其显示在窗口中。但是,我的功能似乎没有执行。但是,如果我将 aDebug.Log放入函数中,它永远不会被记录,但是,Debug.Log在函数被调用 ( LoadAvatarTexture) 之前的 a 会记录。据我了解,这IEnumerator不适用于EditorWindow课堂,但适用于MonoBehaviour课堂。我该怎么做才能让我的编辑器窗口加载图像?

public class MyEditorWindow : EditorWindow {

  Texture2D avatarTexture;

  [MenuItem("GameSmart/Player Manager", false, 0)]
  public static void ShowManager() {
    var window = EditorWindow.GetWindow(typeof(MyEditorWindow));
    window.titleContent = new GUIContent("Player Manager");
    window.minSize = new Vector2(400, 300);
  }

  void OnGUI() {
    var loadPlayer = GUILayout.Button("Load Player");
    if (loadPlayer) {
      Debug.Log("I log to the console just fine");
      LoadAvatarTexture("http://dev-avatars.gamesmart.com/default.png");
    }
    if (avatarTexture != null) {
      float aspect = (float)avatarTexture.width / (float)avatarTexture.height;
      Rect previewRect = GUILayoutUtility.GetAspectRect(aspect, GUILayout.Width(100), GUILayout.ExpandWidth(true));
      GUI.DrawTexture(previewRect, avatarTexture, ScaleMode.ScaleToFit, true, aspect);
    }
  }

  IEnumerator LoadAvatarTexture(string url) {
    Debug.Log("I do not log to the console");
    var www = new WWW(url);
    yield return www;
    avatarTexture = www.texture;
  }

}

标签: c#unity3d

解决方案


但是,我的功能似乎没有执行。

那是因为LoadAvatarTexture是协程函数。您不会像普通函数那样调用协程函数。你从StartCoroutine函数开始。例如,StartCoroutine(LoadAvatarTexture())

即使StartCoroutine在您的特定情况下启动它也不起作用,因为这是一个编辑器插件并且StartCoroutine需要实例MonoBehaviour才能工作。StartCoroutine您只能在脚本派生时才能访问,MonoBehaviour但不能访问。

你有两个选择:

1 . 继续将LoadAvatarTexture函数作为当前的协程函数,但从MonoBehaviour相机或场景中的任何对象获取实例。我更喜欢主摄像头,因为它不太可能被禁用。

代替

LoadAvatarTexture("http://dev-avatars.gamesmart.com/default.png");

//Get camera's MonoBehaviour
MonoBehaviour camMono = Camera.main.GetComponent<MonoBehaviour>();
//Use it to start your coroutine function
camMono.StartCoroutine(LoadAvatarTexture("http://dev-avatars.gamesmart.com/default.png"));

请注意,您必须在使用请求之前检查错误。以下是LoadAvatarTexture修改后的新函数以检查错误:

IEnumerator LoadAvatarTexture(string url)
{
    Debug.Log("I do not log to the console");
    var www = new WWW(url);
    yield return www;
    if (string.IsNullOrEmpty(www.error))
        avatarTexture = www.texture;
    else
        Debug.Log(www.error);
}

2 . 另一种选择是使该LoadAvatarTexture函数成为普通 ( void) 函数而不是协程函数,然后用于WWW.isDone确定请求何时完成。

void OnGUI()
{
    var loadPlayer = GUILayout.Button("Load Player");
    if (loadPlayer)
    {
        Debug.Log("I log to the console just fine");
        LoadAvatarTexture("http://dev-avatars.gamesmart.com/default.png");
    }

    //Check if request is done then get the texture
    if (www != null && www.isDone)
    {
        if (string.IsNullOrEmpty(www.error))
            avatarTexture = www.texture;
        else
            Debug.Log(www.error);

        //Reset
        www = null;
    }

    if (avatarTexture != null)
    {
        float aspect = (float)avatarTexture.width / (float)avatarTexture.height;
        Rect previewRect = GUILayoutUtility.GetAspectRect(aspect, GUILayout.Width(100), GUILayout.ExpandWidth(true));
        GUI.DrawTexture(previewRect, avatarTexture, ScaleMode.ScaleToFit, true, aspect);
    }
}

WWW www;
void LoadAvatarTexture(string url)
{
    Debug.Log("I do not log to the console");
    www = new WWW(url);
    if (string.IsNullOrEmpty(www.error))
        avatarTexture = www.texture;
    else
        Debug.Log(www.error);
}

推荐阅读