मेरे पास एक घास-प्रीफ़ैब है जो कुछ समय के बाद प्रीफ़ैब का ग्रिड बनाने के बाद खुद को 8 में से एक स्थिति में तुरंत चालू कर देता है। वर्तमान में मैं प्रीफ़ैब प्रति 8 ट्रिगर-कोलाइडर का उपयोग करके अन्य घास-प्रीफ़ैब की जांच करता हूं। नीचे स्क्रीनशॉट देखें:

enter image description here

समस्या यह है कि उनमें से केवल एक समूह को तुरंत चालू करने के बाद एकता धीमी हो जाती है।

मैं प्रदर्शन सुधारों से संबंधित किसी भी सुझाव के लिए तैयार हूं।

यहाँ मेरा कोड है:

using UnityEngine;
public class GrassController : MonoBehaviour
{
    [SerializeField] private float growthRate = 1.1f;
    [SerializeField] private float maxSize = 1f;
    [SerializeField] private float reproduceEffort = 0.1f;
    [SerializeField] private GameObject prefab;
    [SerializeField] private GameObject sprite;
    [SerializeField] private ReproduceHitBoxController[] reproduceHitBoxes;
    [SerializeField] private float size = 0f;
    private float initialSize = 0.1f;
    private void Awake()
    {
        size = initialSize;
        ApplyGrowth();
    }
    private void FixedUpdate()
    {
        if (size < maxSize) Grow();
        else Reproduce();
    }
    private void Grow()
    {
        size *= growthRate;
        if (size >= maxSize) size = maxSize;
        ApplyGrowth();
    }
    private void ApplyGrowth()
    {
        sprite.transform.localScale = new Vector3(size, size, sprite.transform.position.z);
    }
    private void Reproduce()
    {
        var reproduceHitBox = reproduceHitBoxes[Random.Range(0, reproduceHitBoxes.Length)];
        if (reproduceHitBox.tagInCollider == true) return;
        Instantiate(prefab, reproduceHitBox.transform.position, Quaternion.identity);
        size -= reproduceEffort;
    }
}

संपादित करें: ऐसा लगता है कि प्रदर्शन पर मुख्य ड्रैग सभी भौतिक-जांच हैं। क्या किसी निश्चित क्षेत्र में अन्य गेमऑब्जेक्ट्स की जांच करने के तरीके हैं जो अधिक प्रदर्शनकारी हैं?

enter image description here

समाधान: मैंने सभी वस्तुओं को उनकी स्थिति के अनुसार सहेजने के लिए एक Dictionary<Vector3,GrassController> बनाया है, इसलिए मुझे केवल प्रत्येक चेक के लिए आसन्न स्थितियों पर पुनरावृति करनी होगी। ध्यान दें कि इस दृष्टिकोण में कुछ संभावित समस्याएं हैं, जैसा कि Tomasz Juszczak ने बताया।

