वास्तव में एक अंतहीन धावक में क्या चल रहा है?


107

उदाहरण के लिए प्रसिद्ध फ्लैपी बर्ड गेम, या कुछ भी जो वास्तव में सॉर्ट करता है, वह खिलाड़ी है (इस मामले में पक्षी, या कैमरा जिसे आप पसंद करते हैं) आगे बढ़ रहा है या पूरी दुनिया पीछे की ओर बढ़ रही है (पक्षी केवल वाई स्थिति बदलता है और एक है निरंतर एक्स स्थिति)?


1
हमने इस प्रश्न और इसके उत्तर से कई ऑफ-टॉपिक टिप्पणियां हटा दी हैं। हमने कुछ मामलों में बार-बार बातचीत करने के लिए कई उचित चर्चाएँ की हैं। इसके बावजूद, कई उपयोगकर्ताओं ने इस तथ्य को अनदेखा करने की आवश्यकता महसूस की है कि टिप्पणियां विस्तारित चर्चाओं के लिए नहीं हैं और जारी हैं। जैसे, यह प्रश्न अस्थायी रूप से बंद कर दिया गया है।
जोश

जवाबों:


146

मैं फिलिप के जवाब से थोड़ा असहमत हूं ; या कम से कम उसने इसे कैसे प्रस्तुत किया। यह धारणा देता है कि खिलाड़ी के चारों ओर दुनिया घूमना बेहतर विचार हो सकता है; जब यह ठीक विपरीत है। तो यहाँ मेरा अपना जवाब है ...


दोनों विकल्प काम कर सकते हैं, लेकिन आम तौर पर दुनिया भर के खिलाड़ी के बजाय खिलाड़ी के चारों ओर दुनिया को स्थानांतरित करके "भौतिकी को पलटना" एक बुरा विचार है।


प्रदर्शन हानि / बर्बादी:

दुनिया में आमतौर पर बहुत सारी वस्तुएं होंगी; कई नहीं तो अधिकांश, स्थिर या नींद। खिलाड़ी के पास एक, या अपेक्षाकृत कुछ वस्तुएं होंगी। खिलाड़ी के चारों ओर पूरी दुनिया को हिलाने का मतलब है, खिलाड़ी को छोड़कर दृश्य में सब कुछ हिलना। स्थिर वस्तुएँ, सोई हुई गतिशील वस्तुएँ, सक्रिय गतिशील वस्तुएँ, प्रकाश-स्रोत, ध्वनि-स्रोत आदि; सभी को स्थानांतरित करना होगा।

यह (स्पष्ट रूप से) केवल वास्तव में आगे बढ़ने से ज्यादा महंगा है (खिलाड़ी, और शायद कुछ और सामान)।


स्थिरता और विस्तार:

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

इस दृष्टिकोण के साथ कई अन्य समस्याएं भी हैं। उदाहरण के लिए, यह कई धारणाओं को तोड़ता है कि कैसे इंजन में काम करना चाहिए। आप RigidBodyउदाहरण के लिए, खिलाड़ी के अलावा किसी अन्य चीज़ के लिए गतिशील का उपयोग करने में सक्षम नहीं होंगे ; RigidBodyकीनेमेटिक पर सेट नहीं की गई किसी वस्तु के रूप में स्थिति / रोटेशन / स्केल सेट करते समय अप्रत्याशित रूप से व्यवहार करेगा (जो आप प्रत्येक फ्रेम के लिए कर रहे हैं, दृश्य में प्रत्येक वस्तु के लिए, खिलाड़ी को छोड़कर)


तो इसका उत्तर केवल खिलाड़ी को स्थानांतरित करना है!

खैर ... हां और नहीं । जैसा कि फिलिप के उत्तर में उल्लेख किया गया है, एक अनंत-धावक प्रकार के खेल में (या किसी बड़े सहज क्षेत्र के साथ कोई भी खेल), मूल से बहुत दूर जाने पर अंततः ध्यान देने योग्य FPPEs ( फ्लोटिंग-पॉइंट प्रिसिजन एरर्स ) का परिचय होगा , और आगे भी, अंततः संख्यात्मक प्रकार के अतिप्रवाह, या तो आपके गेम को क्रैश करने का कारण बनते हैं, या, मूल रूप से, गेम-वर्ल्ड स्मोक क्रैक ... स्टेरॉयड पर! 😵 (क्योंकि इस बिंदु से, FPPEs खेल को पहले से ही "सामान्य" दरार पर बना देगा)


