मेरे पास एक घास-प्रीफ़ैब है जो कुछ समय के बाद प्रीफ़ैब का ग्रिड बनाने के बाद खुद को 8 में से एक स्थिति में तुरंत चालू कर देता है। वर्तमान में मैं प्रीफ़ैब प्रति 8 ट्रिगर-कोलाइडर का उपयोग करके अन्य घास-प्रीफ़ैब की जांच करता हूं। नीचे स्क्रीनशॉट देखें:
समस्या यह है कि उनमें से केवल एक समूह को तुरंत चालू करने के बाद एकता धीमी हो जाती है।
मैं प्रदर्शन सुधारों से संबंधित किसी भी सुझाव के लिए तैयार हूं।
यहाँ मेरा कोड है:
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;
}
}
संपादित करें: ऐसा लगता है कि प्रदर्शन पर मुख्य ड्रैग सभी भौतिक-जांच हैं। क्या किसी निश्चित क्षेत्र में अन्य गेमऑब्जेक्ट्स की जांच करने के तरीके हैं जो अधिक प्रदर्शनकारी हैं?
समाधान: मैंने सभी वस्तुओं को उनकी स्थिति के अनुसार सहेजने के लिए एक 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;
}
}
मैं परिणामों से खुश हूं:
2 जवाब
मैं वर्तमान में प्रोफाइलर में क्या देख रहा हूं।
Physics
एकता का एक बहुत व्यापक शब्द है, जो आपको बताता है कि Nvidia Physx है उपयोग में। यह "निष्पादक*" टकराव की जाँच के लिए ज़िम्मेदार है, और यह वही है जो आप वर्तमान में देख रहे हैं।
क्योंकि Physx कैसे काम करता है, उन वस्तुओं के लिए जो "निकट-पास" हैं, आप मूल रूप से प्रत्येक FixedUpdate
पर "प्रत्येक-साथ-प्रत्येक" की जांच कर रहे हैं।
प्रोफाइलर में अधिक जानकारी है जिस पर फिजिक्स के सबसिस्टम इस समय दिए गए फ्रेम स्पैन में 800ms ले रहे हैं।
इस समस्या को कैसे ठीक करें
एकता भौतिकी द्वारा कभी भी स्थानांतरित नहीं होने वाली हर चीज के लिए टकराव, टकराने वाले और ट्रिगर का उपयोग करना बंद कर दें। इसके बजाय "प्रत्येक के साथ-साथ" चेक किए बिना "यदि घास वस्तु के बगल में है" की जांच करने के लिए चतुर डेटा संरचनाओं का उपयोग करें
- आस-पास उगाई गई प्रत्येक घास का संदर्भ रखें और ऐसी वस्तुओं की सूची का उपयोग करके देखें कि क्या पास में घास है (कार्यान्वयन के लिए मुश्किल लेकिन बहुत इष्टतम) नोट: ऐसी सूची में आपके पास कभी भी 8 से अधिक ऑब्जेक्ट नहीं होने चाहिए।
- एक "ग्रिड" आधारित प्रणाली या तथाकथित विखंडू को लागू करें। फिर प्रत्येक ग्रिड सेल में घास की जांच करें यदि दिए गए सेल पर कब्जा है। यह केवल तभी काम करेगा जब आपके पास एक दूसरे से समान दूरी पर सब कुछ हो, लेकिन इस प्रतिबंध के बिना काम करने के लिए अनुकूलित किया जा सकता है - (यह सबसे सार्वभौमिक समाधान है जिसका आपको उपयोग करना चाहिए, सबसे आसान ओ लागू करना भी।)
- Quadtree (3D के लिए Octtree) का उपयोग करें। यह बढ़े हुए रिज़ॉल्यूशन के कॉन्टेंट-साइज़ नेस्टेड "चंक्स" बनाएगा जो आपको यह जाँचने के लिए O (LogN) प्रदर्शन देगा कि क्या आपके बगल में कुछ है। (यह सीमित स्थान वाले खेलों के लिए सबसे अच्छा है, जिसे आप जानते हैं कि मानचित्र आकार की सीमाएँ हैं)। नोट: Physx हुड के नीचे इसका उपयोग करता है, लेकिन यह 3D और भौतिकी आंदोलन के लिए फूला हुआ है
- ब्रूट फोर्स विधि यदि आप जानते हैं कि आपके पास कभी अधिक नहीं होगा तो मान लें कि 1000 घास की वस्तुएं हैं और आप जानते हैं कि "ग्रो" विधि का उपयोग प्रति फ्रेम एक से कम बार किया जाएगा, आपके पास एक नियंत्रक हो सकता है सभी घास वस्तुओं की सूची। एक सूची में 1000 से अधिक तत्वों की पुनरावृत्ति में प्लेटफॉर्म के आधार पर 0.01-0.05ish मिलीसेकंड का समय लगेगा। तो मैं कहूंगा कि सहने योग्य लागत के साथ रहने के लिए।
निजी तौर पर, मैं अभी के लिए नंबर 4 के साथ जाऊंगा, और नंबर 2 या 3 तक विस्तार करूंगा जब ग्रो की लागत कम-अंत वाले प्लेटफार्मों के लिए लैग-स्पाइक्स उत्पन्न करेगी। (3-5ms या अधिक)
संयंत्र प्रतिपादन घटक को अक्षम करें। जो स्क्रीन पर दिखाई नहीं दे रहे हैं।
संबंधित सवाल
नए सवाल
c#
C # (उच्चारण "तेज देखें") Microsoft द्वारा विकसित एक उच्च स्तरीय, सांख्यिकीय रूप से टाइप किया हुआ, बहु-प्रतिमान प्रोग्रामिंग भाषा है। C # कोड आमतौर पर Microsoft के .NET परिवार के टूल और रन-टाइम को लक्षित करता है, जिसमें .NET फ्रेमवर्क, .NET कोर और Xamarin अन्य शामिल हैं। C # या C # के औपचारिक विनिर्देश में लिखे गए कोड के बारे में प्रश्नों के लिए इस टैग का उपयोग करें।