मैं यूनिटी 3 डी में एक रूपरेखा कैसे बना सकता हूं?


13

मैं मनमानी ऊंचाई की एक आयत को उजागर करने की कोशिश कर रहा हूं। मैंने सोचा कि ऐसा करने का सबसे आसान तरीका एक अलग "बॉक्स" गेमबॉज़ बनाना होगा जो आयत को रेखांकित करता है।

मैं दोनों एक MeshRenderer + पारदर्शी बनावट, और एक LineRenderer दोनों के साथ आयत के चार बिंदुओं को रेखांकित करने की कोशिश कर चुका हूँ। न ही बहुत संतोषजनक हैं।

यहाँ छवि विवरण दर्ज करें

(बीच में लाइन रेंडरर, दाईं ओर छोटा क्यूब)

इस बारे में जाने का सही तरीका क्या है? मैं बाईं आयत जैसा कुछ पाने की कोशिश कर रहा हूं - मेरे चयन के चार बिंदुओं के माध्यम से निश्चित चौड़ाई का एक सरल परिधि।

जवाबों:


8

का उपयोग करें GUI.Box()

यदि आपको केवल एक 2D आयत की आवश्यकता है, तो GUI जाने का रास्ता है। एक बनावट के रूप में एक साधारण आयत का उपयोग करके एक नया GUIStyle बनाएं (आयत के अंदर पारदर्शी होना चाहिए, निश्चित रूप से), इसके Borderमूल्य को सेट करें ताकि यह खिंचाव न हो, और कॉल करें GUI.Box(new Rect(...),"",myGuiStyle);

Camera.WorldToScreenPointयदि आप विश्व निर्देशांक (अर्थात 3 डी) में किसी चीज़ को रेखांकित करना चाहते हैं तो आप विधि का उपयोग कर सकते हैं , बस याद रखें कि यूनिटी की दुनिया में निर्देशांक y नीचे से ऊपर तक जाता है, और GUI y में ऊपर से नीचे तक जाता है।

कोड उदाहरण:

void OnGUI()
{
    //top left point of rectangle
    Vector3 boxPosHiLeftWorld = new Vector3(0.5f, 12, 0);
    //bottom right point of rectangle
    Vector3 boxPosLowRightWorld = new Vector3(1.5f, 0, 0);

    Vector3 boxPosHiLeftCamera = Camera.main.WorldToScreenPoint(boxPosHiLeftWorld);
    Vector3 boxPosLowRightCamera = Camera.main.WorldToScreenPoint(boxPosLowRightWorld);

    float width = boxPosHiLeftCamera.x - boxPosLowRightCamera.x;
    float height = boxPosHiLeftCamera.y - boxPosLowRightCamera.y;


     GUI.Box(new Rect(boxPosHiLeftCamera.x, Screen.Height - boxPosHiLeftCamera.y, width, height),"", highlightBox);
}

जब तक मैं गलत नहीं हूँ, GUI.Box () हमेशा दृश्य में किसी भी ऑब्जेक्ट के शीर्ष पर खींची जाएगी? क्या GUI तत्व के पीछे या आंशिक रूप से गेमबजेक्ट के पीछे होना संभव है?
रेवेन ड्रीमर

हां, GUI हमेशा अन्य वस्तुओं के बाद खींची जाती है। एक हैक है जो आप GUI के शीर्ष पर एक अलग कैमरा रेंडर करने के लिए उपयोग कर सकते हैं, लेकिन यह थोड़े अनपेक्षित है।
कोई बात नहीं

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

मैंने आपका एडिटिंग कोड सैंपल स्वीकार कर लिया, और उसमें GUI-y-upside-down बग फिक्स किया।
नहीं

1

नीचे एक गैर-शेडर दृष्टिकोण है।

अपने 2d बॉक्स को चार लाइनों से अधिक कुछ नहीं के रूप में सोचो, जहां प्रत्येक पंक्ति केवल एक आयाम में फैली हुई है (अन्य दो आयाम किनारे के क्रॉस-सेक्शन हैं)। यह बहुत पसंद है यदि आप वास्तविक जीवन में एक बॉक्स का निर्माण करने के लिए थे, जहां आप लकड़ी की चर लंबाई को एक साथ जोड़ रहे हैं कि सभी का क्रॉस-सेक्शन आकार समान हो।

इसे ध्यान में रखते हुए, आप एक कंपोनेंट को तैयार कर सकते हैं, कहते हैं BoxBuilder, जब एक गेमऑबजेक्ट से जुड़ा होता है, तो चार बच्चे गेम ऑबजेक्ट बनाता है और उसका प्रबंधन करता है। प्रत्येक चाइल्ड गेम ऑब्जेक्ट आपके बॉक्स किनारों में से एक है, और केवल एक 3 डी क्यूब हो सकता है जो केवल एक आयाम में फैला है। एक widthऔर heightपरिभाषित BoxBuilderस्तर के साथ, आप चार बच्चे के किनारों की आवश्यक स्थिति और गैर-समान पैमाने की गणना कर सकते हैं। यह का एक बहुत हो जाएगा pos.x=w/2, pos.y=h/2, ..., scale.x=h, scale.y=w, कोड की तरह आदि।

हालांकि मेरा मानना ​​है कि आप केवल 2-डी के लिए पूछ रहे हैं, ध्यान दें कि यदि आवश्यक हो, तो यह विचार 3 डी बक्से पर लागू किया जा सकता है, जहां BoxBuilderअब 12 बच्चे किनारों को बनाना और प्रबंधित करना होगा, लेकिन फिर से प्रत्येक किनारे को एक स्थानीय आयाम में स्केल करना होगा।