using UnityEngine;
public class GrassController : MonoBehaviour
{
    [SerializeField] private float growthRate = 1.1f;
    [SerializeField] private float maxSize = 1f;
    [SerializeField] private float reproduceEffort = 0.1f;
    [SerializeField] private GameObject prefab;
    [SerializeField] private GameObject sprite;
    [SerializeField] private GameController gameController;
    [SerializeField] private float size = 0f;
    private Vector3[] growPoints;
    private float initialSize = 0.1f;
    private void Awake()
    {
        growPoints = new Vector3[] {
            new Vector3(transform.position.x + 1, transform.position.y + 1, transform.position.z),
            new Vector3(transform.position.x + 1, transform.position.y, transform.position.z),
            new Vector3(transform.position.x + 1, transform.position.y - 1, transform.position.z),
            new Vector3(transform.position.x, transform.position.y - 1, transform.position.z),
            new Vector3(transform.position.x - 1, transform.position.y - 1, transform.position.z),
            new Vector3(transform.position.x - 1, transform.position.y, transform.position.z),
            new Vector3(transform.position.x - 1, transform.position.y + 1, transform.position.z),
            new Vector3(transform.position.x, transform.position.y + 1, transform.position.z),
        };
        size = initialSize;
        gameController.grassControllers.Add(transform.position, this);
        ApplyGrowth();
    }
    private void FixedUpdate()
    {
        if (size < maxSize) Grow();
        else Reproduce();
    }
    private void Grow()
    {
        size *= growthRate;
        if (size >= maxSize) size = maxSize;
        ApplyGrowth();
    }
    private void ApplyGrowth()
    {
        sprite.transform.localScale = new Vector3(size, size, sprite.transform.position.z);
    }
    private void Reproduce()
    {
        var growPoint = growPoints[Random.Range(0, growPoints.Length)];
        if (gameController.grassControllers.ContainsKey(growPoint) == true) return;
        Instantiate(prefab, growPoint, Quaternion.identity);
        size -= reproduceEffort;
    }
}

मैं परिणामों से खुश हूं:

enter image description here

0
Lucas Venturini 14 नवम्बर 2021, 20:11

2 जवाब

सबसे बढ़िया उत्तर

मैं वर्तमान में प्रोफाइलर में क्या देख रहा हूं।

Physics एकता का एक बहुत व्यापक शब्द है, जो आपको बताता है कि Nvidia Physx है उपयोग में। यह "निष्पादक*" टकराव की जाँच के लिए ज़िम्मेदार है, और यह वही है जो आप वर्तमान में देख रहे हैं।

क्योंकि Physx कैसे काम करता है, उन वस्तुओं के लिए जो "निकट-पास" हैं, आप मूल रूप से प्रत्येक FixedUpdate पर "प्रत्येक-साथ-प्रत्येक" की जांच कर रहे हैं।

प्रोफाइलर में अधिक जानकारी है जिस पर फिजिक्स के सबसिस्टम इस समय दिए गए फ्रेम स्पैन में 800ms ले रहे हैं।

इस समस्या को कैसे ठीक करें

एकता भौतिकी द्वारा कभी भी स्थानांतरित नहीं होने वाली हर चीज के लिए टकराव, टकराने वाले और ट्रिगर का उपयोग करना बंद कर दें। इसके बजाय "प्रत्येक के साथ-साथ" चेक किए बिना "यदि घास वस्तु के बगल में है" की जांच करने के लिए चतुर डेटा संरचनाओं का उपयोग करें

  1. आस-पास उगाई गई प्रत्येक घास का संदर्भ रखें और ऐसी वस्तुओं की सूची का उपयोग करके देखें कि क्या पास में घास है (कार्यान्वयन के लिए मुश्किल लेकिन बहुत इष्टतम) नोट: ऐसी सूची में आपके पास कभी भी 8 से अधिक ऑब्जेक्ट नहीं होने चाहिए।
  2. एक "ग्रिड" आधारित प्रणाली या तथाकथित विखंडू को लागू करें। फिर प्रत्येक ग्रिड सेल में घास की जांच करें यदि दिए गए सेल पर कब्जा है। यह केवल तभी काम करेगा जब आपके पास एक दूसरे से समान दूरी पर सब कुछ हो, लेकिन इस प्रतिबंध के बिना काम करने के लिए अनुकूलित किया जा सकता है - (यह सबसे सार्वभौमिक समाधान है जिसका आपको उपयोग करना चाहिए, सबसे आसान ओ लागू करना भी।)
  3. Quadtree (3D के लिए Octtree) का उपयोग करें। यह बढ़े हुए रिज़ॉल्यूशन के कॉन्टेंट-साइज़ नेस्टेड "चंक्स" बनाएगा जो आपको यह जाँचने के लिए O (LogN) प्रदर्शन देगा कि क्या आपके बगल में कुछ है। (यह सीमित स्थान वाले खेलों के लिए सबसे अच्छा है, जिसे आप जानते हैं कि मानचित्र आकार की सीमाएँ हैं)। नोट: Physx हुड के नीचे इसका उपयोग करता है, लेकिन यह 3D और भौतिकी आंदोलन के लिए फूला हुआ है
  4. ब्रूट फोर्स विधि यदि आप जानते हैं कि आपके पास कभी अधिक नहीं होगा तो मान लें कि 1000 घास की वस्तुएं हैं और आप जानते हैं कि "ग्रो" विधि का उपयोग प्रति फ्रेम एक से कम बार किया जाएगा, आपके पास एक नियंत्रक हो सकता है सभी घास वस्तुओं की सूची। एक सूची में 1000 से अधिक तत्वों की पुनरावृत्ति में प्लेटफॉर्म के आधार पर 0.01-0.05ish मिलीसेकंड का समय लगेगा। तो मैं कहूंगा कि सहने योग्य लागत के साथ रहने के लिए।

