एकता में, एक वेक्टर 2 और एक वेक्टर 3 अस्पष्ट क्यों जोड़ रहा है, लेकिन असाइन करना नहीं है?


11

निम्नलिखित दो वैक्टर दिए गए हैं:

Vector3 v3 = Vector3.one;
Vector2 v2 = Vector2.one;

यह रेखा अस्पष्ट है:

v3 += v2; // Unity reports dimension ambiguity

इस असाइनमेंट के नहीं होने पर:

v3 = v2; // Unity assigns despite different dimensions

ऐसा क्यों है?


तो, महान जवाब के लिए Anko और Xavi Montero को बहुत-बहुत धन्यवाद। समस्या को पुन: पेश करने की कोशिश करते हुए मैंने महसूस किया कि मेरे प्रश्न को बदल दिया जाना चाहिए। तथ्य यह हो रहा है जब एक वेक्टर 2 को ट्रांसफोर्म करने के लिए नियत किया जाए। ताकि ट्रांसफॉर्मेशन हो सके। पोजिशन = ए + बी; BOTH a और b जहां वेक्टर 2 सही ढंग से संकलित हैं और यह x और y असाइन करता है! इसके बजाय, जब मैं लाइन को ट्रांसफ़ॉर्म में बदलता हूं तो यह काम नहीं करता है। प्रस्ताव + = a; // या b मैं यूनिटी 5.0.0f का उपयोग कर रहा हूं और स्क्रिप्ट एक UI तत्व (छवि) से जुड़ी हुई है जो संकलक को प्रभावित नहीं करती है लेकिन आपके लिए परिदृश्य को पुन: उत्पन्न करने के लिए महत्वपूर्ण जानकारी हो सकती है।
स्टीकऑवरफ्लो

तो आप लोग मुझे बताएं कि मुझे क्या करना है। क्या हम सवाल और अपने जवाब बदल सकते हैं या हम एक नई शुरुआत करेंगे?
स्टीकऑवरफ्लो

वेक्टर 3 + वेक्टर 2 और वेक्टर 3 + = वेक्टर 2 कभी भी कोई भी काम नहीं करेगा जो आप चाहते हैं क्योंकि दोनों को दूसरे में बदला जा सकता है और आपको जो करना चाहते हैं उसके अनुसार स्पष्ट रूप से डालना होगा। वेक्टर 3 = वेक्टर 2 काम करता है क्योंकि इसमें कोई अस्पष्टता नहीं है। मुझे नया प्रश्न बदलने या पोस्ट करने की आवश्यकता नहीं है।

मैं प्रश्न को बदलने के लिए कह रहा हूं क्योंकि मामला मेरे द्वारा वर्णित से थोड़ा अलग है, जो आपके उत्तर के प्रवाह को तोड़ सकता है।
स्टीकऑवरफ्लो

नाह चिंता मत करो, कुछ भी नहीं टूटता।

जवाबों:


12

पूरा मुद्दा संदेश:

त्रुटि CS0121: कॉल निम्न विधियों या गुणों के बीच अस्पष्ट है: UnityEngine.Vector2.operator +(UnityEngine.Vector2, UnityEngine.Vector2)' andUnityEngine.Vector3.operator + (UnityEngine.Vector3, UnityEngine.Vector3) '

एकता ने एक Vector3को एक Vector2और इसके विपरीत में परिवर्तित करने का एक तरीका प्रदान किया । यह आपके मामले में अस्पष्टता का कारण बनता है क्योंकि दोनों + ऑपरेटरों को लागू किया जा सकता है।

अपने आप Vector2को Vector3उस ऑपरेशन में स्पष्ट रूप से कास्ट करें , ताकि कंपाइलर उपयोग करना जानता हो UnityEngine.Vector3.operator +(UnityEngine.Vector3, UnityEngine.Vector3)

यदि आप उत्सुक हैं, तो उस विशिष्ट त्रुटि के लिए Microsoft के डॉक्स यहां हैं


अपने संपादन के बाद संपादित करें:

Vec3 += Vec2ऊपर वर्णित उसी कारण से अस्पष्ट है। Vec3 += Vec2वास्तव में होने की कल्पना करो Vec3 = Vec3 + Vec2। निहित रूपांतरणों के कारण Vec3 + Vec2दोनों Vector2और Vector3उत्तर दे सकते हैं , इसीलिए आपको यह निर्दिष्ट करना होगा कि आप क्या चाहते हैं।

Vec3 = Vec2अस्पष्ट नहीं है क्योंकि Vec2 को संक्षेप में एक में बदल दिया जाता है Vector3और फिर प्रारंभिक Vec3 को सौंपा जाता है। तो पूरे ऑपरेशन वास्तव Vector3 = Vector3में आप Vec2 को Vector3मैन्युअल रूप से डालने के बिना है ।