व्यावहारिक है, लेकिन बहुत जटिल है।
बात नहीं

अगर मुझे इसे इस तरह से करना था, तो मैं बस 4 लाइन रेंडरर्स का उपयोग करूंगा ...
रेवेन ड्रीमर

यह ठीक से गहराई से संभालती है।
डकमास्ट्रो

1

एक सरल तरीका दो पास के साथ एक Shader का उपयोग करना है: पहली पास वस्तु को थोड़ा ऊपर करने के लिए शीर्ष shader का उपयोग करता है और पिक्सेल shader का उपयोग करके इसे उस ठोस रंग से मेल खाता है जिस रंग की आप रूपरेखा चाहते हैं, और फिर दूसरा दर्रा नियमित रूप से प्रतिपादन करता है।


क्या आप बेहतर तरीके से समझाने के लिए एक कोड उदाहरण दे सकते हैं?
रेवेन ड्रीमर

यह केवल उत्तल वस्तुओं के लिए काम करेगा (एक आयत की तरह) जिसका मूल इसके ज्यामितीय केंद्र पर है।
रूट

1

मुझे एक ही रूपरेखा बनाने में यही समस्या थी, सिवाय इसके कि मुझे एक 3 डी क्यूब के लिए "स्ट्रोक" बनाने की आवश्यकता थी, और इसे करने का एक नया तरीका मिला जो मैंने ऑनलाइन कहीं और नहीं देखा है।

नीचे की छवि में रूपरेखा के साथ दो आकार हैं। दायीं ओर लाइनरेंडर के साथ निर्मित क्यूब है, जो फ्लैट चेहरे बनाता है जो हमेशा उपयोगकर्ता की ओर मुड़ता है। मैंने इस विधि को सुपर ग्लिच पाया, जिसमें यादृच्छिक "स्ट्रोक" थे जो चेहरे को बनाते हुए त्रिकोणों की नकल करते थे।

बाईं ओर एक 12 अलग-अलग स्कीनी क्यूब्स के साथ मेरा "इनोवेशन" है जो एक रूपरेखा की तरह दिखता है। रूपरेखा में "स्ट्रोक" के आकार को बदलने के लिए मुझे 12 स्कीनी क्यूब्स में से प्रत्येक के दो पक्षों के आकार को बढ़ाने / घटाने की आवश्यकता है। यह भी 2d रूपरेखा के लिए काम करेगा। बस रंग और वॉइला को बदलने के लिए एक सामग्री लागू करें!

दो अलग-अलग रूपरेखा

इस छवि में आप इस घन की संरचना का विस्तार देख सकते हैं। यह सब रनटाइम पर बनाया जा सकता है लेकिन मैंने इसे हाथ से बनाया है और इसे प्रीफैब के रूप में इस्तेमाल किया है।

विस्तार


0

मैं वर्तमान में एक ही समस्या का सामना कर रहा हूं, और मेरा समाधान बिल्कुल वही है जो डकमेस्ट्रो और रेवेन ड्रीमर ने सुझाया है - एक स्क्रिप्ट है जो रनटाइम पर 4 चाइल्ड ऑब्जेक्ट बनाती है, जिनमें से प्रत्येक सीमा के किनारे का प्रतिनिधित्व करता है और प्रत्येक को लाइन रेंडरर्स संलग्न करता है।

मेरे मामले में मुझे अपनी वस्तु के चारों ओर रखने के लिए सीमा का लगातार आकार बदलने की आवश्यकता थी (एक पाठ जाल [जो एक कस्टम पाठ क्षेत्र के लिए एक मेष रेंडरर का उपयोग करता है)) इसलिए हर अद्यतन मैंने ऐसा किया:


float width = Mathf.Max(renderer.bounds.size.x + paddingX * 2, minWidth);      
float x = renderer.bounds.center.x - width / 2;
float height = renderer.bounds.size.y + paddingY * 2;
float y = renderer.bounds.center.y - height / 2;

AlterBorder(0, new Vector3(x - thickness / 2, y, 0), new Vector3(x + width + thickness / 2, y, 0)); //Bottom edge going left to right
AlterBorder(1, new Vector3(x + width, y + thickness / 2, 0), new Vector3(x + width, y + height - thickness / 2, 0)); //Right edge going bottom to top
AlterBorder(2, new Vector3(x + width + thickness / 2, y + height, 0), new Vector3(x - thickness / 2, y + height, 0)); //Top edge going right to left
AlterBorder(3, new Vector3(x, y + height - thickness / 2, 0), new Vector3(x, y + thickness / 2, 0)); //Left edge going top to bottom

AlterBorder() बस उपयुक्त लाइन रेंडरर (पहले पैरामीटर द्वारा निर्दिष्ट) तक पहुंचता है और क्रमशः इसके पहले और दूसरे वेक्टर पर इसकी शुरुआत और अंत सेट करता है।

ध्यान दें कि मैंने rendererआकार के लिए मेरे संदर्भ के रूप में उपयोग किया था , लेकिन जाहिर है कि आप किसी भी आयत का उपयोग कर सकते हैं, जब तक कि x, y शीर्ष बाएं कोने है।

जो मैं इस काम को वास्तव में अच्छी तरह से बता सकता हूं, वह खेल में बहुत अच्छा लग रहा है क्योंकि मैं अपनी सीमा रेखा को आसानी से सभी 3 अक्षों में घुमा सकता हूं (यहां तक ​​कि इसे घुमाएं, और चूंकि लाइन रेंडरर्स हमेशा कैमरे का सामना करते हैं, यह अजीब नहीं दिखता है), और है लागू करने के लिए मुश्किल नहीं है।

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