2013-06-06 17 views
16

मैं उलझन में हूं और coroutines (यूनिटी 3 डी और शायद अन्य स्थानों में) के बारे में उत्सुक हूं। कोरआउट एक नया धागा है? एकता के documentation उन्होंने कहा:यूनिटी 3 डी में कोरआउट एक नया धागा है?

एक coroutine एक समारोह है कि इसके निष्पादन (उपज) को निलंबित कर सकते हैं जब तक दिए गए YieldInstruction खत्म है।

और वे सी # उदाहरण here है:

  1. ऊपर के उदाहरण है, जो लाइन coroutine है में:

    using UnityEngine; 
    using System.Collections; 
    
    public class example : MonoBehaviour { 
        void Start() { 
         print("Starting " + Time.time); 
         StartCoroutine(WaitAndPrint(2.0F)); 
         print("Before WaitAndPrint Finishes " + Time.time); 
        } 
        IEnumerator WaitAndPrint(float waitTime) { 
         yield return new WaitForSeconds(waitTime); 
         print("WaitAndPrint " + Time.time); 
        } 
    } 
    

    मैं इस उदाहरण के बारे में कई प्रश्न हैं? WaitAndPrint() एक कोरआउट है? WaitForSeconds() एक कोरआउट है?

  2. इस पंक्ति में: yield return new WaitForSeconds(waitTime);, क्यों yield और return दोनों मौजूद हैं? मैंने Unity documentation में पढ़ा है कि "उपज कथन एक विशेष प्रकार की वापसी है, जो सुनिश्चित करता है कि अगली बार उपज स्टेटमेंट के बाद यह कार्य लाइन से जारी रहेगा।" यदि yield एक विशेष return है, तो return क्या है?

  3. हमें IEnumerator क्यों वापस करना है?

  4. क्या StartCoroutine एक नया धागा शुरू करता है?

  5. उपरोक्त उदाहरण में WaitAndPrint() कितनी बार बुलाया गया है? yield return new WaitForSeconds(waitTime); वास्तव में वापस आया था? यदि हां तो मुझे लगता है कि उपरोक्त कोड में WaitAndPrint() को दो बार बुलाया गया था। और मुझे लगता है कि StartCoroutine() कई बार WaitAndPrint() पर कॉल कर रहा था। हालांकि, मैंने another Unity documentation देखा जो कहता है: "उपरोक्त कथन का उपयोग करके किसी भी बिंदु पर कोरआउटिन को निष्पादित किया जा सकता है। उपज वापसी मूल्य निर्दिष्ट होता है जब कोरआउट शुरू होता है।" ये शब्द मुझे महसूस करते हैं कि WaitAndPrint() वास्तव में वापस नहीं आया है; यह केवल रोका गया था; यह वापस आने के लिए WaitForSeconds() के लिए इंतजार कर रहा था। यदि यह मामला है, तो उपर्युक्त कोड WaitAndPrint() में केवल एक बार बुलाया गया था, और StartCoroutine फ़ंक्शन शुरू करने के लिए केवल ज़िम्मेदार था, इसे कई बार कॉल नहीं किया गया था।

+0

आपके शीर्षक में प्रश्न के उत्तर में, coroutines ** नहीं ** एक नया धागा शुरू करें और अपने आप में धागे से कोई संबंध नहीं है। यह मत भूलना कि यूनिटी 3 डी मौलिक रूप से फ्रेम आधारित है .. मोनोहेवियोर एक फ्रेम आधारित अवधारणा है। Coroutines - एकता में - मूल रूप से इस प्रतिमान से जुड़े हुए हैं। धागे पूरी तरह से uninvolved हैं। – Fattie

+0

मैं इस ट्यूटोरियल पर ठोकर खा रहा हूं http://www.unitygeek.com/coroutines-in-unity3d/, यह unity3d –

उत्तर

16