इसलिए एकता मानती है कि मैं चाहता हूं कि मेरे वेक्टर 3 के एक्स और वाई को मेरे वेक्टर 2 के एक्स और वाई से और मेरे जेड को 0 एफ से सेट किया जाए। सही?
स्टीकऑवरफ्लो

हां, Vec3 = Vec2 Vec3 = (वेक्टर 3) Vec2 के बराबर होने की कल्पना करें। आपको मैन्युअल रूप से कास्ट करने की आवश्यकता नहीं है क्योंकि यह वास्तव में उस मामले में इसके अलावा और कुछ नहीं हो सकता है।

हाँ, वास्तव में मेरे प्रश्न का शीर्षक कुछ ऐसा हो सकता है "वेक्टर 2 को असाइन करते समय मुझे वेक्टर 3 में डालने की आवश्यकता क्यों नहीं है"। मैं सही सवालों के शीर्षक और आलेखन में सर्वश्रेष्ठ नहीं हूँ: / धन्यवाद एलेक्स। मेरी जिज्ञासा संतुष्ट हुई है।
स्टेकऑवरफ्लो

3

मुझे vars का नाम बदलने के लिए (स्पष्टता के लिए):

Vector3 pos3d = new Vector3 (1f, 2f, 3f);
Vector2 pos2d = new Vector2 (1f, 2f);

उत्तर

यह pos3d + pos2dलाइन के सेक्शन के कारण है। यह हिस्सा वास्तव में अस्पष्ट है जबकि +=ऐसा नहीं है। मुझे स्पष्ट करें कि एक क्यों और दूसरा क्यों।

विश्लेषण 1

इस लाइन में

transform.position = pos3d + pos2d;

संकलक pos3d + pos2dआगे बढ़ने से पहले अभिव्यक्ति का मूल्यांकन करने की कोशिश करता है , भले ही परिणाम कहां रखा जाए।

ऐसा करने के लिए, सिस्टम पहले किसी भी सार्वजनिक स्थैतिक फ़ंक्शन को खोजने की कोशिश करता है जो एक वेक्टर 3 और एक वेक्टर 2 जोड़ता है, उदाहरण के लिए यह संभव हस्ताक्षर:

public static Vector3 operator +(Vector3 a, Vector2 b);

या उदाहरण के लिए यह संभव हस्ताक्षर:

public static Vector2 operator +(Vector3 a, Vector2 b);

फिर भी एपीआई में उन हस्ताक्षरों में से कोई भी नहीं है, इसलिए संकलक ज्ञात हस्ताक्षर करने के मापदंडों को "कास्ट" करने की कोशिश करता है।

फिर संकलक उन दो संभावित हस्ताक्षर पाता है:

public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);

ये यहाँ प्रलेखित हैं: http://docs.unity3d.com/ScriptReference/Vector3-operator_add.html और यहाँ: http://docs.unity3d.com/ScriptReference/Vector2-operator_add.html

तो दो संभावनाएँ हैं:

तो जैसा कि दोनों कास्टिंग संभव है, पॉस 2d को वेक्टर 3 में डाला जा सकता है और पॉस 3 डी को एक वेक्टर 2 में डाला जाता है, कंपाइलर फिर उसी स्रोत कोड को संकलित करने के संभावित तरीकों का पता लगाता है (बशर्ते स्वचालित छिपी हुई कास्टिंग हो)।

पॉस 3 डी को वेक्टर 2 में डालना और दूसरे हस्ताक्षर के साथ आगे बढ़ना संभव है, या तो वेक्टर 3 में पॉज़ 2 डी डालें और पहले हस्ताक्षर के साथ आगे बढ़ें।

जैसा कि अभिव्यक्ति pos3d + pos2dका मूल्यांकन पहले किया जाता है, ध्यान में रखने से पहले "जहां परिणाम लागू किया जाएगा" तब कंपाइलर को यह नहीं पता होगा कि आप किस कास्ट करेंगे-कोडर- जैसे कि यह प्रदर्शन करना है।

यदि आप 3D की ओर बढ़ना चाहते हैं, तो आप इसे लिख सकते हैं:

transform.position = pos3d + ( Vector3 )pos2d;

और समस्या दूर हो गई है, जैसा कि अब स्पष्ट है: पहले वेक्टर 2 को एक अन्य प्रकार की वेक्टर 3 में स्थानांतरित करें, फिर वेक्टर 3 + वेक्टर 3 का योग करें। बशर्ते कि यह स्थिर हस्ताक्षर हो

public static Vector3 operator +(Vector3 a, Vector3 b);

