0

我有一个在我的场景中被多次调用的协程。

IEnumerator Save_assets(string file, int i, string name){

    var filename = Path.GetFileName(file);
    docPath = Application.streamingAssetsPath+"/files/";
    var temp_name = docPath+filename;

    downloaded_asset = false;

    if(!Directory.Exists(docPath)){
        Directory.CreateDirectory(docPath);
    }

    if (!System.IO.File.Exists(temp_name)){
        WWW  www = new WWW(file);
        yield return www;
        //Save the image
        System.IO.File.WriteAllBytes(temp_name, www.bytes);
    }

    /*  I really would like to have a sort of listener here doing something like:
        //pseudocode
        while(global.file != true){ //while not done
            yield return null;
        }

    */
    downloaded_asset = true;
    finished = false;
    tries = 0;

    go = GameObject.Find(name);
    go.gameObject.BroadcastMessage("paint_file", temp_name);

}

一旦调用了paint_file,该类上的Update函数就会不断寻找发生的特定条件,假设它是“done = true;”。

void paint_file(file){
    [...]//code
}

void Update () {
   var done = true;//let's pretend there's no code here, just  done = true
   if(done){
        Debug.Log("Finished: "+paint_file._filename);
    }
}

我不知道如何设置这个 var global.file = done,任何帮助将不胜感激

4

1 回答 1

1

避免使用全局变量(静态变量或单例),而是使用直接回调或将内容与组件/对象引用挂钩

最好避免 Find 和 broadcastMessage ,因为它们很慢 :-)

而是有:

var SomeComponentType myReferenceToThatComponent;

on Awake(){
    if(myReferenceToThatComponent==null){
        myReferenceToThatComponent = GetComponent<SomeComponentType>();
    }
}

一旦你引用了一个组件,你就可以访问它上面的任何公共项目,例如:

myReferenceToThatComponent.done = true;
myReferenceToThatComponent.SomeMethod( true );

好处是您可以在编辑器中设置该引用,但如果您不将其设置为空,它会尝试查找它,并且只找到一次,任何进一步的使用都将使用缓存的结果而不必再次使用昂贵的搜索。

您的 www 应该被“使用”包围,这是确保完成后垃圾收集的常见做法

using ( WWW www = new WWW( url, form ) ) {
    yield return www;

}

我认为查找和获取组件和对象的无数方法超出了这个答案的范围

请记住,Unity 最好是基于组件的,这与 C# 编码的典型 OOP 继承/接口风格完全不同。

-

构造协程以一个接一个地运行等待一个完成的方法:

void Start() {
    StartCoroutine( BaseRoutine() );
}

IEnumerator BaseRoutine() {
    for ( int i = 0; i < 10; i++ ) {
        yield return StartCoroutine( ChildRoutine( i ) );
    }       
}

IEnumerator ChildRoutine( int i ) {
    Debug.Log( "ChildRoutine number: " + i );
    yield return new WaitForSeconds( 1 ); // Put your yield return WWW here for example
}
于 2013-08-20T14:47:11.847 回答