Coroutines एक अत्यंत शक्तिशाली .net4.5 में async/इंतजार द्वारा समर्थित सुविधाओं के प्रकार का अनुकरण करने के लिए प्रयोग किया जाता तकनीक रहे हैं, लेकिन पिछले संस्करणों (ग #> = v2.0) में।

Microsoft CCR (पढ़ना) इस दृष्टिकोण को नियोजित (नियोजित) भी नियोजित करता है।

चलो एक चीज़ को रास्ते से बाहर निकालें। yield अकेले मान्य नहीं है और हमेशा return या break द्वारा पीछा किया जाता है।

एक मानक आईएन्यूमेरेटर (जो प्रवाह नियंत्रण संदेशों को उत्पन्न नहीं करता है) के बारे में सोचें।

IEnumerator YieldMeSomeStuff() 
{ 
    yield "hello"; 
    Console.WriteLine("foo!"); 
    yield "world"; 
} 

अब:

IEnumerator e = YieldMeSomeStuff(); 
while(e.MoveNext()) 
{ 
    Console.WriteLine(e.Current); 
} 

उत्पादन क्या है?

 
hello 
foo! 
world 

सूचना कैसे, दूसरी बार हम MoveNext कहा जाता है, से पहले गणनाकार झुकेंगे "दुनिया" कुछ कोड गणनाकार भीतर भाग गया। इसका अर्थ यह है कि एन्युमरेटर में, हम कोड लिख सकते हैं जो इसे yield return कथन हिट करने तक निष्पादित करता है, फिर जब तक कोई MoveNext पर कॉल नहीं करता है (हाथ से सभी राज्य/चर के साथ अच्छी तरह से कब्जा कर लिया जाता है, तो हम वहां से चुन सकते हैं जहां हमने छोड़ा था)। MoveNext कॉल के बाद, yield return कथन के बाद कोड का अगला बिट तब तक चलाया जा सकता है जब तक कि yield return तक पहुंच न जाए। तो हम अब yield return कथन के बीच कोड के निष्पादन को MoveNext के साथ कोड के निष्पादन को नियंत्रित कर सकते हैं।

अब, बजाय तार उपज का कहना है, हमारे गणनाकार संदेश है कि MoveNext के फोन करने वाले से कहता है उपज के लिए, "एक्स (waittime) सेकंड के लिए चारों ओर लटका कृपया इससे पहले कि आप MoveNext फिर से फोन" थे। कॉलर को विभिन्न संदेशों को "समझने" के लिए लिखा गया है। ये संदेश हमेशा की तर्ज पर होंगे "कृपया MoveNext को फिर से कॉल करने से पहले ऐसा करने के लिए प्रतीक्षा करें और ऐसा करें"

अब हमारे पास कोड को रोकने और पुनरारंभ करने का एक शक्तिशाली माध्यम है जिसके लिए आगे बढ़ने से पहले अन्य स्थितियों को पूरा करने की आवश्यकता होती है, बिना किसी विधि में उस कार्यक्षमता को लिखने के बिना, कोरिनिन के बिना एसिंक सामग्री करना। कोरआउट के बिना, आप एक भयानक एसिंक राज्य ऑब्जेक्ट को पास करने के लिए मजबूर हैं कि आपको एक विधि के अंत के बीच स्थिति को कैप्चर करने और कुछ एसिंक सामग्री के बाद दूसरे की शुरुआत करने के लिए मैन्युअल रूप से इकट्ठा करने की आवश्यकता होगी)। कोरोटाइन्स इसे खत्म करते हैं क्योंकि गुंजाइश संरक्षित है (कंपाइलर जादू द्वारा), इसलिए आपके स्थानीय चर लंबे समय तक एसिंक सामग्री पर बने रहते हैं।

StartCoroutine बस पूरी प्रक्रिया शुरू करता है। यह संख्यात्मक पर MoveNext पर कॉल करता है ... कुछ कोड गणनाकर्ता में चलता है ... गणनाकर्ता एक नियंत्रण संदेश उत्पन्न करता है, जो StartCoroutine में कोड को सूचित करता है जब MoveNext को फिर से कॉल करें। यह एक नए थ्रेड में नहीं होने की आवश्यकता है, लेकिन बहुप्रचारित परिदृश्यों में आसान हो सकता है क्योंकि हम विभिन्न धागे से MoveNext पर कॉल कर सकते हैं और जहां काम किया जाता है उसे नियंत्रित कर सकते हैं।

+2

में कोरआउट के उपयोग के बारे में बहुत अच्छी तरह से बताता है और दूसरों के लिए, [एकता का निष्पादन आदेश पृष्ठ] (http: // docs .unity3d.com/दस्तावेज़ीकरण/मैनुअल/ExecutionOrder.html) अपडेट() के बाद चल रहे कोरआउट को दिखा रहा है। – Jerdak

संबंधित मुद्दे