उपलब्ध है, कि कोई भी अस्पष्टता के साथ प्रयोग किया जाएगा।

विश्लेषण २

दूसरी ओर, जब आप करते हैं

transform.position = pos3d;
transform.position += pos2d; 

कोई अस्पष्टता नहीं है: पहली पंक्ति एक वेक्टर 3 को एक वेक्टर 3 (कोई संदेह नहीं) बताती है।

दूसरी पंक्ति के बराबर है

transform.position = transform.position + pos2d;

विशेषता के साथ ट्रांसफॉर्मेशन। केवल एक बार मूल्यांकन किया जाता है, और इसलिए इस प्रकार को ध्यान में रखा जाता है, जैसा कि आप +=ऑपरेटर के बारे में इस Microsoft पृष्ठ में देख सकते हैं :

https://msdn.microsoft.com/en-us/library/sa7629ew.aspx

इसके अतिरिक्त यह कहता है कि "+ = ऑपरेटर को सीधे ओवरलोड नहीं किया जा सकता है, लेकिन उपयोगकर्ता-परिभाषित प्रकार + ऑपरेटर (देखें)) को ओवरलोड कर सकते हैं।" इसलिए हमें लगता है चाहिए Vector3के +=ऑपरेटर के रूप में माइक्रोसॉफ्ट द्वारा वर्णित जहां लिखा है कि कार्य करता है:

x += y

के बराबर है

x = x + y

सिवाय इसके कि एक्स का केवल एक बार मूल्यांकन किया जाए। + ऑपरेटर का अर्थ x और y के प्रकारों पर निर्भर करता है (संख्यात्मक ऑपरेंड के लिए इसके अलावा, स्ट्रिंग ऑपरेंड्स के लिए संक्षिप्तिकरण, और इसके बाद)।

इसलिए हम सुनिश्चित कर सकते हैं कि दूसरा दृष्टिकोण Vector3वर्ग के + ऑपरेंड को आमंत्रित करता है , जिस पर हस्ताक्षर हैं:

public static Vector3 operator +(Vector3 a, Vector3 b);

इसलिए इसे प्राप्त करने के लिए कोई अन्य तरीका नहीं है, क्योंकि यह एक वेक्टर 3 में पॉस 2 डी को परिवर्तित करने के बजाय एक अंतर्निहित छिपी कास्ट के लिए है जो किसी अन्य रूप में नहीं हो सकता है।

मदद की उम्मीद है !!


संपादित करें

में Unity 5.0.1f1 Personalसाथ MonoDevelop-Unit 4.0.1, एलेक्स एम कहते हैं, लाइनों:

transform.position = pos3d;
transform.position += pos2d;

अभी भी त्रुटि डाली "Assets/Scripts/CubeScript.cs(15,27): error CS0121: The call is ambiguous between the following methods or properties: 'UnityEngine.Vector2.operator +(UnityEngine.Vector2, UnityEngine.Vector2)' and 'UnityEngine.Vector3.operator +(UnityEngine.Vector3, UnityEngine.Vector3)'"

इसलिए वास्तव में + = दोनों हस्ताक्षरों का उपयोग कर रहा है

public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);

इस तथ्य की परवाह किए बिना कि "पहले से ही" जहां "परिणाम रखा जाएगा (मुझे लगता है क्योंकि एक वेक्टर 2 का उत्पादन गंतव्य (वेक्टर 3) के लिए अनुकूल है और अगर वह संभव नहीं था, तो शायद, कंपाइलर उचित के साथ एक का चयन करेगा। उत्पादन का प्रकार)।

इस बिंदु के लिए धन्यवाद एलेक्स एम।


+=या तो काम नहीं करता है, यह अभी भी एक Vector3+ है Vector2। मेरा जवाब देखिए।

तुम्हारा, ठीक है, तुम्हारा, मेरा संपादन करेंगे।
ज़ावि मोंटेरो

बस अपनी टिप्पणी को शामिल करने के लिए संपादित किया गया।
ज़ावि मोंटेरो

transform.position + = pos2d संकलित कर रहा है। मैं कल अधिक सटीक रहूंगा (बस एक संस्करण बग हो सकता है)
स्टेकऑवरफ्लो

संपादन के बाद मैं अनुक्रम में खो गया ... इसलिए ... pos3d += pos2d(आपके संपादित प्रश्न के अनुसार) विफल रहता है लेकिन transform.position += pos2dसंकलन (आपकी टिप्पणी के अनुसार ऊपर) ?? जैसा .positionकि अजीब लगेगा Vector3- स्पष्ट रूप से यह नहीं देख सकता कि क्या आप अर्थ हैं।
ज़ावी मोंटेरो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.