निजी तौर पर, मैं अभी के लिए नंबर 4 के साथ जाऊंगा, और नंबर 2 या 3 तक विस्तार करूंगा जब ग्रो की लागत कम-अंत वाले प्लेटफार्मों के लिए लैग-स्पाइक्स उत्पन्न करेगी। (3-5ms या अधिक)

1
Tomasz Juszczak 15 नवम्बर 2021, 00:10
धन्यवाद! बहुत मददगार! मुझे लगता है कि मैं कल #1 और #4 के मिश्रण की कोशिश करूँगा। मैं वस्तुओं को स्थिति से स्टोर करने के लिए कुंजी-मूल्य जोड़े की एक सरणी बनाने की सोच रहा हूं, इसलिए मुझे केवल 8 संभावित पदों पर पुनरावृति करना है, लेकिन ऑब्जेक्ट के आधार पर प्रत्येक आस-पास की वस्तु का संदर्भ रखने से परेशान नहीं होना चाहिए। तुम क्या सोचते हो?
 – 
Lucas Venturini
15 नवम्बर 2021, 00:51
1
यह भी एक बहुत अच्छा विचार है! यद्यपि आपको वेक्टर2इंट को एक कुंजी के रूप में उपयोग करने और फ़्लोट से बचने की आवश्यकता होगी क्योंकि यदि आप फ्लोट का उपयोग कर रहे हैं तो यह समान मानों के लिए अद्वितीय हैश मान उत्पन्न कर सकता है।
 – 
Tomasz Juszczak
15 नवम्बर 2021, 00:59
जानकारी के लिए धन्यवाद। मैं इंतजार नहीं कर सका और कुछ बदलावों को तुरंत लागू कर दिया। यह वास्तव में अच्छी तरह से काम करता है, इसलिए मैं अभी के लिए केवल की-वैल्यू-फ्लोट मुद्दे पर ध्यान देने जा रहा हूं। किसी मोड़ पर घास से आगे बढ़ना है।
 – 
Lucas Venturini
15 नवम्बर 2021, 01:25

संयंत्र प्रतिपादन घटक को अक्षम करें। जो स्क्रीन पर दिखाई नहीं दे रहे हैं।

-1
Pedro Henrique Pires Rodrigues 14 नवम्बर 2021, 22:16
प्रत्येक पौधा स्क्रीन पर उसी क्षण प्रकट होता है, जिस क्षण वे तत्काल होते हैं।
 – 
Lucas Venturini
14 नवम्बर 2021, 22:54
1
यह प्रशंसा यह नहीं बताती है कि इससे उसे इस मुद्दे को हल करने में कैसे मदद मिलेगी। कृपया विस्तार करें और एक कोड नमूना प्रदान करें कि इस तरह की चीज़ को कैसे लागू किया जा सकता है?
 – 
Tomasz Juszczak
15 नवम्बर 2021, 00:10