Bu sayfa yaygın performans sorunlarını ve bunları hafifletmek için en iyi uygulamaları açıklamaktadır.
Script hesaplaması
Luau kodundaki maliyetli işlemler daha uzun sürede işlenir ve dolayısıyla kare hızını etkileyebilir. Paralel olarak yürütülmediği sürece, Luau kodu senkron olarak çalışır ve bir iş parçacığını bırakana kadar ana iş parçacığını engeller.
Yaygın sorunlar
Tablo yapılarında yoğun işlemler - Seri hale getirme, tersine seri hale getirme ve derin klonlama gibi karmaşık işlemler, özellikle büyük tablo yapıları üzerinde yüksek performans maliyeti taşır. Bu, bu işlemlerin özyinelemeli olması veya çok büyük veri yapıları üzerinde yineleme yapması durumunda özellikle doğrudur.
Yüksek frekanslı olaylar - Maliyetli işlemleri RunService üzerindeki çerçeve tabanlı olaylara bağlamak, frekansı sınırlamadan bu işlemlerin her çerçevede tekrarlanmasına neden olur ve bu da genellikle hesaplama süresinde gereksiz bir artışa yol açar. Bu olaylar şunlardır:
Hafifletme
- RunService olayları üzerinde kodu sınırlı bir şekilde uygulayın, yüksek frekanslı çağrının gerekli olduğu durumlarla sınırlayın (örneğin, kamerayı güncelleme). Çoğu diğer kodu diğer olaylarda veya daha az sıklıkla bir döngü içinde çalıştırabilirsiniz.
- task.wait() kullanarak büyük veya maliyetli görevleri bölün, böylece işi birden fazla çerçeve boyunca yayabilirsiniz.
- Gereksiz yere maliyetli işlemleri tanımlayın ve veri modeline erişmesi gerekmeyen hesaplama gerektiren görevler için çoklu iş parçacığı kullanın.
- Bazı sunucu tarafı betikleri, bir betiği bayt kod yerine makine koduna derleyen yerel kod üretiminden yararlanabilir.
MicroProfiler kapsamları
| Kapsam | İlişkili hesaplama |
| RunService.PreRender | PreRender olayında yürütülen kod |
| RunService.PreSimulation | Stepped olayında yürütülen kod |
| RunService.PostSimulation | Heartbeat olayında yürütülen kod |
| RunService.Heartbeat | Heartbeat olayında yürütülen kod |
MicroProfiler ile betikleri hata ayıklama hakkında daha fazla bilgi için, belirli kodları etiketleme ve debug.profilebegin ve debug.profileend gibi daha fazla özgüllük artırma işlevlerini içeren debug kütüphanesine bakın. Betikler tarafından çağrılan birçok Roblox API yöntemi de yararlı sinyaller sağlayabilecek kendi ilişkili MicroProfiler etiketlerine sahiptir.
Script bellek kullanımı
Bellek sızıntıları, kullanımdan çıktığında çöp toplayıcısının düzgün şekilde serbest bırakamadığı bellek tüketen betikler yazdığınızda meydana gelebilir. Sunucuda sızıntılar özellikle yaygındır çünkü birkaç gün çevrimiçi kalabilirken, bir istemci oturumu çok daha kısa bir sürede sona erer.
Geliştirici Konsolu'ndaki aşağıdaki bellek değerleri, daha fazla inceleme gerektiren bir sorun gösterebilir:
- LuaHeap - Yüksek veya artan tüketim, bir bellek sızıntısını işaret eder.
- InstanceCount - Sürekli artan örnek sayıları, kodunuzdaki bazı örneklere yapılan referansların çöp toplayıcı tarafından temizlenmediğini gösterir.
- PlaceScriptMemory - Bellek kullanımının betik bazında dökümünü sağlar.
Yaygın sorunlar
Bağlantıları açık bırakma - Motor, bir örneğe bağlı olan olayları ve bağlı geri çağırmada referans verilen değerleri asla çöp toplamaz. Bu nedenle, aktif olay bağlantıları ve bağlı örneklerin içindeki kodlar, bağlantılı işlevler ve referans edilen değerler, olaylar tetiklendiğinde bile bellek çöp toplayıcının kapsamı dışındadır.
Olaylar ait oldukları örnek yok edildiğinde koparılır, ancak Player nesneleri için bunun geçerli olduğunu varsaymak yaygın bir hatadır. Bir kullanıcı oyunu terk ettiğinde, motor otomatik olarak onların temsilcisi Player nesnesini ve karakter modelini yok etmez, bu nedenle Player nesnesine ve karakter modeli altında olan örneklere, örneğin CharacterAdded'ya yapılan bağlantılar, betiklerde koparılmadığı sürece bellek tüketmeye devam eder. Bu, zaman içinde sunucuda yüzlerce kullanıcının oyuna katılıp çıktığı için çok önemli bellek sızıntılarına yol açabilir.
Tablolar - Nitelik gerektirmeyen nesneleri tablolara eklemek ama artık gereksiz olduğunda çıkarmamak, kullanıcı verilerini takip eden tablolalar için özellikle gereksiz bellek tüketimine yol açar. Örneğin, aşağıdaki kod örneği, her kullanıcının katılmasıyla kullanıcı bilgilerini ekleyen bir tablo oluşturur:
Örneklocal playerInfo = {}Players.PlayerAdded:Connect(function(player)playerInfo[player] = {} -- bazı bilgilerend)Bu kayıtları artık gereksiz hale geldiğinde çıkarmazsanız, tablo boyutu büyümeye devam eder ve daha fazla kullanıcı oturuma katıldıkça daha fazla bellek tüketir. Bu tabloyu yineleyen herhangi bir kod da boyut büyüdükçe daha maliyetli hale gelir.
Hafifletme
Bellek sızıntılarını önlemek için tüm kullanılan değerleri temizlemek için:
Tüm bağlantıları koparın - Kod tabanınızda geçin ve her bağlantının aşağıdaki yollardan biriyle temizlendiğinden emin olun:
- Disconnect() işlevini kullanarak manuel olarak disconnect.
- Olayın ait olduğu örneği Destroy() ile yok etmek.
- Bağlantının geri döndüğü betik nesnesini yok etmek.
Oyuncu nesnelerini ve karakterleri ayrıldıktan sonra kaldırın - Kullanıcının ayrılmasından sonra oyuncu nesnelerini ve karakter modellerini otomatik olarak yok etmek için Workspace.PlayerCharacterDestroyBehavior'ı etkinleştirin. İsterseniz, bunları manuel olarak temizleyebilirsiniz:
Örnek oyuncu ve karakter temizliğilocal Players = game:GetService("Players")Players.PlayerAdded:Connect(function(player)player.CharacterRemoving:Connect(function(character)task.defer(character.Destroy, character)end)end)Players.PlayerRemoving:Connect(function(player)task.defer(player.Destroy, player)end)
Fizik hesaplaması
Aşırı fizik simülasyonu, hem sunucu hem de istemci üzerinde her çerçevede artan hesaplama süresinin önemli bir nedeni olabilir.
Yaygın sorunlar
Aşırı fizik zaman adımı sıklığı - Varsayılan olarak, adım davranışı, fizik mekanizmasının karmaşıklığına bağlı olarak 60 Hz, 120 Hz veya 240 Hz'de adım atan uyarlamalı modda çalışır.
Tüm fizik montajlarının 240 Hz'de adım almasını zorlayan geliştirilmiş bir doğruluk modunda da mevcut olup bu, her çerçevede önemli ölçüde daha fazla hesaplama gerektirir.
Simüle edilen nesnelerin aşırı sayıda karmaşıklığı - Simüle edilen daha fazla 3D montajı varsa, fizik hesaplamaları her çerçevede daha uzun sürer. Genellikle oyunlar, simüle edilmesi gerekmeyen nesneleri simüle eder veya ihtiyaç duyduğundan daha fazla kısıtlama ve eklem içeren mekanizmaları vardır.
Aşırı hassas çarpışma algılama - Mesh parçalarının çarpışmaları algılamak için bir CollisionFidelity özelliği vardır ve bu, farklı performans etki seviyeleri ile çeşitli modlar sunar. Mesh parçaları için hassas çarpışma algılama modu, en pahalı performans maliyetine sahiptir ve motorun hesaplama süresini uzatır.
Hafifletme
Simülasyona ihtiyaç duymayan parçaları sabitleyin - Fizik tarafından sürülmeleri gerekmeyen tüm parçaları sabitleyin, örneğin statik NPC'ler için.
Uyarlamalı fizik adımı kullanın - Uyarlamalı adım, fizik mekanizmalarının hesaplama oranını dinamik olarak ayarlar; böylece bazı durumlarda fizik güncellemeleri daha seyrek yapılır.
Mekanik karmaşıklığını azaltın
- Mümkünse, bir montajdaki fizik kısıtlamalarının veya eklemlerinin sayısını en aza indirin.
- Bir mekanizma içindeki kendiliğinden çarpışmaları azaltın, örneğin çocukların birbiriyle çarpışmalarını önlemek için sınırlamalar veya çarpışma yok kısıtlamaları uygulayarak.
Meshler için hassas çarpışma sadakatinin kullanımını azaltın
Kullanıcının fark etmeyeceği küçük veya etkileşime girmeyen nesneler için kutu sadakatini kullanın.
Küçük-orta boy nesneler için, şekle bağlı olarak kutu veya kılçık sadakatlerini kullanın.
Büyük ve çok karmaşık nesneler için mümkünse görünmez parçalar kullanarak özel çarpışmalar oluşturun.
Çarpışmalar gerektirmeyen nesneler için çarpışmaları devre dışı bırakın ve kutu veya kılçık sadakatini kullanın, çünkü çarpışma geometrisi hala bellek içinde saklanır.
Çarpışma geometrisini Studio'da hata ayıklama amaçları için, 3D görüntü alanının sağ üst köşesindeki Görselleştirme Seçenekleri widget'ından Çarpışma sadakati'ni açarak görüntüleyebilirsiniz.
Alternatif olarak, Keşfediciyi CollisionFidelity=PreciseConvexDecomposition filtresi uygulamak, hassas sadakati olan tüm mesh parçalarının sayısını gösterecek ve bunları kolayca seçmenizi sağlayacaktır.
Hassasiyet ve performans gereksinimlerinizi dengeleyen bir çarpışma sadakati seçimi konusunda derinlemesine bir rehberlik için Fizik ve görüntüleme parametrelerini ayarlayın.
MicroProfiler kapsamları
| Kapsam | İlişkili hesaplama |
| physicsStepped | Genel fizik hesaplaması |
| worldStep | Her çerçevede alınan kesirli fizik adımları |
Fizik bellek kullanımı
Fizik hareketi ve çarpışma algılama bellek tüketir. Mesh parçalarının çarpışma sınırlarını değerlendirmek için kullanılacak yaklaşımı belirleyen bir CollisionFidelity özelliği vardır.
Yaygın sorun
Varsayılan ve hassas çarpışma algılama modları, daha düşük hassasiyetli çarpışma şekillerine sahip iki diğer moddan önemli ölçüde daha fazla bellek tüketir.
PhysicsParts altında yüksek bellek tüketimi seviyeleri görürseniz, oyununuzdaki nesnelerin çarpışma sadakatinin azaltılması gerektiğini keşfetmeniz gerekebilir.
Nasıl hafifletilir
Çarpışma sadakati için kullanılan belleği azaltmak için:
- Çarpışmalara ihtiyaç duymayan parçalar için, BasePart.CanCollide, BasePart.CanTouch ve BasePart.CanQuery'yi false olarak ayarlayarak çarpışmalarını devre dışı bırakın.
- Çarpışma hassasiyetini CollisionFidelity ayarını kullanarak azaltın. Box en düşük bellek yüküne sahiptir ve Default ve Precise genellikle daha pahalıdır.
- Küçük sabit parçaların çarpışma sadakatini Box olarak ayarlamak genellikle güvenlidir.
- Çok karmaşık büyük meshler için, daha küçük nesnelerden oluşan kendi çarpışma meshinizi kutu çarpışma sadakatiyle oluşturmak isteyebilirsiniz.
İnsanlar
Humanoid, oyuncu ve oyuncu olmayan karakterler (NPC'ler) için geniş bir işlevsellik yelpazesi sunan bir sınıftır. Güçlü olmasına rağmen, bir Humanoid önemli bir hesaplama maliyeti ile gelir.
Yaygın sorunlar
- NPC'lerde tüm HumanoidStateTypes'ı açık bırakma - Belirli HumanoidStateTypes'in açık bırakılmasının bir performans maliyeti vardır. NPC'leriniz için gerekli olmayanları devre dışı bırakın. Örneğin, NPC'niz merdiven tırmanmayacaksa Climbing durumunu devre dışı bırakmak güvenlidir.
- Sıklıkla Humanoids veya cilalı MeshParts ile modelleri örneklemek, değiştirmek ve yeniden canlandırmak - Bu motorun işlenmesi için yoğun olabilir, özellikle bu modeller katmanlı kıyafetler kullanıyorsa. Bu, sık sık yeniden doğan avatarların olduğu oyunlarda özellikle sorun yaratabilir.
- MicroProfiler'da uzun süreli updateInvalidatedFastClusters etiketleri (4 ms'den fazla), avatarın örneklendirmesi/değiştirilmesinin aşırı geçersiz kılmalara neden olduğunu gösterir.
- Gerekmediği durumlarda Humanoid'leri kullanmak - Hareket etmeyen statik NPC'lerin genellikle Humanoid sınıfına ihtiyacı yoktur.
- NPC'lerin sunucudan büyük bir sayıda animasyon oynatması - Sunucuda çalışan NPC animasyonları, sunucuda simüle edilmelidir ve istemciye çoğaltılmalıdır. Bu gereksiz bir yük olabilir.
- Gereksiz boyut ve ölçek değişiklikleri gerçekleştirmek - Boyut/ölçek değişiklikleri FastCluster'ın yeniden oluşturulmasına neden olur. FastCluster ile ilgili performans sorunları yaşıyorsanız, bu süre zarfında bunu azaltmaya çalışın. Benzer şekilde, diğer özellik değişiklikleri de FastCluster'ın yeniden oluşturulmasına neden olabilir, bu nedenle genel olarak bu değişiklikleri mümkün olduğunca azaltın.
Hafifletme
- NPC animasyonlarını istemcide oynatın - Çok sayıda NPC'ye sahip oyunlarda, istemcide Animator oluşturarak animasyonları yerel olarak çalıştırmayı düşünün. Bu, sunucu üzerindeki yükü azaltır ve gereksiz çoğaltma gereksinimini ortadan kaldırır. Ayrıca, NPC'ler yalnızca karaktere yakınken animasyonları oynatma gibi ek optimizasyonların yapılmasına olanak tanır.
- Humanoid'lerin yerine performans dostu alternatifler kullanın - NPC modellerinin mutlaka bir insansı nesne içermesi gerekmez.
- Statik NPC'ler için, hareket etmeleri gerekmiyorsa sadece animasyon oynatmaları gereken basit bir AnimationController kullanın.
- Hareketli NPC'ler için, NPC'lerinizin karmaşıklığına bağlı olarak kendi hareket denetleyicinizi uygulamayı ve animasyonlar için bir AnimationController kullanmayı düşünün.
- Kullanılmayan insansal durumları devre dışı bırakın - Her humanoid için gerekli durumları yalnızca etkinleştirmek için Humanoid:SetStateEnabled()'ı kullanın.
- Sık yeniden doğan NPC modellerini havuzlayın - Bir NPC'yi tamamen yok etmek yerine, NPC'yi pasif NPC havuzuna gönderin. Bu şekilde, yeniden doğması gereken yeni bir NPC gerektiğinde, havuzdan bir NPC'yi yeniden etkinleştirebilirsiniz. Bu işlem havuzlama olarak adlandırılır ve karakterlerin örneklenmesi gereken zamanların miktarını en aza indirir.
- Sadece kullanıcılar yakında olduğunda NPC'leri doğurun - Kullanıcılar menzil dışındayken NPC'leri doğurmayın ve kullanıcılar menzil dışına çıktığında onları kaldırın.
- Örneklenene kadar avatar hiyerarşisinde değişiklik yapmaktan kaçının - Bir avatar hiyerarşisinin belirli değişiklikleri önemli performans etkilerine sahip olabilir. Bazı optimizasyonlar mevcuttur:
- Özel prosedürel animasyonlar için, JointInstance.C0 ve JointInstance.C1 özelliklerini güncellemeyin. Bunun yerine Motor6D.Transform özelliğini güncelleyin.
MicroProfiler kapsamları
| Kapsam | İlişkili hesaplama |
| stepHumanoid | Humanoid kontrolü ve fiziği |
| stepAnimation | Humanoid ve animator animasyonu |
| updateInvalidatedFastClusters | Bir avatarın örneklenmesi veya değiştirilmesiyle ilişkili |
Görselleştirme
İstemcinin her çerçevede harcadığı zamanın önemli bir kısmı mevcut çerçevedeki sahneyi görüntülemektedir. Sunucu, herhangi bir görselleştirme işlemi yapmaz, bu nedenle bu bölüm yalnızca istemci özeldir.
Çizim çağrıları
Bir çizim çağrısı, motorun GPU'ya bir şeyi görüntülemek için verdiği talimatların bir setidir. Çizim çağrılarının önemli bir yükü vardır. Genel olarak, her çerçevede daha az çizim çağrısı varsa, bir çerçeveyi görüntülemek için harcanan hesaplama zamanı daha azdır.
Stüdyo'daki Render İstatistikleri ⟩ Zamanlama öğesi ile şu anda kaç tane çizim çağrısının yapıldığını görebilirsiniz. İstemci üzerinde Render İstatistikleri görüntülemek için ShiftF2 tuşlarına basabilirsiniz.
Verilen bir çerçevede sahnenizde çizilmesi gereken daha çok nesne varsa, GPU'ya daha fazla çizim çağrısı gönderilir. Ancak, Roblox Motoru, aynı doku özelliklerine sahip olan kimlikleri aynı çizim çağrısına dönüştüren bir örnekleme süreci kullanır. Özellikle, aynı MeshContent'a sahip birden fazla mesh, aşağıdaki durumlarda bir çizim çağrısında bir arada işlenir:
- SurfaceAppearances varsa birbirine eşitse, aksi takdirde TextureContents eşitse.
- Hem SurfaceAppearance hem de MeshPart.TextureID mevcut olmadığında materyaller birbirine eşitse.
Diğer yaygın sorunlar
Aşırı nesne yoğunluğu - Eğer birçok nesne yüksek yoğunlukta bir arada toplanmışsa, sahnenin bu alanını görüntülemek daha fazla çizim çağrısı gerektirir. Haritanızın belirli bir parçasına baktığınızda kare hızınızın düştüğünü görüyorsanız, bu alandaki nesne yoğunluğunun çok yüksek olduğuna dair iyi bir işaret olabilir.
Dekorlar, dokular ve parçacıklar gibi nesneler iyi gruplandırılmaz ve ek çizim çağrıları oluşturur. Bir sahnedeki bu nesne türlerine özellikle dikkat edin. Özellikle, ParticleEmitters'da yapılan özellik değişiklikleri performansı dramatik bir şekilde etkileyebilir.
Kaçırılan örneklendirme fırsatları - Sıklıkla, bir sahne aynı mesh'i birkaç kez içerecek şekilde tasarlanmıştır, ancak mesh'in her bir kopyası farklı mesh veya doku varlık kimliklerine sahiptir. Bu, örneklemeyi engeller ve gereksiz çizim çağrılarına neden olabilir.
Bu sorunun yaygın bir nedeni, tüm sahnenin bir kerede içe aktarılmasıdır, bunun yerine bireysel varlıkların Roblox'a aktarılması ve daha sonra sahneyi oluşturmak için yinelemeli şekilde çoğaltılmasıdır.
Aşağıdaki örnek gibi basit bir betik, farklı mesh kimliklerini kullanan aynı isimli mesh parçalarını belirlemenize yardımcı olabilir:
for _,descendant in workspace:GetDescendants() doif descendant:IsA("MeshPart") thenprint(descendant.Name .. ", " .. descendant.MeshId)endendÇıktı ( Yığın Satırları etkin) aşağıdaki gibi görünebilir. Tekrar eden satırlar aynı mesh'in yeniden kullanımını gösterir, bu iyidir. Benzersiz satırlar mutlaka kötü değildir, ancak adlandırma şemanıza bağlı olarak, oyununuzda birden fazla olabileceğini gösterebilir:
BüyükKayalar, rbxassetid://106420009602747 (x144) -- iyiBüyükKayalar, rbxassetid://120109824668127BüyükKayalar, rbxassetid://134460273008628BüyükKayalar, rbxassetid://139288987285823BüyükKayalar, rbxassetid://71302144984955BüyükKayalar, rbxassetid://90621205713698BüyükKayalar, rbxassetid://113160939160788BüyükKayalar, rbxassetid://135944592365226 -- tüm potansiyel tekrarlarAşırı nesne karmaşıklığı - Çizim çağrılarının sayısından daha önemli olmasa da, sahnedeki üçgen sayısı bir çerçevenin render edilme süresini etkiler. Çok fazla karmaşık mesh'e sahip sahneler yaygın bir sorundur; ayrıca, MeshPart.RenderFidelity özelliği çok fazla mesh üzerinde Precise olarak ayarlandığında da sorun yaratabilir.
Aşırı gölge oluşturma - Gölge işleme, pahalı bir süreçtir ve gölge oluşturma (veya gölgelerden etkilenen küçük parçaların yüksek sayısı ve yoğunluğu) olan haritalarda performans sorunları olabilir.
Yüksek şeffaflık aşırı çizimi - Kısmen şeffaf olan nesneleri birbirine yakın yerleştirmek, motorun örtüşen pikselleri birden fazla kez render etmesine neden olur; bu da performansı etkileyebilir. Bu sorunun nasıl tanımlanacağı ve düzeltileceği hakkında daha fazla bilgi için Katmanlı şeffaflıkları silin başlıklı bölüme bakın.
Gereksiz cilalı MeshPart hareketi - Humanoid olmayan bir Modelin parçası olan cilalı MeshPart'lar, mekansal olarak düzenlenmiş FastClusters kullanılarak gruplandırılır. Bu MeshPart'lar hareket ettiğinde, bunların sürekli olarak bu mekansal kümeleme yapılarına eklenmesi ve çıkarılması gerekir; bu da kümelerin yenilenmesine zorlar ve performansı etkiler.
- Çok etkili bir çözüm, Model içinde bir Humanoid yerleştirmektir. Humanoid'in varlığı, varsayılan mekansal kümeleme davranışını geçersiz kılarak tüm Model için tek bir birleşik FastCluster kullanımını zorlar. Bu nedenle, konum güncellemeleri artık küme yenilerini gerektiremez ve böylece performans darboğazını azaltır. Bu teknik, hareket etmesi beklenen MeshPart'lar için kesinlikle saklı tutulmalıdır; çünkü hafıza aşırı yükü oluşturabilir ve mekanik optimizasyonun faydalarını ortadan kaldırabilir. Bu gibi değişiklikler yaptıktan sonra oyununuzun performansını profil almanızı öneririz. Daha fazla bilgi için Humanoid performans ipuçlarına göz atın.
Model içinde çok fazla parça - Bir Modelde çok fazla parça olması, bir parçanın özelliğinin değişebileceği potansiyeli nedeniyle yenilemelerin daha sık gerçekleşmesine neden olabilir. FastCluster kullanırken bir Model içinde parçaların dengeli olmasını sağlayın.
Hafifletme
Aynı meshleri örnekleyip benzersiz mesh miktarını azaltın - Tüm aynı meshlerin aynı temel varlık kimliklerine sahip olmasını sağlarsanız, motor onları tanıyabilir ve tek bir çizim çağrısında yeniden oluşturabilir. Her bir mesh'iermapında yalnızca bir kez yükleyin ve ardından yeniden kullanılmak üzere Stüdyo'da çoğaltın; büyük haritaları bir bütün olarak içe aktarmaktan kaçının, çünkü bu durum aynı meshlerin ayrı içerik kimliklerine sahip olmasına ve motor tarafından benzersiz varlıklar olarak tanınmasına neden olabilir. Paketler varlıkların yeniden kullanımında faydalı bir mekanizmadır.
Kümeleme - Kümeleme, nihai render edilen çerçeveye dahil olmayan nesneler için çizim çağrılarını ortadan kaldırma sürecidir. Varsayılan olarak, motor görünüm alanının (frustum kümelemesi) dışındaki nesneler için çizim çağrılarını atlar, ayrıca diğer nesneler tarafından görünümden gizlenen parçalar, mesh'ler ve araziyi (gizlenme kümelemesi) atlar. Bazen, iç mekânlar gibi belirli senaryolarda bir oda veya portal sistemi uygulamak ve nesneleri manuel olarak kükleme işlemi yaparak çizim çağrılarını veya genel hesaplama yükünü daha da azaltmayı düşünebilirsiniz.
Modellerin ayrıntı seviyesini azaltma - örnek akışı etkinleştirin ve dünya modellerinizin LevelOfDetail özelliğini SLIM olarak ayarlayarak, kamera ile mesafe arttıkça optimize edilmiş hafif SLIM mesh'leri renderlayın.
Avatarların detay seviyesini azaltma - örnek akışını etkinleştirin ve Workspace.EnableSLIMAvatars özelliğini ayarlayın; böylece kamera ile mesafe arttıkça platform avatar modellerinin her türlü aksesuar veya katmanlı giysi ile birlikte optimize edilmiş hafif avatar temsilleri ile render edilmesi sağlanır.
Render sadakatini azaltma - MeshPart.RenderFidelity'ni Automatic veya Performance olarak ayarlayın. Bu, meshlerin daha az karmaşık alternatiflere geri dönmesine izin verir; bu da çizilmesi gereken poligon sayısını azaltabilir.
Uygun parçalarda ve ışık nesnelerinde gölge oluşturmayı devre dışı bırakma - Roblox motoru, istemci grafik kalitesi seviyesi azaldıkça gölge kalitesini otomatik olarak düşürür; 4'ün altındaki kalitelerde gölgeleri tamamen devre dışı bırakır. Ancak, gölgeler etkinken performansı artırmak ve gölgelerin açık kalma olasılığını artırmak için ışık nesneleri ve parçalardan gölge oluşturma özelliklerini seçici bir şekilde devre dışı bırakabilirsiniz. Edit zamanında veya dinamik olarak, bu gibi bazı optimizasyonları yapmayı düşünebilirsiniz:
BasePart.CastShadow özelliğini kullanarak, gölge oluşumunun muhtemel olmadığı küçük parçalarda gölge oluşturmayı devre dışı bırakın. Bu strateji, kullanıcının kamerasından uzak parçalara uygulandığında oldukça etkilidir.
Mümkünse hareket eden nesnelerin gölgelerini devre dışı bırakın.
Nesnelerin gölge oluşturmasına gerek yoksa, Light.Shadows'ı ışık nesnelerine devre dışı bırakın.
Işık nesnelerinin aralığını ve açısını sınırlayın.
Daha az ışık nesnesi kullanın.
İç mekânlarda belirli bir aralık dışındaki ışıkları devre dışı bırakmayı düşünün veya odadan odaya ayrı olarak düşünün.
MicroProfiler kapsamları
| Kapsam | İlişkili hesaplama |
| Prepare and Perform | Genel render işlemi |
| Perform/Scene/computeLightingPerform | Işık ızgarası ve gölge güncellemeleri |
| LightGridCPU | Voksel ışık ızgarası güncellemeleri |
| ShadowMapSystem | Gölge haritalama |
| Perform/Scene/UpdateView | Renderleme ve parçacık güncellemeleri için hazırlanma |
| Perform/Scene/RenderView | Renderleme ve sonrası işleme |
Ağ ve çoğaltma
Ağ ve çoğaltma, verilerin sunucu ve bağlı istemciler arasında gönderilme sürecini açıklar. Bilgiler her çerçevede istemci ve sunucu arasında gönderilir; ancak daha büyük miktarda bilgi daha fazla hesaplama süresi gerektirir.
Yaygın sorunlar
Aşırı uzaktan trafik - RemoteEvent veya RemoteFunction nesneleri üzerinden büyük miktarda veri göndermek veya bunları çok sık çağırmak, her çerçevede gelen paketleri işlemek için büyük miktarda CPU süresi harcanmasına neden olabilir. Yaygın hatalar şunları içerir:
- Yeniden çoğaltılmasına gerek olmayan verileri her çerçevede yeniden çoğaltmak.
- Kullanıcı girişine bağlı olarak herhangi bir mekanizma olmadan veri çoğaltmak.
- Gereksiz verileri göndermek. Örneğin, bir kullanıcı bir öğe satın aldığında, satın alınan öğenin detaylarını göndermek yerine, oyuncunun tüm envanterini göndermek.
Karmaşık örnek ağaçlarının oluşturulması veya kaldırılması - Sunucudaki veri modelinde bir değişiklik yapıldığında, bağlı istemcilere çoğaltılır. Bu, çalışma zamanında haritalar gibi büyük örnek hiyerarşilerini oluşturmak ve yok etmek çok ağ yoğun olabilir.
Buradaki yaygın bir suçlu, riglerde Animasyon Editörü eklentileri tarafından kaydedilen karmaşık animasyon verisidir. Bunlar, oyun yayımlanmadan önce kaldırılmazsa ve animasyonlu model düzenli olarak kopyalanıyorsa, gereksiz yere büyük miktarda veri çoğaltılacaktır.
Sunucu tarafı TweenService - TweenService bir nesneyi sunucu tarafında tweenlemek için kullanılıyorsa, tweenlenen özellik her çerçevede her istemciye çoğaltılır. Bu sadece tween'in istemcilerin gecikmesi değiştikçe sarsıntılı hale gelmesine neden olmakla kalmaz, gereksiz ağ trafiği yaratır.
Hafifletme
Gereksiz çoğaltmayı azaltmak için aşağıdaki taktikleri kullanabilirsiniz:
- Uzaktan olaylar aracılığıyla büyük miktarda veri göndermekten kaçının. Bunun yerine, yalnızca gerekli verileri daha düşük bir sıklıkta gönderin. Örneğin, bir karakterin durumunu değiştiğinde çoğaltın, her çerçevede değil.
- Karmaşık örnek ağaçlarını (haritalar gibi) parçalara ayırarak yükleyin, böylece bu işlerin çoğaltılmasını birden fazla çerçeve boyunca dağıtayabilirsiniz.
- Animasyon meta verilerini temizleyin, özellikle riglerin animasyon dizinini dönüştürme sonrası.
- Gereksiz örnek çoğaltımını sınırlayın, özellikle sunucunun oluşturulan örnekler hakkında bilgi sahibi olmasına gerek olmadığı durumlarda. Bu şunları içerir:
- Bir patlama veya sihirli bir büyü patlaması gibi görsel efektler. Sunucu, sonucu belirlemek için yalnızca yeri bilmesi yeterli olurken, istemciler görselleri yerel olarak yaratabilir.
- Birinci şahıs öğe görünümleri.
- Nesneleri istemcide tweenlemek.
MicroProfiler kapsamları
| Kapsam | İlişkili hesaplama |
| ProcessPackets | Gelen ağ paketleri için işleme, olay çağrıları ve özellik değişiklikleri |
| Allocate Bandwidth and Run Senders | Sunuculardaki ilgili giden etkinlikler |
Varlık bellek kullanımı
İçerik oluşturucuların istemci bellek kullanımını iyileştirmek için kullanabileceği en etkili mekanizma örnek akışı etkinleştirmektedir.
Örnek akışı
Örnek akışı, gereksiz parçaları yükleyip uygulama modelinin bir kısmını yükleyerek bellek kullanımını önemli ölçüde azaltmaya ve 클라이언이 시스템 압력을 겪을 때 충돌을 방지하는 능력을 높ır.
Bellek sorunlarıyla karşılaşıyorsanız ve örnek akışını devre dışı bıraktıysanız, oyununuzu desteklemek için güncellemeniz gerekecek, özellikle 3D dünyanız büyükse. Örnek akışı 3D uzaydaki mesafeye dayanır, bu nedenle daha büyük dünyalar doğal olarak ondan daha fazla fayda sağlar.
Örnek akışı etkinleştirildiğinde, bunun yoğunluğunu artırabilirsiniz. Örneğin, şunları düşünün:
- Mümkün olduğunda Enum.ModelStreamingMode.Persistent kullanımını azaltın. Eğer bunu bir uyumluluk tedbiri olarak kullanıyorsanız, betiklerinizi güncellemeniz gerekebilir.
- Workspace.StreamingMinRadius ve Workspace.StreamingTargetRadius değerlerini azaltın.
Akış seçenekleri ve bunların avantajları hakkında daha fazla bilgi için akış özelliklerini görün.
Diğer yaygın sorunlar
Varlık çoğaltılması - Yaygın bir hata, aynı varlığın birden fazla kez yüklenmesi ve farklı varlık kimliklerine yol açmasıdır. Bu, aynı içeriğin belleğe birden fazla kez yüklenmesine neden olabilir.
Aşırı varlık hacmi - Varlıklar benzer olsa bile, aynı varlığı yeniden kullanma ve bellek tasarrufu fırsatlarının kaçırıldığı durumlar vardır.
Ses dosyaları - Ses dosyaları, özellikle hepsini istemcide aynı anda yüklemek yerine, oyununuzun yalnızca bir kısmı için gerekenleri yüklemek iyi bir strateji olabilir.
Yüksek çözünürlüklü dokular - Grafik bellek tüketimi, diskteki doku boyutuyla ilgili değildir; dokudaki piksel sayısı bellek kullanımını belirler. Örneğin, 1024x1024 piksel dokusu, 512x512 piksel dokusunun grafik bellek kullanımının dört katını tüketir.
Roblox'a yüklenen resimler, sabit bir formata dönüştürülür, bu nedenle daha az bayt içeren bir renk modelinde resim yüklemenin bellek faydası yoktur. Benzer şekilde, yüklemeden önce resimleri sıkıştırmak veya ihtiyaç duymayan resimlerde alfa kanalını kaldırmak diskte resim boyutunu azaltabilir, fakat bellek kullanımını iyileştirmez.
Oyun yüklendiğinde, motor öncelikle düşük kaliteli dokularla başlayıp, kullanılabilir cihaz belleğine, kameranın mesafesine, dokunun kapladığı ekran alanına ve diğer faktörlere bağlı olarak kaliteyi artırır. Yine de, dokularınızı stratejik bir şekilde boyutlamak, oyununuzda bellek kullanımını artırabilir.
Hafifletme
Varlıkları yalnızca bir kez yükleyin - Aynı varlık kimliğini nesneler arasında yeniden kullanarak ve aynı varlıkları, özellikle doku ve resimleri, birden fazla kez ayrı olarak yüklemeyerek yeniden yükleme yapın.
Tekrar eden varlıkları bulun ve düzeltin - Birden fazla kez farklı kimlikler ile yüklenmiş, aynı mesh parçalarını ve dokuları arayın.
- Varlıkların benzerliğini otomatik olarak algılayacak bir API olmasa da, yerinizde tüm resim varlık kimliklerini toplamak (manüel veya bir betik aracılığıyla), bunları indirip harici karşılaştırma araçları ile karşılaştırmak mümkündür.
- Mesh parçaları için en iyi strateji, benzersiz mesh kimliklerini alıp boyutlarına göre düzenlemektir, böylece elle tekrar edenleri tanıyabilirsiniz.
- Farklı renkler için ayrı dokular kullanmak yerine, tek bir doku yükleyin ve SurfaceAppearance.Color özelliğini kullanarak çeşitli tonları uygulayın.
Varlıkları haritada ayrı olarak içe aktarın - Bütün haritanın bir seferde içe aktarılması yerine, haritadaki varlıkları ayrı ayrı yükleyin ve yeniden inşa edin. İçe aktarıcı mesh'lerin tekrar edilmesini yapmaz, bu nedenle büyük bir haritayı ayrı hizalama ile içe aktarırsanız, her bir döşeme bir ayrı varlık olarak içe aktarılır (daha fazlası), bu da zamanla performans ve bellek sorunlarına yol açabilir.
Resimlerin piksel sayısını gerekli olandan daha fazlasına düşürün. Bir resim ekranın büyük bir bölümünü kaplamıyorsa, genellikle en fazla 512x512 piksel kullanılır. Küçük resimlerin çoğu 256x256 pikselden daha küçük olmalıdır.
Trim levhaları kullanarak 3D haritalarda maksimum doku yeniden kullanımını sağlayın. Trim levhalarını oluşturma adım ve örnekleri için Trim levhaları oluştur başlığını inceleyin.
Ayrıca birçok daha küçük kullanıcı arayüzü resmini tek bir resim olarak yüklemek için sprite levhalarını yüklemeyi düşünebilirsiniz. Daha sonra ImageLabel.ImageRectOffset ve ImageLabel.ImageRectSize kullanarak levhanın kısımlarını görüntüleyebilirsiniz.
Yükleme süreleri
Birçok oyun özel yükleme ekranları uygular ve varlıkların görüntü, ses ve dokularının arka planda indirilebilmesi için ContentProvider:PreloadAsync() yöntemini kullanır.
Bu yaklaşımın avantajı, oyununuzun önemli kısımlarının pop-in olmadan tamamen yüklüdür. Ancak, bu yöntemi gerçekten gerekli olandan daha fazla varlık çoğaltmak için aşırı şekilde kullanmanın yaygın bir hatadır.
Kötü bir uygulama örneği, tüm Workspace'i yüklemektir. Bu, dokuların pop-in olmasını önlese de, yükleme sürelerini önemli ölçüde artırır.
Benzer bir uygulama ise, istenen tüm varlıkların yüklendiğinden emin olmak için ContentProvider.RequestQueueSize'ı kullanmaktır. Ancak, bu aynı şekilde belirgin yükleme sürelerini artıran geçerli bir yöntem olmadığı gibi, güvenilir bir yöntem değildir.
Bunun yerine, yalnızca Yükleme Ekranı ve oyundaki önemli resimler, buton arka planları ve simgeleri gibi önemli varlıklar için ContentProvider:PreloadAsync()'ı kullanın. Yüklemeniz gereken çok sayıda varlık varsa, bir Yükleme Atla düğmesi sağlamanızı öneririz.