वास्तविक समाधान:

ना तो करो और ना दोनों करो! आपको दुनिया को स्थिर रखना चाहिए, और इसके चारों ओर खिलाड़ी को स्थानांतरित करना चाहिए। लेकिन "री-रूट" दोनों खिलाड़ी और दुनिया, जब खिलाड़ी दृश्य की जड़ (स्थिति [0, 0, 0]) से बहुत दूर होने लगता है ।

यदि आप चीजों की सापेक्ष स्थिति (इसके चारों ओर दुनिया के खिलाड़ी) रखते हैं, और इस प्रक्रिया को एकल फ्रेम-अपडेट में करते हैं, तो (वास्तविक) खिलाड़ी को नोटिस भी नहीं होगा!

ऐसा करने के लिए, आपके पास दो प्राथमिक विकल्प हैं:

  1. खिलाड़ी को दृश्य के मूल में ले जाएं, और खिलाड़ी के सापेक्ष नई स्थिति में दुनिया को स्थानांतरित करें।
  2. एक ग्रिड की तरह दुनिया के बारे में सोचो; ग्रिड के उस हिस्से को स्थानांतरित करें जो खिलाड़ी रूट में है, और खिलाड़ी को ग्रिड के उस हिस्से के सापेक्ष नई स्थिति में ले जाएं।

कार्रवाई में इस प्रक्रिया का एक उदाहरण है


लेकिन, कितनी दूर है?

आप एकता के स्रोत-कोड को देखें, तो वे का उपयोग 1e-5( 0.00001) "बराबर" दो फ्लोटिंग प्वाइंट मूल्यों को देखते हुए के अंदर के लिए आधार के रूप में Vector2और Vector3(वस्तुओं की स्थिति के लिए जिम्मेदार डेटा-प्रकार, [euler-] रोटेशन और तराजू)। चूंकि फ्लोटिंग-पॉइंट सटीक नुकसान शून्य से दोनों तरीके से होता है, इसलिए यह मान लेना सुरक्षित है कि दृश्य रूट / उत्पत्ति से दूर 1e+5( 100000) इकाइयों के तहत कुछ भी काम करने के लिए सुरक्षित है।

परंतु! जबसे...

  1. इन री-रूटिंग प्रक्रियाओं को स्वचालित रूप से संभालने के लिए एक सिस्टम बनाना अधिक उपयुक्त है।
  2. आपका खेल चाहे जो भी हो, दुनिया के 100000 यूनिट (मीटर [?]) चौड़े होने के लिए एक सन्निहित "खंड" की कोई आवश्यकता नहीं है।

... तो यह शायद एक अच्छा विचार है कि 100000 इकाइयों के निशान की तुलना में जल्द / अधिक बार फिर से रूट करें। उदाहरण के लिए मैंने जो वीडियो प्रदान किया है, वह प्रत्येक 1000 इकाइयों या ऐसा करने के लिए लगता है, उदाहरण के लिए।


2
टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है । कृपया अधिक टिप्पणियों को यहां पोस्ट करने के बजाय उस चैट का उपयोग करें।
एलेक्जेंडर Vaillancourt

> यह (स्पष्ट रूप से) केवल वास्तव में आगे बढ़ने की तुलना में अधिक महंगा है <क्या यह चल रहा है? जब प्रतिपादन, तुम वैसे भी सभी वस्तुओं पर कैमरा मैट्रिक्स के साथ एक matrices गुणा करना होगा, पहचान पर तय कैमरा होने इस तरह से कम महंगा होगा ।
मात्सेमन्न

वह क्षण जब खेल विकास एकता विकास बन जाता है ...
LJ '

