नमस्ते, हैकरनून! अगला विषय जो मैंने चुना है वह में ईसीएस (एंटिटी-कंपोनेंट-सिस्टम) है। मैंने आपको सारी जानकारी अधिक सुलभ तरीके से समझने में मदद करने के लिए इसे दो भागों में विभाजित किया है। यूनिटी डेवलपमेंट मैं आपको एंटिटी-कंपोनेंट-सिस्टम के बारे में वह सब कुछ बताऊंगा जो मैं जानता हूं और इस दृष्टिकोण के बारे में विभिन्न पूर्व धारणाओं को दूर करने का प्रयास करूंगा। आपको ईसीएस के फायदे और नुकसान, इस दृष्टिकोण की ख़ासियत, इसके साथ दोस्ती कैसे करें, संभावित नुकसान और उपयोगी प्रथाओं के बारे में कई शब्द मिलेंगे। मैं यूनिटी/सी# के लिए ईसीएस फ्रेमवर्क पर भी संक्षेप में नजर डालूंगा। यह लेख उन लोगों के लिए अच्छा होगा जो ईसीएस से परिचित होना चाहते/शुरू करते हैं। मुझे उम्मीद है कि जिन लोगों ने ईसीएस का स्वाद चखा है, वे भी अपने लिए कुछ नया करने पर जोर दे सकेंगे। यदि आप C# के अलावा किसी अन्य भाषा में गेम बनाते हैं, तो भी आपको यह लेख उपयोगी लग सकता है। इसमें कोई कोड नमूने और पैटर्न का इतिहास नहीं होगा, केवल मेरा अनुभव, तर्क और अवलोकन होंगे :) ईसीएस (इकाई-घटक-प्रणाली) क्या है? एंटिटी-कंपोनेंट-सिस्टम एक वास्तुशिल्प पैटर्न है जो विशेष रूप से गेम के विकास के लिए बनाया गया है। यह एक गतिशील आभासी दुनिया का वर्णन करने के लिए बिल्कुल उपयुक्त है। इसकी विशिष्टताओं के कारण, कुछ लोग इसे लगभग एक नया प्रोग्रामिंग प्रतिमान मानते हैं। ईसीएस वंशानुक्रम से अधिक संरचना का एक पूर्ण सिद्धांत है। यह डेटा-ओरिएंटेड डिज़ाइन (डीओडी) का एक विशेष उदाहरण हो सकता है, लेकिन यह एक विशेष कार्यान्वयन द्वारा पैटर्न की व्याख्या पर निर्भर करता है। आइए इस पैटर्न का नाम समझें: - एक अधिकतम अमूर्त वस्तु। यह गुणों के लिए एक सशर्त कंटेनर है जो परिभाषित करता है कि यह इकाई क्या होगी। इसे अक्सर डेटा तक पहुँचने के लिए एक पहचानकर्ता के रूप में दर्शाया जाता है। इकाई - ऑब्जेक्ट डेटा वाली एक संपत्ति। ईसीएस में घटकों में तर्क की एक भी बूंद के बिना केवल शुद्ध डेटा होना चाहिए। फिर भी, कुछ डेवलपर्स घटकों में विभिन्न गेटर्स और सेटर्स की अनुमति देते हैं। फिर भी, मुझे लगता है कि स्थैतिक उपयोगिताएँ इन उद्देश्यों के लिए बेहतर अनुकूल हैं। घटक - डेटा प्रोसेसिंग का तर्क। ईसीएस में सिस्टम में कोई डेटा नहीं होना चाहिए, केवल डेटा प्रोसेसिंग लॉजिक होना चाहिए। लेकिन, फिर से, कुछ डेवलपर्स इसे सिस्टम के कुछ सहायक व्यवहार को परिभाषित करने की अनुमति देते हैं, उदाहरण के लिए, स्थिरांक या विभिन्न सहायक सेवाएं। सिस्टम जैसा कि आप ऊपर से पहले ही समझ चुके हैं: ईसीएस सख्ती से डेटा को तर्क से अलग करता है। किसी ऑब्जेक्ट का व्यवहार इंटरफेस/अनुबंध/सार्वजनिक एपीआई द्वारा निर्धारित नहीं किया जाता है, जैसा कि हम शास्त्रीय ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग (ओओपी) में करते हैं, बल्कि ऑब्जेक्ट को अलग से मौजूद डेटा + प्रोसेसिंग लॉजिक के साथ निर्दिष्ट गुणों द्वारा निर्धारित किया जाता है। ईसीएस में, डेटा सब कुछ परिभाषित करता है। यह मुख्य गुण है जो इसे अन्य विकास दृष्टिकोणों से अलग करता है: सब कुछ डेटा है। ईसीएस दुनिया में वस्तु गुण, विशेषताएँ और घटनाएँ सिर्फ डेटा हैं। लॉजिक बस इस सभी डेटा की पाइपलाइन प्रोसेसिंग है। ईसीएस की आवश्यकता क्यों है? आपके पास संभवतः पहले से ही एक प्रश्न है: "मुझे ईसीएस की आवश्यकता क्यों है? इसका क्या उपयोग है?" और आपको यह तय करने में मदद करने के लिए कि इस लेख को आगे पढ़ना चाहिए या नहीं, मैं आपको बताऊंगा कि मुझे ईसीएस क्यों पसंद है। व्यक्तिगत रूप से, मुझे ईसीएस पसंद है क्योंकि: ईसीएस के साथ, आप प्रोजेक्ट के आर्किटेक्चर से लड़ने के बजाय बस बैठ जाते हैं और । बड़े और सुंदर पदानुक्रम बनाने, कई कनेक्शनों के बारे में सोचने और "X को Y के बारे में नहीं पता होना चाहिए" के बारे में चिंता करने की कोई आवश्यकता नहीं है। साथ ही, ईसीएस सिद्धांत आपको खराब वास्तुकला के कारण होने वाली निराशाजनक स्थिति से (निश्चित रूप से 100% नहीं) बचाते हैं, जब आगे की परियोजना का विकास बहुत दर्दनाक हो जाता है। और यहां तक कि अगर कुछ गलत हो गया, तो ईसीएस में रिफैक्टरिंग कोई समस्या नहीं है। और यह मेरी राय में, ईसीएस के बारे में सबसे अच्छी बात यही है। यूनिटी में एक गेम बनाते हैं ईसीएस पर कोड सरल और स्पष्ट है। कोई विशेष सिस्टम क्या करता है, यह समझने के लिए आपको कक्षाओं के बीच कॉल के माध्यम से क्रॉल करने की आवश्यकता नहीं है। आप सब कुछ एक ही बार में देख सकते हैं, खासकर यदि आप किसी फीचर को सिस्टम में, सिस्टम को तरीकों में विभाजित करते हैं, और कोड को अधिक जटिल नहीं बनाते हैं। इसके अलावा, ईसीएस प्रोफाइलिंग को बहुत सरल बनाता है। आप एक बार में देख सकते हैं कि कौन सा तर्क (सिस्टम) कितना फ्रेम समय लेता है। आपको कॉल की गहराई में अंतराल के स्रोत की तलाश करने की आवश्यकता नहीं है। तर्क में हेरफेर करना सरल है। नया तर्क जोड़ना व्यावहारिक रूप से दर्द रहित है। आप बाकी कोड को सीधे प्रभावित करने के डर के बिना सही जगह पर एक नया सिस्टम डालें (यह ध्यान दिया जाना चाहिए कि डेटा के माध्यम से अप्रत्यक्ष प्रभाव संभव है)। आप डेटा (घटकों) का उपयोग करते हुए बिना किसी समस्या के क्लाइंट और सर्वर के बीच सामान्य तर्क (सिस्टम) का उपयोग कर सकते हैं। आप बाकी कोड को प्रभावित किए बिना पुराने सिस्टम को रिफैक्टर किए गए सिस्टम से बदलकर आसानी से सिस्टम को फिर से लिख सकते हैं। यदि आपको परिणाम नापसंद है, तो पुराने सिस्टम को वापस चालू करें। वही तंत्र आसानी से ए/बी परीक्षण आयोजित कर सकता है। सब कुछ डेटा के इर्द-गिर्द घूमता है। यह बेहद सुविधाजनक साबित होता है। संस्थाओं पर डेटा में सीधे हेरफेर करके, कॉम्बिनेटरिक्स की संभावनाएं बहुत अधिक हैं। आप किसी इकाई को किसी भी चीज़ में ढालने के लिए डेटा का उपयोग कर सकते हैं। और मान लीजिए कि ढांचा संस्थाओं पर डेटा देखने के लिए उपकरण प्रदान करता है। उस स्थिति में, आप मेमोरी में देखने के लिए डिबगर चलाए बिना किसी भी इकाई पर डेटा और उसकी गतिशीलता की जांच कर सकते हैं। अब क्या तुम मुझे समझते हो? ईसीएस के साथ कैसे काम करें? यहां मैं सरल शब्दों में वर्णन करूंगा कि ईसीएस के साथ विकास प्रक्रिया सबसे सरल उदाहरण में कैसे काम करती है। मैं इसे किसी प्रोग्रामिंग भाषा का संदर्भ दिए बिना यथासंभव अमूर्त रूप से करूँगा। यदि आपके पास पहले से ही ईसीएस के साथ कुछ अनुभव है, तो आप सीधे अगले भाग पर जा सकते हैं :) एक ऐसी वस्तु बनाएं जो किसी दिए गए गति वेक्टर की दिशा में चलती हो। कार्य: सबसे पहले, आइए उस डेटा को परिभाषित करें जिसकी हमें अपने काम के लिए आवश्यकता है। हमारे कार्य के लिए, हमें वस्तु की स्थिति और दिए गए गति वेक्टर की आवश्यकता होगी। ईसीएस भाषा में, ये होंगे: स्थिति वेक्टर को संग्रहीत करने के लिए पोजीशनकंपोनेंट मोशन वेक्टर के लिए मूवमेंट कंपोनेंट अगला कदम तर्क का वर्णन करना है। आइए एक बनाएं। सिस्टम की मुख्य विधि में, कार्यान्वयन के आधार पर, यह या कुछ और हो सकता है। आपको ईसीएस में सभी इकाइयां मिलती हैं जिनमें और होते हैं। यह वास्तव में कैसे किया जा सकता है यह फ्रेमवर्क पर निर्भर करता है, लेकिन अक्सर यह जैसी SQL क्वेरी जैसा दिखता है। MovementSystem Run()/Execute()/Update() PositionComponent MovementComponent GetAllEntities().With<PositionComponent>().With<MovementComponent>() और अंत में, आप बस हमारे दो घटकों के साथ एक इकाई (दस टुकड़े भी) बनाते हैं और गति वेक्टर को शून्य से अलग सेट करते हैं। अब, की प्रत्येक कॉल पर (चाहे हम इसे कहां और कब भी कॉल करें), हमारी वस्तु दिए गए मोशन वेक्टर की दिशा में स्थिति बदल देगी। कार्य पूरा हुआ! :) MovementSystem अक्सर सिस्टम किसी तरह प्रोजेक्ट के गेमलूप में एम्बेडेड होते हैं और इंजन द्वारा ही हर फ्रेम को ट्विच करते हैं। लेकिन आप इसे हाथ से और किसी भी अन्य तरीके से कर सकते हैं, क्योंकि यह सिर्फ एक विधि कॉल है। आइए देखें कि मुख्य समस्या को हल करने के अलावा हमें विकास की क्या अतिरिक्त संभावनाएँ मिलीं: हमारा कोई भी अन्य सिस्टम केवल मूवमेंटकंपोनेंट प्रॉपर्टी की उपस्थिति की जांच करके यह निर्धारित कर सकता है कि कोई वस्तु चल रही है या नहीं कोई भी अन्य सिस्टम अपनी आवश्यकताओं के लिए मोशन वेक्टर प्राप्त कर सकता है हमारी कोई भी अन्य प्रणाली इच्छानुसार हमारी किसी भी इकाई के लिए मोशन वेक्टर निर्दिष्ट करने में सक्षम होगी हम चाहें तो किसी अन्य इकाई को केवल उस पर और रखकर भी चला सकते हैं। समय यह बहुत उपयोगी है। PositionComponent MovementComponent यूनिटी गेम बनाते एकता में ईसीएस के फायदे इस अनुभाग में, हम चर्चा करेंगे कि ईसीएस के बारे में क्या अच्छा है और क्या बुरा है। नीचे वर्णित कुछ विशेषताएं सिक्के के दो पहलू हैं। वे विकास के लिए लाभदायक भी हैं और असुविधाजनक भी, ऐसी सीमाएँ बनाते हैं जिन्हें कभी-कभी दरकिनार करना पड़ता है। सबसे पहले, आइए यूनिटी में ईसीएस के फायदों पर चर्चा करें। कमजोर कोड सामंजस्य के लिए यह एक लाभकारी संपत्ति है। यह हमें अपेक्षाकृत आसानी से और कोड के पुराने टुकड़ों को तोड़े बिना कोड बेस को रिफैक्टर और विस्तारित करने की अनुमति देता है। हम किसी भी तरह से पुराने तर्क में हस्तक्षेप किए बिना पुराने डेटा का उपयोग करके हमेशा नया व्यवहार जोड़ सकते हैं। ईसीएस इस प्रभाव को प्राप्त करता है क्योंकि डेटा एंटिटी में सभी तर्क इंटरैक्शन को व्यक्त करता है। यह बिना किसी गारंटी के एक अधिकतम अमूर्त वस्तु है, जैसे C#/Java में कुछ ऑब्जेक्ट। यूनिटी गेम डेवलपर्स हालाँकि, आपको याद रखना चाहिए कि ईसीएस में डेटा परिवर्तन का क्रम एक महत्वपूर्ण भूमिका निभाता है। यह अंततः रीफैक्टरिंग की जटिलता को प्रभावित कर सकता है और आपके पुराने तर्क को तोड़ सकता है या अप्रिय दुष्प्रभाव वाले बग भी पैदा कर सकता है। तर्क की पूर्ण प्रतिरूपकता और परीक्षणशीलता यदि सभी इंटरैक्शन शुद्ध डेटा में व्यक्त किए जाते हैं, तो हमारा तर्क हमेशा डेटा स्रोत से पूरी तरह से अलग हो जाता है। यह हमें तर्क को एक परियोजना से दूसरे परियोजना में स्थानांतरित करने और उसका पुन: उपयोग करने की अनुमति देता है (निश्चित रूप से डेटा प्रारूप को संरक्षित करते हुए), साथ ही इसके संचालन का परीक्षण करने के लिए किसी भी इनपुट डेटा पर तर्क को चलाने की अनुमति देता है। ख़राब कोड लिखना कठिन है ईसीएस आर्किटेक्चर पर कम मांग रखता है क्योंकि यह वह ढांचा तैयार करता है जिसके साथ वास्तव में खराब कोड डिज़ाइन बनाना अधिक कठिन होता है। साथ ही, जैसा कि ऊपर कहा गया था, हम समस्या को अपेक्षाकृत दर्द रहित तरीके से और बाकी कोड पर न्यूनतम प्रभाव के साथ ठीक कर सकते हैं, भले ही खराब कोड डिज़ाइन हो। ईसीएस हमें "कुछ भी तोड़े बिना इस तर्क को हमारी वास्तुकला में कैसे फिट किया जाए" और नई सुविधाएँ जोड़ने के बारे में कम सोचने की अनुमति देता है। प्रॉपर्टी कॉम्बिनेटरिक्स यह लाभ ईसीएस को गतिशील दुनिया का वर्णन करने के लिए एक उत्कृष्ट विकल्प बनाता है। जरा कल्पना करें: आप बिना किसी परेशानी के अपनी किसी भी संस्था को कोई भी संपत्ति (और इसलिए तर्क) दे सकते हैं! यदि आप चाहते हैं कि कैमरा स्वस्थ रहे, तो आप कैमरे पर लगा सकते हैं। इससे नुकसान होगा (यदि ऐसी व्यवस्था है तो)। किसी इकाई पर डालें, और यदि उसमें है तो वह तुरंत जलने से नुकसान उठाना शुरू कर देता है। क्या आप चाहते हैं कि घर खिलाड़ी के नियंत्रण में चले? कोई समस्या नहीं, बस का उपयोग करें। HealthComponent InFireComponent HealthComponent PlayerInputListenerComponent एक अनुभवी डेवलपर कहेगा: "हा, वंशानुक्रम पैटर्न पर अधिकांश संरचना इसे संभाल सकती है। ईसीएस कैसे बेहतर है?" मेरा उत्तर है: "ईसीएस आपको न केवल इकाई निर्माण के संदर्भ में गुणों को संयोजित करने की अनुमति देता है, बल्कि एक ही इकाई पर कई गुणों (घटकों) को संयोजित करते समय विशिष्ट तर्क भी बनाने की अनुमति देता है।" मैंने इकाई के घटकों को छुए बिना पुराने डेटा के लिए पूरी तरह से नया तर्क जोड़ने की क्षमता का भी उल्लेख नहीं किया है! एकल उत्तरदायित्व को लागू करना आसान है जब हमारे पास तर्क डेटा से पूरी तरह से अलग होता है और किसी वस्तु/इकाई से बंधा नहीं होता है, तो पदानुक्रम में इसके स्थान के बजाय इसके उद्देश्य से तर्क के विभाजन को नियंत्रित करना आसान हो जाता है। प्रत्येक प्रणाली बस अपने लिए विशिष्ट कुछ विशिष्ट कार्य करती है। अक्सर सिस्टम कोड एक ही प्रकार के कई घटकों के लिए एकल विधि कॉल जैसा दिखता है। परिणामस्वरूप, कोड को पढ़ना और समझना अधिकतर आसान होता है। स्पष्ट प्रोफ़ाइलिंग प्रोफाइलिंग करते समय, हम देख सकते हैं कि इसमें क्या तर्क और कितना फ्रेम समय लगता है। यह प्रसंस्करण के लिए जिम्मेदार अपने तर्क के साथ अलग-अलग प्रणालियों के कारण संभव है। हमें यह समझने के लिए कॉल स्टैक में गहराई तक जाने की ज़रूरत नहीं है कि किस चीज़ में सबसे अधिक समय लगता है। हम तुरंत दोषी चारमूवमेंटसिस्टम को देख सकते हैं। यह ध्यान दिया जाना चाहिए कि यह लाभ ईसीएस फ्रेमवर्क डिवाइस पर निर्भर करता है क्योंकि फ्रेमवर्क में स्वयं कॉल स्टैक हो सकता है। ईसीएस अच्छे प्रदर्शन को बढ़ावा दे सकता है बहुत से लोग सोचते हैं कि अच्छा प्रदर्शन ईसीएस का मुख्य लाभ है (एकता प्रचार के लिए धन्यवाद)। ये बिल्कुल सच नहीं है. कोड निष्पादन की गति पैटर्न के सिद्धांतों से उत्पन्न एक अच्छा बोनस है: एक स्थान पर डेटा - दूसरे में तर्क + SIMD (एकल निर्देश, एकाधिक डेटा)। और यदि ईसीएस लागू करते समय ढांचा डीओडी का पालन करता है और अच्छा डेटा स्थानीयता प्राप्त करता है, तो हमें कैश-अनुकूल कोड भी मिलता है, जो आपके प्रोसेसर को खुश कर देगा। अंतिम ईसीएस प्रदर्शन कई कारकों पर निर्भर करता है: फ्रेमवर्क वास्तव में डेटा को कैसे संग्रहीत करता है, फ्रेमवर्क संस्थाओं को कैसे फ़िल्टर करता है, सिस्टम कितनी तेजी से डेटा तक पहुंचता है, और आपके सिस्टम के अंदर कोड कितनी तेजी से काम करता है। हालाँकि, , ईसीएस हमेशा सामान्य मोनोबिहेवियर दृष्टिकोण से तेज़ होगा, खासकर बड़ी मात्रा में डेटा पर। लेकिन यह मत भूलिए कि आपके गेम के प्रदर्शन में जो मायने रखता है वह वास्तुशिल्प पैटर्न नहीं है, बल्कि आपके द्वारा लिखे गए कोड की एल्गोरिथम जटिलता और प्रदर्शन है। एकता विकास के संदर्भ में डेटा प्रोसेसिंग का आसान समानांतरीकरण चूँकि तर्क को एक अलग डेटा प्रोसेसर में विभाजित किया गया है और डेटा वास्तव में एक रैखिक अनुक्रम है, हम बिना किसी समस्या के एक सिस्टम के भीतर प्रसंस्करण को समानांतर कर सकते हैं। यह बहुत महत्वपूर्ण है यदि सिस्टम एक साथ बड़ी संख्या में संस्थाओं को संसाधित करता है और वे किसी भी तरह से एक-दूसरे के साथ नहीं जुड़ते हैं। आप इससे भी आगे जा सकते हैं और विभिन्न थ्रेड्स को तर्क भेज सकते हैं जो बदले हुए डेटा के साथ ओवरलैप नहीं होता है। हालाँकि, इसे नियंत्रित करना और निगरानी करना अधिक कठिन है। फिर भी, डेटा तैयार करने के लिए मुख्य थ्रेड के साथ सिंक्रनाइज़ेशन में एक बाधा होगी। इसके अलावा, यह पता चल सकता है कि थ्रेड के बीच डेटा तैयार करने और वितरण के लिए ओवरहेड आपके सिस्टम में कोड निष्पादन समय से अधिक होगा। इसलिए, आपको यह मूल्यांकन करने की आवश्यकता है कि क्या यह इसके लायक है। स्वच्छ डेटा के साथ काम करना बहुत आसान है लगभग हर यूनिटी गेम में, हमें नेटवर्क पर भेजने के लिए कुछ न कुछ सहेजना, लोड करना या क्रमबद्ध करना होगा। यह बहुत आसान है जब डेटा को तर्क से अलग किया जाता है। यह सोचने की ज़रूरत नहीं है, "यह निजी डेटा में कैसे आना चाहिए..." और उचित क्रमबद्धता के लिए कुछ विशेष तरीकों को कॉल करें। आप बस इकाई पर आवश्यक घटकों को सहेजें/लोड करें। फिर यदि सिस्टम इसे आवश्यक समझेगा तो इसे वांछित स्थिति में पूरा कर देगा। आप जितनी बार चाहें ईसीएस फ्रेमवर्क बदल सकते हैं ईसीएस ढाँचे एक दूसरे के समान हैं क्योंकि सिद्धांत समान हैं। एक डेवलपर जिसने ईसीएस के लिए अपने दिमाग का पुनर्निर्माण किया है और एक फ्रेमवर्क को अच्छी तरह से समझ लिया है, वह बिना किसी समस्या के दूसरे ईसीएस फ्रेमवर्क के साथ काम कर सकता है। एपीआई और किसी विशेष ढांचे की विशेषताओं को सीखने में केवल समय लगेगा। लेकिन नए दृष्टिकोण के लिए अपने दिमाग को फिर से बनाने की आवश्यकता नहीं होगी। एकता में ईसीएस के विपक्ष जैसा कि आप देख सकते हैं, यूनिटी में ईसीएस के अन्य पैटर्न की तुलना में कई मूल्यवान फायदे हैं। अब आइए यूनिटी में ईसीएस के नुकसानों पर चर्चा करें। अनुभवी यूनिटी डेवलपर्स के लिए एक उच्च सीमा हालाँकि ईसीएस अवधारणा को एक वाक्य में वर्णित किया जा सकता है, लेकिन इसका सही ढंग से उपयोग करना सीखने के लिए बहुत अभ्यास की आवश्यकता हो सकती है। ईसीएस के लिए आवश्यक है कि आप डिजाइन के बारे में पहले से जो कुछ भी जानते थे उसे भूल जाएं: आपके सभी ऊर्ध्वाधर विरासत पदानुक्रम, कि किसी वस्तु का व्यवहार उसके इंटरफ़ेस द्वारा निर्धारित होता है, कि एक वस्तु कुछ ठोस और अपरिवर्तनीय है, कि एक वस्तु में एक निजी स्थान हो सकता है, और वह तर्क हो सकता है जहाँ चाहो बुला लिया करो। ईसीएस में सबकुछ वैसा नहीं है. यह ऊपर वर्णित के विपरीत है। यहां सभी डेटा खुला है, सभी संस्थाएं अमूर्त और बहुत गतिशील हैं, उनके गुण एक ही विमान में हैं और सभी के लिए सुलभ हैं, तर्क कन्वेयर के सिद्धांत पर काम करता है, और सामान्य रूप से संस्थाओं का व्यवहार डेटा के आधार पर तुरंत बदल जाता है। कमज़ोर कोड सामंजस्य एक समस्या हो सकता है मान लीजिए कि आपको अचानक दो ठोस संस्थाओं (उदाहरण के लिए, एक कैटरपिलर बॉडी और एक टैंक बुर्ज) के बीच घनिष्ठ संपर्क की आवश्यकता है। उस स्थिति में, आपको इस समस्या का सामना करना पड़ता है कि इकाइयाँ अमूर्त हैं, और आप कंपाइलर स्तर पर गारंटी नहीं दे सकते कि कैटरपिलर बॉडी दूसरे छोर पर होगी। यह रास्ते में आ जाएगा क्योंकि यूनिटी गेम एक ऐसी जगह है जहां बहुत अधिक करीबी बातचीत होती है, और आप हमेशा गुणों और व्यवहार की गारंटी के साथ एक सीधा संदर्भ चाहते हैं। आपको घटक की उपस्थिति की जांच करनी होगी और किसी तरह उसकी अनुपस्थिति को संभालना होगा, उसके साथ बातचीत शुरू करने के लिए इकाई से घटक तक पहुंचना होगा, आदि। कहीं से भी किसी भी डेटा तक पहुँचें ईसीएस दुनिया संस्थाओं का एक खुला बॉक्स है जिसमें सभी घटकों के लिए डेटा उपलब्ध है। उपरोक्त कमज़ोर कोड सामंजस्य की तरह, यह ECS का फ़ायदा और नुकसान दोनों है। एक ओर, यह अत्यधिक सुविधाजनक है। आपको यह पता लगाने की ज़रूरत नहीं है कि डिज़ाइन प्रक्रिया में पहले बनाए गए स्व-सीमित ढांचे को कैसे बायपास किया जाए ("एक्स को वाई के बारे में नहीं पता होना चाहिए") और कुछ तत्काल समस्या को हल करने के लिए पहले से छिपे हुए डेटा को जनता के सामने कैसे लाया जाए। दूसरी ओर, कोई भी अनुभवहीन प्रोग्रामर डेटा को वहां से बदलने का प्रयास करेगा जहां यह नहीं होना चाहिए। लेकिन आमतौर पर, टीम वर्क में दूसरों के काम पर भरोसा करना शामिल होता है, इसलिए भरोसा करें लेकिन सत्यापित करें;) सिस्टम एक के बाद एक, विशेष रूप से प्रवाह में काम करते हैं ईसीएस सिद्धांतों का सही ढंग से पालन करते समय, आपको एक सिस्टम के तर्क को दूसरे सिस्टम के अंदर नहीं बुलाना चाहिए। सिस्टम को एक-दूसरे के अस्तित्व के बारे में बिल्कुल भी पता नहीं होना चाहिए। अन्यथा, यह अनावश्यक कोड सामंजस्य का कारण बनेगा और संभावित रूप से आपके प्रोजेक्ट को नुकसान पहुंचाएगा। हालाँकि, यह सीमा असुविधाजनक हो सकती है और कभी-कभी विभिन्न समाधानों की ओर ले जाएगी जो ईसीएस सिद्धांतों का उल्लंघन नहीं करेंगे। यदि आपको अभी भी यहां और अभी कुछ कोड कॉल करने की आवश्यकता है, तो बस विधियों के साथ एक नियमित ऑब्जेक्ट बनाएं और इसे एक घटक में डालें, अपने आप को प्रताड़ित न करें। पुनरावर्ती तर्क के साथ ठीक से काम नहीं करता यह कमी पिछली समस्या का परिणाम है. सिस्टम कोड को थ्रेड के बाहर और जहां भी हम चाहें कॉल करने की क्षमता की कमी के कारण, ईसीएस किसी एक विशेष सिस्टम के बाहर पुनरावर्ती कोड बनाना लगभग असंभव बना देता है। इस कमी के समाधान के रूप में (ईसीएस सिद्धांतों के अनुपालन के लिए एक समाधान के रूप में), मैं आपको केवल एक विशेष संरचना/प्रणाली बनाने का प्रस्ताव दे सकता हूं जो सिस्टम की एक विशिष्ट सूची को अनंत लूप में कॉल करेगा जब तक कि एक विशेष शर्त पूरी हो जाती है। मेरा मतलब है, जब तक DoActionComponent वाली इकाइयाँ मौजूद हैं। यदि आपके पास अधिक सुंदर समाधान हैं, तो मुझे टिप्पणियों में उनके बारे में पढ़कर खुशी होगी :) सिस्टम निष्पादन क्रम महत्वपूर्ण है ईसीएस में, यह समझना और नियंत्रित करना महत्वपूर्ण है कि सिस्टम आपके डेटा को कैसे बदलते हैं। यह अक्सर संभव है कि हम जिस डेटा पर काम कर रहे हैं उस पर किसी प्रणाली का प्रभाव न पड़ जाए और अंततः विभिन्न अनियोजित दुष्प्रभाव हो जाएं। वैसे, उन्हें ट्रैक करना जटिल हो सकता है (जो अगला दोष है)। हालाँकि, सिस्टम लिखते समय, उन्हें इस तरह से डिज़ाइन करना अक्सर संभव होता है कि इससे कोई फर्क नहीं पड़ता कि सिस्टम को किस क्रम में लागू किया गया है। डिबग करना कठिन है यह काफी विवादास्पद मुद्दा है, खासकर आधुनिक स्मार्ट आईडीई के साथ। गहन स्टैकट्रेस की कमी के कारण (हमारे सिस्टम में तर्क है जो इकाई से बंधा नहीं है) और डेटा और इकाई स्थिति को कैसे और किसके द्वारा बदला गया, इस पर नज़र रखने की असंभवता के कारण, आपके सिस्टम में इसका कारण ढूंढना चुनौतीपूर्ण हो सकता है अचानक उस तरह से काम नहीं करता जैसा उसका इरादा था। यह समझना आसान नहीं है कि किसी विशेष कॉल के कारण क्या हुआ, हालांकि किसी ने इकाई में एक घटक जोड़ा है या एक अतिरिक्त ++ बनाया है। संक्षेप में कहें तो, ईसीएस में, डिबगिंग टूल के बिना, यह ट्रैक करना कठिन है कि घटकों में डेटा क्यों और कैसे बदल गया, खासकर जब आपके पास हजारों इकाइयां हों और केवल एक ही समस्याग्रस्त हो। इसे डिबगिंग टूल द्वारा ठीक किया जा सकता है जो फ्रेमवर्क प्रदान कर सकता है। लेकिन वे बॉक्स से बाहर उपलब्ध नहीं हो सकते हैं, और आपको उन्हें स्वयं लिखना होगा या भुगतना होगा। डेटा संरचनाओं के लिए भयानक विकल्प, विशेषकर पदानुक्रमित संरचनाओं के लिए ईसीएस के साथ डेटा संरचनाओं को लागू करना कठिन, असुविधाजनक है और, मेरी राय में, इसका कोई मतलब नहीं है। मैं यह नहीं कह रहा हूं कि यह असंभव है (यदि आप पर्याप्त प्रयास करते हैं, तो कुछ भी संभव है), लेकिन सड़क के अंत में यह एक कांटेदार रास्ता होगा जिसमें कोई विशेष लाभ नहीं होगा, इसलिए अपनी पसंद में तर्कसंगत रहें। मैं कुछ समस्याएं सूचीबद्ध करूंगा जो ईसीएस पर कुछ डेटा संरचना को समझने का प्रयास करते समय हस्तक्षेप करेंगी: ईसीएस में, सभी डेटा हर जगह से पहुंच योग्य है। यह डेटा संरचनाओं के लिए बेहद खतरनाक हो सकता है जहां अधिकतम स्थिरता की आवश्यकता होती है। कोई भी गुजरने वाला "मगरमच्छ" आपके तर्क को दरकिनार करने के लिए किसी भी आंतरिक डेटा को बदल सकता है, जिससे आपकी डेटा संरचना पूरी तरह से टूट सकती है। यदि हम ईमानदारी से ईसीएस सिद्धांतों का पालन करते हैं, तो हम अपनी डेटा संरचना के तर्क को यहां और अभी लागू नहीं कर सकते, जैसा कि आमतौर पर उनके साथ काम करते समय आवश्यक होता है। हालाँकि, इस बिंदु से स्थैतिक उपयोगिताओं/एक्सटेंशन के साथ लड़ा जा सकता है। ईसीएस क्षैतिज आर्किटेक्चर का प्रतिनिधि है। इसमें सारा डेटा एक ही तल में होता है, लगभग हमेशा घटकों की केवल एक-आयामी सारणी। यदि आपकी डेटा संरचना को लंबवतता/पदानुक्रम की आवश्यकता होती है तो इससे यह मुश्किल हो जाता है। डेटा संरचनाओं के लिए तत्वों (पदानुक्रम) के बीच क्रॉस-रेफरेंस की आवश्यकता होना असामान्य नहीं है। लेकिन, जैसा कि आपको याद होगा, ईसीएस में सब कुछ एक अधिकतम अमूर्त इकाई के इर्द-गिर्द घूमता है। इससे काम करना चुनौतीपूर्ण हो जाता है क्योंकि दूसरे छोर पर हमें जिस प्रकार के तत्व की आवश्यकता है उसकी कोई गारंटी नहीं है। परिणामस्वरूप, इसे अलग से संभालना होगा। डेटा संरचना और उसके तत्वों को आमतौर पर रनटाइम में डेटा प्रारूप को बदलने की आवश्यकता नहीं होती है, न ही उन्हें कॉम्बिनेटरिक्स की आवश्यकता होती है। वे काफी कठोर हैं. प्रत्येक डेटा संरचना इकाई में केवल एक ही घटक हो सकता है। मान लीजिए आपको अभी भी डेटा संरचना की आवश्यकता है। उस स्थिति में, मेरा सुझाव है कि आप इसे विधियों के साथ एक अलग ऑब्जेक्ट के रूप में बनाएं और फिर इस ऑब्जेक्ट को अपने घटक में डालें और हमेशा की तरह सिस्टम से इसके साथ काम करें। अधिक फ़ाइलें और कक्षाएं में, किसी प्रोजेक्ट में फ़ाइलों की संख्या शास्त्रीय दृष्टिकोण में समान कोड की तुलना में तेजी से बढ़ती है। कम से कम इसलिए कि डेटा और तर्क के साथ 1 वर्ग के बजाय, आपके पास दो वर्ग हैं: घटक और सिस्टम (आप अभी भी उन्हें एक फ़ाइल में छिपा सकते हैं)। अधिक से अधिक, यदि आप सभी घटकों को परमाणु (1 घटक - 1 फ़ील्ड) बनाते हैं, तो बहुत, बहुत सारी फ़ाइलें होंगी... ईसीएस दृष्टिकोण बॉयलरप्लेट कोड यह खामी दृढ़ता से ईसीएस ढांचे के विशिष्ट कार्यान्वयन पर निर्भर करती है। कुछ फ्रेमवर्क में आपको बहुत सारे तकनीकी कोड लिखने पड़ते हैं। अन्य में, डेवलपर ने सरलतम एपीआई को संभव बनाने और बॉयलरप्लेट को न्यूनतम करने का प्रयास किया। लेकिन, यदि आप इसकी तुलना अन्य तरीकों से करते हैं, तो आपको लगभग हमेशा कम से कम थोड़ी मात्रा में अतिरिक्त कोड लिखना पड़ता है। मेरा मतलब है घटकों की घोषणा करना, आवश्यक घटकों के साथ एक फ़िल्टर प्राप्त करना, उससे इकाइयाँ प्राप्त करना, किसी इकाई से एक घटक प्राप्त करना, आदि। छोटा निष्कर्ष यह पहले भाग का अंत है. दूसरे भाग में, मैं चर्चा करूंगा: ईसीएस में नौसिखिया गलतियाँ ईसीएस में अच्छी प्रथाएँ यूनिटी/सी# में ईसीएस के साथ काम करने के लिए रूपरेखा यदि आपके कोई प्रश्न हैं, तो उन्हें टिप्पणियों में छोड़ें!