यूनिटी लेयर मास्क को बिट शिफ्टिंग का उपयोग करने की आवश्यकता क्यों है?


10

मैं अंत में पता लगा रहा हूं कि मेरे जमीनी टक्कर कोड के लिए मेरी परत के मुखौटे काम क्यों नहीं कर रहे थे। मैं NameToLayer()उस लेयर का उपयोग कर रहा था जिसकी मुझे आवश्यकता थी, लेकिन लेयर मास्क बिट शिफ्टिंग का उपयोग वास्तव में लेयर मास्क वैल्यू को सेट करने के लिए करते हैं। यह बेहद असामान्य है और मुझे ऐसा कोई कारण नहीं दिखता है कि इसे पीछे के कोड में क्यों न संभाला जाए। हमें इस तरह कोड का उपयोग क्यों करना है:

mask = 1 << LayerMask.NameToLayer("Default");

जब कुछ इस तरह:

mask = LayerMask.NameToLayer("Default");

अधिक सहज ज्ञान युक्त बनाता है और एकता एपीआई के बाकी हिस्सों के समान काम करता है?


2
स्ट्रिंग संस्करण का उपयोग अधिक प्रसंस्करण शक्ति लेता है। स्ट्रिंग का उल्लेख नहीं करना आंतरिक रूप से एक सरणी है जो एक संदर्भ प्रकार है और कचरा कलेक्टर में जोड़ा जाता है।
क्रीथिक

जवाबों:


3

यह बेहद परफॉर्मेंट है। यही सब कुछ है - स्पष्ट उदाहरण के रूप में तार की तुलना करना 10. के कारक द्वारा धीमा है और भौतिकी गणना को बहुत अनुकूलित किया जाना है, इसलिए यह अच्छा है कि जो कोई जानता था कि इस तरह से लिखा जा रहा है।

तो स्पष्ट अनुवर्ती सवाल है - यह रूपांतरण और बिट-शिफ्टिंग को संभालने के लिए एक सहायक विधि में क्यों नहीं लपेटा गया है। मुझे लगता है कि वास्तव में कोई नहीं मिला - मैंने अपनी खुद की निफ्टी हेल्पर उपयोगिता को रोल किया है और यह सामान्य अभ्यास है।


1
यूनिटी टीम द्वारा सही डिजाइन विकल्प एक स्ट्रिंगर के बजाय एक इंडेक्सर के रूप में एक पूर्णांक का उपयोग करने के लिए होता। मैं समझता हूं कि जब मैं सोचता हूं कि कचरा कलेक्टर अपने वर्तमान कार्यान्वयन के साथ कितना पागल हो रहा है, तो स्ट्रिंग सरणी आवंटन का उल्लेख नहीं करना चाहिए।
क्राइथिक

1
बिल्कुल - किसी भी सरणी को पूर्णांक द्वारा संदर्भित किया जाता है। एक सरल एनम द्वारा इंजीर आसानी से मानवीय रूप से पठनीय बन सकता है।
जॉर्डन जॉर्जिएव

एक त्वरित और गंदा कार्यान्वयन कार्य करता है, लेकिन बड़ी परियोजनाओं के लिए मैं [प्रकार सुरक्षित] ( परिसंपत्ति भंडार ।unity3d.com/en/#//content/35903 ) का उपयोग करता हूं ।
जॉर्डन जॉर्जिएव

20

बिट शिफ्टिंग का उपयोग करने से आप एक भौतिकी ऑपरेशन में कई परतों को ध्यान में रख सकते हैं:

 Physics.Raycast(ray, out hitInfo, Mathf.Infinity, layerMask )

बिना किसी बदलाव के, आपको केवल एक परत में और केवल एक को रेकास्ट करने की अनुमति होगी। थोड़ी शिफ्टिंग के साथ, आप कई विशिष्ट परतों में रीकास्ट कर सकते हैं:

layerMask = (1 << LayerMask.NameToLayer("MyLayer1")) | (1 << LayerMask.NameToLayer("MyLayer2")) ;

आप विशिष्ट लोगों को छोड़कर प्रत्येक परतों में रीकास्ट भी कर सकते हैं:

layerMask = (1 << LayerMask.NameToLayer("MyLayer1")) | (1 << LayerMask.NameToLayer("MyLayer2")) ;
layerMask = ~layerMask;

यदि आप एकता में "परत प्रबंधक" को देखते हैं, तो परतों को एक साधारण एक आयाम सरणी के सूचक के रूप में देखा जा सकता है


संपादित करें: मैंने इसे पहले कभी नहीं देखा है, लेकिन LayerMaskपरतों के नाम को देखते हुए "कम्प्यूटेड" लेयर मास्क प्राप्त करने के लिए क्लास का एक उपयोगिता कार्य है:

Debug.Log( LayerMask.GetMask("UserLayerA", "UserLayerB") ) ;

मान लीजिए UserLayerAऔर UserLayerBदसवीं और ग्यारहवीं परतें हैं। इनमें यूजर लेयर के 10 और 11. मान होंगे। लेयर मास्क वैल्यू प्राप्त करने के लिए उनके नाम गेटमास्क में दिए जा सकते हैं। तर्क या तो उनके नामों की सूची हो सकती है या उनके नामों को संग्रहीत करने वाले तार की एक सरणी। इस स्थिति में रिटर्न मान 2 ^ 10 + 2 ^ 11 = 3072 होगा।

दस्तावेज़ से लिंक करें: https://docs.unity3d.com/ScriptReference/LayerMask.GetMask.html


2
मास्क बनाते समय आपको |पूर्णांक या पूर्णांक जोड़ के बजाय का उपयोग करना चाहिए +, पूर्णांक जोड़ अप्रत्याशित व्यवहार उत्पन्न कर सकता है।
वंड्रा

1
लेकिन फिर, वे आंतरिक रूप से ऐसा कर सकते थे और एक विधि प्रदान की जैसेLayerMask.NamesToLayers(params string[] layerNames)
QBrute

शुभ बिंदु @wondra! ;) - हाँ, वे यह QBrute कर सकते थे, लेकिन यदि आप लेयर मास्क को बदलना चाहते हैं, तो बिट शिफ्टिंग ऑपरेशन का उपयोग करना कहीं अधिक लचीला है (जोड़ना, परत हटाना,
निष्क्रिय करना

बिटवाइज़ ऑपरेशन भी बहुत तेज़ हैं। वे बड़े बाइनरी डेटा को संयोजित करने का एक शानदार तरीका हैं।
गूसडर

यह वास्तव में इस सवाल का जवाब नहीं देता है कि विधि सिर्फ एक परत संख्या के बजाय एक परत मुखौटा वापस क्यों नहीं करती है।
घन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.