@ मात्सेमन्न - यदि आप चैट करने गए थे, तो आपने देखा होगा कि यह कोई नई बात नहीं है। जैसा कि पहले ही समझाया गया है, NOT-EQUALS दृश्य प्रस्तुत करना; वे अलग-अलग और लगभग पूरी तरह से स्वतंत्र विषय और पाइपलाइन हैं। जिस तरह से वस्तुओं को दृश्य में रखा जाता है, उसी तरह से संदर्भ के फ्रेम का उलटा करना मतलब होगा कि आपके पास रेंडर के बजाय दोनों सिरों पर भारी प्रक्रिया होगी । --- इसके अलावा, भले ही आप के तर्क के अनुसार प्रदर्शन समान रूप से कारोबार किया गया था, उलटा के साथ अन्य सभी समस्याएं अभी भी अनसुलझी रहेंगी, जिससे यह दृष्टिकोण फिर से एक से भी बदतर हो जाएगा।
20

@LJ was सवाल विशेष रूप से एकता के बारे में किया गया था (देखें डी। एवरहार्ड के [IMHO डिफेंसिंग एडिट्स से पहले ओपी के टैग देखें), और इसलिए उत्तर को प्रतिबिंबित करने के लिए सिलवाया गया था । --- लेकिन यहाँ सबसे अच्छा हिस्सा है: यह एकता, अवास्तविक, cryEngine, स्रोत, आदि रहो ... सबसे अच्छा और / या सबसे लोकप्रिय इंजन इस तरह से काम करते हैं (और वे इसे एक कारण के लिए करते हैं), इसलिए उत्तर केवल नहीं है सामान्य रूप से पूरी तरह से मान्य है, लेकिन बनाए जा रहे अंक अभी भी सटीकता के शिखर पर हैं । सामान्यतया, यदि आप संदर्भ के भौतिकी के फ्रेम को उल्टा करते हैं, तो आप विशेष रूप से गतिशील वस्तुओं पर, समस्याओं में चलने की उम्मीद कर सकते हैं।
XenoRo

89

दोनों विकल्प काम करते हैं।

लेकिन अगर आप चाहते हैं कि अंतहीन धावक वास्तव में अंतहीन हो, तो आपको खिलाड़ी को स्थिर रखना होगा और दुनिया को आगे बढ़ाना होगा। अन्यथा आप अंत में एक्स-पोजीशन को स्टोर करने के लिए आपके द्वारा उपयोग किए जाने वाले वैरिएबल की सीमा से टकराएंगे। एक पूर्णांक अंततः अतिप्रवाह होगा और एक फ्लोटिंग पॉइंट वैरिएबल तेजी से कम सटीक हो जाएगा जो गेमप्ले को थोड़ी देर बाद गड़बड़ कर देगा। लेकिन आप एक बड़े पर्याप्त प्रकार का उपयोग करके इस समस्या से बच सकते हैं कि कोई भी इन समस्याओं का सामना नहीं करेगा एक बार में एक सत्र में खेल सकते हैं (जब एक खिलाड़ी प्रति सेकंड 1000 पिक्सेल चलता है, तो 49 दिनों के बाद 32 बिट पूर्णांक ओवरफ्लो हो जाएगा)।

इसलिए जो भी आपको वैचारिक रूप से अधिक सहज लगता है वह करें।


टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
जोश

1
मुझे नहीं लगता है कि कुछ भी हल है। खिलाड़ी की (और कैमरा) स्थिति रखने के बजाय, आप दुनिया की स्क्रॉल स्थिति रखते हैं - यह कैसे अलग है?
Agent_L

1
@Agent_L आमतौर पर, दुनिया टुकड़ों में उत्पन्न होती है, और प्रत्येक टुकड़े की अपनी X / Y स्थिति होती है। जब टुकड़ा खिलाड़ी के पीछे पर्याप्त (जैसे ऑफस्क्रीन) हो जाता है, तो उसे हटा दिया जाता है, और वे केवल अग्रिम में एक निश्चित राशि उत्पन्न करते हैं, इसलिए वे हमेशा एक छोटी सी सीमा के भीतर होते हैं - एक खेल जिसे मैंने कभी भी एक समन्वय नहीं किया था। ~ 1000 से कम या 0 से कम, एक अनंत, बेतरतीब ढंग से उत्पन्न धावक होने के बावजूद, क्योंकि - मैंने प्रत्येक चंक में खिलाड़ी की स्थिति का ट्रैक रखा, और प्रत्येक चंक के अनुक्रम में अनुक्रम।
निक हार्टले

मैं "चर अतिप्रवाह" अवधारणा नहीं खरीदता। यदि खिलाड़ी हिल नहीं रहा है, तो "पृष्ठभूमि" उसी राशि से नकारात्मक रूप से ऑफसेट होगी, जो खिलाड़ी चल रहा है तो ऑफसेट होगा। दोनों मामले वास्तव में एक ही समस्या (विपरीत दिशाओं में) में चलेंगे, और दोनों को अतिप्रवाह की सीमा पर विशेष हैंडलिंग की आवश्यकता होगी।
खर्चा

2
प्रति सेकंड 1000 पिक्सल पर 64 बिट पूर्णांक पर जाने के लिए 586 मिलियन वर्ष लगेंगे। यह वास्तव में केवल एक समस्या है अगर आप 16 बिट पूर्णांक जैसे छोटे प्रकार का उपयोग कर रहे हैं।
लिंडन व्हाइट

38

XenoRo के उत्तर का निर्माण , उनके द्वारा बताए गए री- रुटिंग विधि के बजाय, निम्नलिखित में से कोई एक कर सकता है:

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

player.position = (player.position + player.velocity) % worldBuffer.width;

यहाँ एक उदाहरण है कि मैं किस बारे में बात कर रहा हूँ:

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

यहाँ एक उदाहरण है कि अंत में लपेटने पर क्या होता है।

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

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

ध्यान दें कि आप किसी भी prng के साथ दोहराए जाने वाले परिणाम प्राप्त करना शुरू कर देंगे , और एक PRNG पीढ़ी के गैर दोहराए जाने वाले दृश्यों की अधिकतम संख्या आमतौर पर pow की लंबाई (2, आंतरिक रूप से उपयोग किए जाने वाले बिट्स की संख्या) से कम होती है, जो मेरजेन ट्विस्टर्स के साथ नहीं है। किसी समस्या का अधिकांश भाग, क्योंकि यह 2.5k आंतरिक स्थिति का उपयोग करता है, लेकिन यदि आप छोटे संस्करण का उपयोग करते हैं, तो आपके पास दोहराने से पहले 2 ^ 127-1 अधिकतम पुनरावृत्तियाँ हैं (या इससे भी बदतर), यह अभी भी एक खगोलीय बड़ी संख्या है । भले ही आपके PRNG में बीज के लिए अच्छे हिमस्खलन मिश्रण कार्यों के माध्यम से एक छोटी अवधि हो (जैसा कि आप अधिक राज्य को जोड़ते हैं) बार-बार होने पर आप दोहराई जाने वाली अवधि की समस्याओं को ठीक कर सकते हैं ।


टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
जोश

15

जैसा कि पहले ही पूछा और स्वीकार किया गया है, यह वास्तव में आपके खेल की गुंजाइश और शैली पर निर्भर करता है, लेकिन चूंकि इसका उल्लेख नहीं किया गया था: FlappyBird दुनिया भर के खिलाड़ी के बजाय स्क्रीन पर बाधा को स्थानांतरित करता है।

एक स्पावरर Vector2.leftदिशा में एक निश्चित गति के साथ स्क्रीन से वस्तुओं को तुरंत हटा रहा है ।


3
यह FlappyBird के लिए काम करता है क्योंकि यह एक बहुत ही सरल खेल है। जैसा कि मेरे उत्तर में उल्लेख किया गया है, एक ही तकनीक, जबकि अभी भी संभव है , सबवे सर्फर की तरह कुछ और अधिक जटिल (अधिक विश्व वस्तुओं / विवरण के साथ) पर बहुत समस्याग्रस्त होगा ।
XenoRo 22

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