Bu sayfa, yaygın performans sorunlarını ve bunlarla başa çıkma için en iyi uygulamaları açıklar.
Script Hesaplama
Luau kodundaki maliyetli işlemler daha uzun sürer ve bu da çerçeve hızını etkileyebilir. Parallelde çalışmadığı sürece, Luau kodu senkron olarak çalışır ve iş parçacığını engelleyerek işlevle karşılaştığında duraklatır.
Yaygın Sorunlar
Tablo yapıları üzerinde yoğun işlemler - Serileştirme, serileştirmeden çıkarma ve derin kopyalama gibi karmaşık işlemler, özellikle büyük tablo yapıları üzerinde yüksek performans maliyeti doğurur. Bu, özellikle bu işlemler geri çağırıyorsa veya çok büyük veri yapıları üzerinde yinelemeli olarak çalışıyorsa geçerlidir.
Yüksek frekanslı olaylar - Maliyetli işlemleri, sınıf tabanlı RunService olaylarına bağlamak, frekansı sınırlamazsanız her çerçevede bu işlemler tekrarlanır ve genellikle gereksiz bir hesaplama süresi artışına neden olur. Bu olaylar şunları içerir:
Düşürme
- Kodunuzu RunService olaylarında sınırlı bir şekilde çağırın; yüksek frekanslı çağırmanın gerekli olduğu durumlara, örneğin, kamerayı güncellemeye sınırlayın. Diğer kodları diğer olaylarda veya döngüde daha az sıklıkta çalıştırabilirsiniz.
- task.wait() kullanarak büyük veya maliyetli görevleri bölün, bu şekilde işleri birden fazla çerçeveye yayabilirsiniz.
- Gereksiz yere maliyetli işlemleri tanımlayın ve veri modeline erişme gerektirmeyen hesaplama açısından maliyetli görevlerde çok iş parçacıklı işleme kullanın.
- Belirli sunucu tarafı betikleri, bir betiği makine koduna derleyen ve bayt kodu yerine kullanılabilecek yerel kod oluşturma ile fayda sağlayabilir.
MikroProfil Sıralamaları
| Aralık | İlişkili hesaplama |
| RunService.PreRender | PreRender olayında çalışan kod |
| RunService.PreSimulation | Stepped olayında çalışan kod |
| RunService.PostSimulation | Heartbeat olayında çalışan kod |
| RunService.Heartbeat | Heartbeat olayında çalışan kod |
MikroProfil kullanarak betikleri hata ayıklama ile ilgili daha fazla bilgi için, belirli kodları etiketleme ve debug.profilebegin ve debug.profileend gibi ekspresyonda daha fazla ayrıntı sağlama işlevlerini içeren debug kütüphanesine bakın. Betikler tarafından çağrılan birçok Roblox API yöntemi de kendi MikroProfil etiketlerine sahiptir ve bu da faydalı sinyal verebilir.
Script Bellek Kullanımı
Bellek sızıntıları, çöp toplayıcının artık kullanılmadığında düzgün bir şekilde serbest bırakamadığı bellek tüketen betikler yazdığınızda ortaya çıkabilir. Sızıntılar, sunucuda sürekli çevrimiçi kalma potansiyeli olduğundan özellikle yaygındır, çünkü oyuncu oturumları çok daha kısadır.
Geliştirici Konsolundaki aşağıdaki bellek değerleri, daha fazla araştırma gerektiren bir sorunu gösterebilir:
- LuaHeap - Yüksek veya büyüyen tüketim, bir bellek sızıntısını gösterir.
- InstanceCount - Sürekli artan instance sayıları, kodunuzda bazı instance'lara olan referansların çöp toplayıcı tarafından serbest bırakılmadığını gösterir.
- PlaceScriptMemory - Bellek kullanımının betik bazında dökümünü sağlar.
Yaygın Sorunlar
Bağlantıları bağlı bırakma - Motor, bir instance'a bağlı olan olayları ve bağlı geri arama içindeki herhangi bir referansı asla bellekten serbest bırakmaz. Bu nedenle, bağlı instance'ların olaylarının ve içindeki kodların aktif bağlantıları, olaylar tetiklendikten sonra bile bellek çöp toplayıcısının kapsamının dışındadır.
Olaylar, ait oldukları instance yok olduğunda bağlantıyı keser, ancak Player nesneleri için bunun geçerli olduğunu varsaymak yaygın bir hatadır. Bir kullanıcı bir oyundan ayrıldığında, motor otomatik olarak temsilci Player nesnesini ve karakter modelini yok etmez, bu nedenle Player nesnesine ve karakter modeli altında CharacterAdded gibi instance'lara olan bağlantılar, betiklerinizde onları kopartmadığınız sürece bellek tüketmeye devam eder. Bu, sunucuda zamanla çok sayıda kullanıcı oyuna katılır ve ayrılırken çok önemli bellek sızıntılarına neden olabilir.
Tablolar - Tablolara nesne eklemek fakat bunlar artık gerekli değilken çıkarmamak gereksiz bellek tüketimine neden olur, özellikle de kullanıcı verilerini takip eden tablolarda. Örneğin, aşağıdaki örnek kod, bir kullanıcı katıldıkça kullanıcı bilgilerini ekleyen bir tablo oluşturur:
Örneklocal playerInfo = {}Players.PlayerAdded:Connect(function(player)playerInfo[player] = {} -- bazı bilgilerend)Eğer bu girişleri artık gerekli olmadıklarında kaldırmazsanız, tablo büyümeye devam eder ve daha fazla kullanıcı katıldıkça daha fazla bellek tüketir. Bu tabloyu yineleyen her kod da tablonun büyümesiyle daha hesaplama açısından maliyetli hale gelir.
Düşürme
Bellek sızıntılarını önlemek için tüm kullanılan değerleri temizlemek için:
Tüm bağlantıları kesin - Kod tabanınızı gözden geçirin ve her bağlantının aşağıdaki yollarla temizlendiğinden emin olun:
- Disconnect() işlevini kullanarak manuel olarak kesmek.
- Olayın ait olduğu instance'ı Destroy() işleviyle yok etmek.
- Bağlantının geri izlediği betik nesnesini yok etmek.
Ayrıldıklarında oyuncu nesnelerini ve karakterleri kaldırın - Kullanıcı bir oyundan ayrıldığında oyuncu nesnelerini ve karakter modellerini otomatik olarak yok etmek için Workspace.PlayerCharacterDestroyBehavior özelliğini etkinleştirin. İsterseniz, bunları manuel olarak da 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 Hesaplama
Aşırı fizik simülasyonu, hem sunucuda hem de istemcide her çerçevede artan hesaplama süresinin ana nedenlerinden biri olabilir.
Yaygın Sorunlar
Aşırı fizik zaman adımı frekansı - Varsayılan olarak, adım davranışı adaptif modda olup fizik her biri 60 Hz, 120 Hz veya 240 Hz olarak adım atmaktadır; bu, fizik mekanizmasının karmaşıklığına bağlıdır.
Daha iyi fizik doğruluğu sağlayan sabit bir mod da mevcuttur. Bu mod, tüm fizik montajlarının her çerçevede 240 Hz (her çerçevede dört kez) adım atmasını zorlar. Bu durum, her çerçevede önemli ölçüde daha fazla hesaplama gerektirir.
Simüle edilen nesnelerin aşırı sayıda ve karmaşıklığı - Simüle edilen daha fazla 3D montajı olduğu sürece, her çerçevede fizik hesaplamaları uzun sürer. Genellikle, oyunlar simüle edilmesi gerekmeyen nesneler taşırken veya gereksiz yere daha fazla kısıtlamaların ve eklemlerin olduğu mekanizmalar barındırır.
Aşırı hassas çarpışma tespiti - Meshe parçaları, çarpışmaları tespit etmek için CollisionFidelity özelliğine sahiptir ve bu çeşitli performans etkileri olan modları sunar. Meshe parçaları için hassas çarpışma tespiti modu en maliyetli performansa sahip olup motorun hesaplaması için daha uzun sürer.
Düşürme
Simülasyona ihtiyaç duymayan parçaları sabitleyerek - Fizik tarafından yönetilmesi gerekmeyen tüm parçaları sabitleyin, örneğin statik NPC'ler için.
Adaptif fizik adımı kullanın - Adaptif adım, fizik mekanizmalarının fizik hesaplamalarının hızını dinamik olarak ayarlayarak bazı durumlarda fizik güncellemelerinin daha az sıklıkta yapılmasına olanak tanır.
Mekanizma karmaşıklığını azaltın
- Mümkün olan yerlerde, bir montajda fizik kısıtlamalarının veya eklemlerinin sayısını minimize edin.
- Bir mekanizmadaki kendi çarpışmaların miktarını azaltın; bu, ragdoll uzuvlarının çarpışmalarını önlemek için sınırlamalar veya çarpışmasız kısıtlamaları uygulamakla mümkündür.
Meshler için hassas çarpışma fidelitesinin kullanımını azaltın
Kullanıcıların nadiren fark edeceği küçük veya etkileşimde bulunmayan nesneler için kutu fidelitesi kullanın.
Küçük-orta boy nesneler için, şekline bağlı olarak kutu veya gövde fidelitelerini 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ışmalara gerek olmayan nesneler için, çarpışmaları devre dışı bırakın ve kutu veya gövde fidelitesini kullanın; çünkü çarpışma geometrisi hala bellekte saklanır.
Studio'da hata ayıklama amaçları için çarpışma geometrisini, 3D görünümdeki üst sağ köşedeki Görselleştirme Seçenekleri widget'ından Çarpışma fidelitesini açarak render edebilirsiniz.
Alternatif olarak, Keşfedicinin CollisionFidelity=PreciseConvexDecomposition filtresini uygulayarak, hassas fideliteye sahip tüm mesh parçalarının sayısını gösterir ve kolayca seçmenizi sağlar.
Hassasiyet ve performans gereksinimlerinizi dengeleyen çarpışma fidelitesi seçme konusunda derinlemesine bilgi için Fizik ve render parametrelerini belirleme sayfasına göz atın.
MikroProfil Sıralamaları
| Aralık | İlişkili hesaplama |
| physicsStepped | Genel fizik hesaplaması |
| worldStep | Her çerçevede alınan ayrık fizik adımları |
Fizik Bellek Kullanımı
Fizik hareketleri ve çarpışma tespiti bellek tüketir. Meshe parçalarının çarpışma sınırlarını değerlendirmek için kullanılan CollisionFidelity özelliği vardır.
Yaygın Sorun
Varsayılan ve hassas çarpışma tespiti modları, daha düşük fidelite çarpışma şekillerine göre çok daha fazla bellek tüketir.
PhysicsParts altında yüksek bellek tüketimi görüyorsanız, oyundaki nesnelerin çarpışma fidelitesini azaltmayı düşünmeniz gerekebilir.
Azaltma Yöntemleri
Çarpışma fidelitesi için kullanılan belleği azaltmak için:
- Çarpışmalara ihtiyacı olmayan parçaların çarpışmalarını devre dışı bırakmak için BasePart.CanCollide, BasePart.CanTouch ve BasePart.CanQuery özelliklerini false olarak ayarlayın.
- Çarpışmaların fidelitesini CollisionFidelity ayarı kullanarak azaltın. Box en düşük bellek aşımına sahiptir; Default ve Precise genellikle daha pahalıdır.
- Her küçük sabit parça için çarpışma fidelitesini Box olarak ayarlamak genellikle güvenlidir.
- Çok karmaşık büyük meshler için, küçük nesnelerden oluşan kendi çarpışma ağınızı kutu çarpışma fidelitesi ile inşa etmek isteyebilirsiniz.
Humanoidler
Humanoid, oyuncu ve oyuncu olmayan karakterler (NPC'ler) için geniş bir işlevsellik yelpazesi sağlayan bir sınıftır. Güçlü olmakla birlikte, Humanoid önemli bir hesaplama maliyetine sahiptir.
Yaygın Sorunlar
- NPC'lerde tüm HumanoidStateTypes'ı açık bırakmak - Belirli HumanoidStateTypes'lerin açık kalmasının bir performans maliyeti vardır. NPC'leriniz için gerekli olmayanları devre dışı bırakın. Örneğin, NPC'niz merdiven çıkacaksa, Climbing durumunu devre dışı bırakmak güvenlidir.
- Sıklıkla Humanoids veya derili MeshParts ile model oluşturma, değiştirme ve yeniden oluşturma
- Bu, motorun işlemesi için yoğun hale gelebilir, özellikle bu modeller katmanlı giysi kullanıyorsa. Bu, sık sık yeniden doğulan avatarların olduğu oyunlarda özellikle sorun teşkil edebilir.
- MikroProfil'de, uzun updateInvalidatedFastClusters etiketleri (4 ms'den fazla) genellikle avatar oluşturma/değiştirme sırasında aşırı geçersiz kılmaların tetiklendiğinin işareti olabilir.
- Humanoidleri gereksiz durumlarda kullanmak - Genellikle hareket etmeyen statik NPC'lerin Humanoid sınıfına ihtiyacı yoktur.
- Sunucudan büyük sayıda NPC üzerinde animasyon oynatmak - Sunucuda çalışan NPC animasyonları, sunucuda simüle edilmeli ve istemciye yansıtılmalıdır. Bu, gereksiz yükün üstlenilmesine neden olabilir.
- Gereksiz boyut ve ölçek değişiklikleri yapmak - Boyut/ölçek değişiklikleri FastCluster'ın yeniden inşa edilmesine neden olur. Eğer FastCluster ile ilgili performans sorunları yaşıyorsanız, bunu oyun sırasında azaltmaya çalışın. Benzer şekilde, diğer özellik değişiklikleri de FastCluster'ın yeniden inşa edilmesine neden olabilir, bu nedenle bu değişiklikleri mümkün olduğunca azaltın.
Düşürme
- NPC animasyonlarını istemcide oynayın - Birçok NPC'ye sahip oyunlarda, Animator'ı istemcide oluşturmayı ve animasyonları yerel olarak çalıştırmayı düşünün. Bu, sunucunun yükünü azaltır ve gereksiz çoğaltma ihtiyacını azaltır. Ayrıca, animasyonları yalnızca karaktere yakın NPC'ler için oynatma gibi ek optimizasyonlar yapmanıza olanak tanır.
- Humanoidler için performans dostu alternatifler kullanın - NPC modellerinin mutlaka bir humanoid nesnesi bulundurması gerekmez.
- Statik NPC'ler için, hareket etmemeleri ama animasyonları oynamaları gerektiği için basit bir AnimationController kullanın.
- Hareket eden NPC'ler için, NPC'lerin karmaşıklığına bağlı olarak kendi hareket denetleyicinizi uygulamayı ve animasyonlar için AnimationController kullanmayı düşünün.
- Gereksiz humanoid durumlarını devre dışı bırakın - Her humanoid için yalnızca gerekli durumları etkinleştirmek için Humanoid:SetStateEnabled() kullanın.
- Sık yeniden doğan NPC modellerini havuzlama - Bir NPC'yi tamamen yok etmek yerine, NPC'yi devre dışı NPC havuzuna gönderin. Bu şekilde, yeniden doğması gereken yeni bir NPC gerektiğinde, havuzdan bir NPC'yi yeniden etkinleştirebilirsiniz. Bu süreç havuzlama olarak adlandırılır ve karakterlerin oluşturulma sürelerini azaltır.
- NPC'leri yalnızca kullanıcılar yakın olduğunda oluşturun - Kullanıcılar menzil dışında olduğunda NPC'leri oluşturmayın ve kullanıcılar menzil dışına çıktığında onları öldürün.
- Bir avatar oluşturulduktan sonra avatar hiyerarşisini değiştirin - Avatar hiyerarşisini oluşturduktan sonra yürütülen bazı değişikliklerin önemli performans sonuçları vardır. 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.
MikroProfil Sıralamaları
| Aralık | İlişkili hesaplama |
| stepHumanoid | Humanoid kontrol ve fizik |
| stepAnimation | Humanoid ve animatör animasyonu |
| updateInvalidatedFastClusters | Bir avatarı oluşturma veya değiştirme ile ilişkili |
Rendering
İstemcinin her çerçevede harcadığı zamanın önemli bir kısmı mevcut çerçevede sahneyi render etmek içindir. Sunucu, herhangi bir render işlemi yapmaz; bu nedenle bu bölüm yalnızca istemci içindir.
Çizim Çağrıları
Bir çizim çağrısı, motorun GPU'ya bir şeyi render etmesi için verdiği talimatlardan oluşan bir settir. Çizim çağrıları önemli bir yük oluşturur. Genellikle, her çerçevede daha az çizim çağrısı olması, bir çerçeveyi render etmek için harcanan zamanın daha az olması anlamına gelir.
Studio'da Render İstatistikleri ⟩ Zamanlama kısmında şu anda kaç çizim çağrısının gerçekleştiğini görebilirsiniz. İstemcide Render İstatistiklerini görüntülemek için ShiftF2 tuşlarına basabilirsiniz.
Sahnenizde bir çerçevede çizim gerektiren daha fazla nesne varsa, GPU'ya yapılan çizim çağrısı sayısı artar. Ancak, Roblox Motoru, aynı doku özelliklerine sahip özdeş meshleri tek bir çizim çağrısında birleştirmek için örnekleme adı verilen bir süreç kullanır. Özellikle, aynı MeshContent'e sahip birden fazla mesh, aşağıdaki koşullar altında tek bir çizim çağrısında işlenir:
- Varsa SurfaceAppearances'lar aynı, aksi durumda TextureContents'lar aynıdır.
- Her iki SurfaceAppearance ve MeshPart.TextureID mevcut olmadığında malzemeler aynıdır.
Diğer Yaygın Sorunlar
Aşırı nesne yoğunluğu - Eğer yüksek yoğunlukta çok sayıda nesne toplanmışsa, sahnenin bu alanının render edilmesi daha fazla çizim çağrısı gerektirir. Belirli bir harita parçasına bakarken çerçeve hızının düştüğünü buluyorsanız, bu alanın nesne yoğunluğunun fazla olduğu iyi bir işarettir.
Dekorasyonlar, dokular ve parçacıklar gibi nesneler iyi bir şekilde gruplandırılmaz ve ek çizim çağrıları getirebilir. Sahnedeki bu nesne türlerine özellikle dikkat edin. Özellikle ParticleEmitters'a ait özellik değişiklikleri performans üzerinde dramatik bir etki yapabilir.
Örnekleme fırsatlarının kaçırılması - Genellikle, bir sahne aynı mesh modelinin bir çok kez kopyasını içerir; ancak, her bir kopya farklı mesh veya doku varlık kimliklerine sahiptir. Bu durum, örnekleme olanağını engeller ve gereksiz çizim çağrılarına yol açabilir.
Bu sorunun yaygın nedeni, bir sahnenin bir kerede tümüyle içeri aktarılmasıdır; bunun yerine, belirli varlıkların Roblox'a içe aktarılıp ardından içe aktarım sonrası çoğaltılmasıdır.
Aşağıdaki gibi basit bir betik, farklı mesh kimliklerini kullanan aynı adı taşıyan mesh parçalarını tanımlamanıza yardımcı olabilir:
for _,descendant in workspace:GetDescendants() doif descendant:IsA("MeshPart") thenprint(descendant.Name .. ", " .. descendant.MeshId)endendÇıktı ( Yığılmış Satırlar etkinleştirildiğinde) aşağıdakine benzeyebilir. Tekrar eden satırlar aynı mesh'in yeniden kullanıldığını gösterir ki bu iyidir. Eşsiz satırlar mutlaka kötü değildir, ancak adlandırma şemanıza bağlı olarak, oyununuzda çift meshlerin var olduğunu gösterebilir.
LargeRock, rbxassetid://106420009602747 (x144) -- iyiLargeRock, rbxassetid://120109824668127LargeRock, rbxassetid://134460273008628LargeRock, rbxassetid://139288987285823LargeRock, rbxassetid://71302144984955LargeRock, rbxassetid://90621205713698LargeRock, rbxassetid://113160939160788LargeRock, rbxassetid://135944592365226 -- olası tüm kopyalarAşırı nesne karmaşıklığı - Çizim çağrısı sayısından daha az önemli olsa da, bir sahnedeki üçgenlerin sayısı, bir çerçevenin ne kadar sürede render edildiğini etkiler. Çok sayıda ve çok karmaşık mesh barındıran sahneler yaygın bir sorundur; aynı zamanda MeshPart.RenderFidelity özelliğinin birçok mesh üzerinde Precise olarak ayarlanması durumunda sorun teşkil edebilir.
Aşırı gölge oluşturma - Gölge ile ilgilenmek maliyetli bir süreçtir ve gölge yayan yüksek sayıda ve yoğunlukta ışık nesnelerine sahip haritalar (veya gölgelerden etkilenen yüksek sayıda ve yoğunlukta küçük parçalar), performans sorunları yaşayabilir.
Yüksek şeffaflık aşırı yüklemesi - Kısmi şeffaflığa sahip nesneleri birbirine yakın yerleştirmek, motorun üst üste binen pikselleri birden fazla kez render etmesine zorlayarak performansı etkileyebilir. Bu sorunu tanımlamak ve düzeltmek hakkında daha fazla bilgi için Katmanlı şeffaflıkları sil bölümüne bakın.
Gereksiz derili MeshPart hareketi - Humanoid olan bir Modelin parçası olan derili MeshPart'lar, mekansal olarak düzenlenen FastClusters kullanılarak gruplandırılır. Bu MeshPart'lar hareket ettiğinde, bu mekansal kümelere sürekli olarak eklenip çıkarılırlar; bu da kümelerin yeniden inşa edilmesine neden olur ve performansı etkiler.
- Son derece etkili bir çözüm, Model içinde bir Humanoid yerleştirmektir. Bir Humanoid'in varlığı, varsayılan mekansal grup davranışını geçersiz kılacak ve tüm Model için tek bir birleşik FastCluster kullanma zorunluluğunu getirir. Bu şekilde, konum güncellemeleri artık grup yeniden inşasını gerektirmeyecek ve bu nedenle performans darboğazı hafiflemiş olacaktır. Bu teknik, beklenen hareketi olan MeshPartlar için özel olarak ayrılmıştır; çünkü bu, bellek aşımına yol açabilecek ve mekansal optimizasyonun avantajlarını ortadan kaldırabilecektir. Bu tür değişiklikler yaptıktan sonra her zaman oyununuzu profillemenizi öneriyoruz. Daha fazla bilgi için Humanoid performans ipuçları sayfasına göz atın.
Model içinde çok fazla parça - Bir Modelde çok fazla parça, bir parçanın özelliklerinin değişmesi durumunda yeniden inşa edilmesi gereği nedeniyle daha sık yeniden inşalara neden olabilir. FastCluster kullanırken bir Modelde parçaların sayısını doğru bir şekilde ayarlayın.
Düşürme
Özdeş meshlerin örneklenmesi ve benzersiz mesh miktarının azaltılması - Tüm özdeş meshlerin aynı alt varlık kimliklerine sahip olmalarını sağlarsanız, motor bunları tek bir çizim çağrısında tanıyıp render edebilir. Her mesh'i bir haritada yalnızca bir kez yüklemeye ve sonra Studio'da yeniden kullanmak için çoğaltmaya dikkat edin; büyük haritalar olarak içe aktarmak, özdeş meshlerin ayrı içerik kimliklerine sahip olmasına neden olabilir ve motor tarafından benzersiz varlıklar olarak tanınabilir. Paketler, nesne yeniden kullanımı için yararlı bir mekanizmadır.
Kesim (Culling) - Kesim, son render edilen çerçeveye etki etmeyen nesneler için çizim çağrılarını ortadan kaldırma sürecini tanımlar. Varsayılan olarak, motor, kameranın görünüm alanının (frustum kesimi) dışında kalan nesneler için çizim çağrılarını atlar ve diğer nesneler tarafından görünümden gizlenmiş parçalar, meshler ve arazi (gizleme kesimi) için düşürür. Belirli senaryolar, örneğin kapalı ortamlar, bir oda veya portal sistemi uygulamanıza ve çizim çağrılarını veya genel hesaplama yükünü daha da azaltmak için nesneleri manuel olarak düşürmenize olanak tanıyabilir.
Modeller için detay seviyesini azaltma - Instance akışı özelliğini etkinleştirin ve dünya modellerinizin LevelOfDetail özelliğini, kameradan uzaklaştıkça optimize edilmiş hafif SLIM mesh'leri render etmek için SLIM olarak ayarlayın.
Avatarlara detay seviyesini azaltma - Instance akışını etkinleştirin ve Workspace.EnableSLIMAvatars ayarını, kameradan uzaklaştıkça optimize edilmiş hafif SLIM temsilleri ile tam animasyon desteğiyle render etmek için ayarlayın.
Render fidelitesini azaltma - MeshPart.RenderFidelity'yi Automatic veya Performance olarak ayarlayın. Bu, meshlerin daha az karmaşık alternatiflere düşmesine olanak tanır ve ç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 düştüğünde gölge kalitesini otomatik olarak azaltır ve 4'ün altında kalitede gölgeleri tamamen devre dışı bırakır. Ancak, ışık nesnelerinde ve parçalarda gölge oluşturma özelliklerini seçici olarak devre dışı bırakabilirsiniz böylece gölgeler etkin olduğunda performansı artırılır ve gölgelerin açık kalma olasılığı artırılır. İşte editör zamanında veya dinamik olarak çalışma sırasında yapabileceğiniz bazı optimizasyon örnekleri:
Küçük parçalarda gölgelerin görünmemesi muhtemel olduğu durumlarda BasePart.CastShadow özelliğini kullanarak gölge oluşturmaktan vazgeçin. Bu strateji, kullanıcıların kameralarına uzak olan parçalara uygulandığında özellikle etkilidir.
Hareket eden nesnelerde mümkünse gölgeleri devre dışı bırakın.
Nesnelerin gölge oluşturmaları gerekmiyorsa, ışık instance'larında Light.Shadows özelliğini devre dışı bırakın.
Işık instance'larının menzilini ve açısını sınırlayın.
Daha az ışık instance'ı kullanın.
Kapalı ortamlar için, belirli bir menzil dışındaki ışıkları devre dışı bırakmayı düşünün veya durumdan duruma.
MikroProfil Sıralamaları
| Aralık | İlişkili hesaplama |
| Prepare and Perform | Genel renderleme |
| Perform/Scene/computeLightingPerform | Işık ızgarası ve gölge güncellemeleri |
| LightGridCPU | Voksellik ışık ızgarası güncellemeleri |
| ShadowMapSystem | Gölge haritalama |
| Perform/Scene/UpdateView | Renderleme hazırlıkları ve parçacık güncellemeleri |
| Perform/Scene/RenderView | Renderleme ve sonrası işlemler |
Ağ oluşturma ve çoğaltma
Ağ oluşturma ve çoğaltma, verilerin sunucu ile bağlı istemciler arasında nasıl gönderildiğini tanımlar. Bilgiler, her çerçevede istemci ile sunucu arasında gönderilir, ancak daha büyük miktarlarda bilgi daha fazla işlem süresi gerektirir.
Yaygın Sorunlar
Aşırı uzak trafik - RemoteEvent veya RemoteFunction nesneleri aracılığıyla çok fazla veri göndermek veya bunları çok sık kullanmak, her çerçevede gelen paketleri işlemek için büyük miktarda CPU zamanının harcanmasına neden olabilir. Yaygın hatalar şunları içerir:
- Her çerçevede kopyalanması gerekmeyen verileri kopyalamak.
- Her kullanıcı girişi üzerinde bir sınır mekanizması olmadan veri kopyalamak.
- Gerekenden fazla veri taşımak. Örneğin, bir nesne satın alındığında oyuncunun tüm envanterini göndermek yerine sadece satın alınan nesnenin ayrıntılarını göndermek.
Karmaşık instance ağaçlarının oluşturulması veya kaldırılması - Sunucuda veri modelinde bir değişiklik yapıldığında, bağlı istemcilere çoğaltılır. Bu, büyük instance hiyerarşilerinin, örneğin haritaların, çalışma zamanında oluşturulması ve yok edilmesinin ağ üzerinde çok yoğun olabileceği anlamına gelir.
Yaygın bir suçlu, Animasyon Editörü eklentileri aracılığıyla riglerde saklanan karmaşık animasyon verisidir. Bunlar oyun yayımlanmadan önce kaldırılmazsa ve animasyonlu modellere sıkça kopyalanırsa, gereksiz yere büyük miktarda veri çoğaltılacaktır.
Sunucu tarafı TweenService - Eğer TweenService, sunucu tarafında bir nesneye tween uygulamak için kullanılıyorsa, tween edilen özellik her çerçevede her istemciye çoğaltılır. Bu, istemcilerin gecikmesi dalgalandığında tweenin sarsıntılı hale gelmesine neden olur ve gereksiz ağ trafiği doğurur.
Düşürme
Gereksiz çoğaltmayı azaltmak için aşağıdaki taktikleri kullanabilirsiniz:
- Uzak olaylar aracılığıyla aynı anda büyük miktarda veri göndermekten kaçının. Bunun yerine, yalnızca gerekli olan verileri daha düşük bir sıklıkta gönderin. Örneğin, bir karakterin durumunu, her çerçevede değil de değiştiğinde çoğaltın.
- Karmaşık instance ağaçlarını parçalara bölün; haritalar gibi haritaları parçalar halinde yükleyin, bu sayede çoğaltma işini birden fazla çerçeveye yayabilirsiniz.
- Animasyon meta verilerini temizleyin, özellikle riglerin animasyon dizinini içe aktarıldıktan sonra.
- Gereksiz instance çoğaltımını sınırlayın, özellikle sunucunun oluşturulan instance'lar hakkında bilgi sahibi olmasının gerekmediği durumlarda. Bu, şunları içerir:
- Patlama veya büyü patlaması gibi görsel efektler. Sunucu sadece sonucu belirlemek için konuma ihtiyaç duyarken, istemciler görselleri yerelde yaratabilir.
- İlk kişinin nesne görüntü modelleri.
- Nesneleri istemcide tweenlemek yerine sunucudan.
MikroProfil Sıralamaları
| Aralık | İlişkili hesaplama |
| ProcessPackets | Olay çağrıları ve özellik değişiklikleri gibi gelen ağ paketlerinin işlenmesi |
| Allocate Bandwidth and Run Senders | Sunucularda ilgili çıkış olayları |
Varlık Bellek Kullanımı
Yaratıcıların istemci bellek kullanımını iyileştirmek için kullanabilecekleri en yüksek etkiye sahip mekanizma, instance akışını etkinleştirmektir.
Instance Akışı
Instance akışı, gerekli olmayan veri modelinin parçalarını seçici olarak yükleyerek, yükleme sürelerini önemli ölçüde azaltabilir ve istemcinin bellek baskısıyla başa çıkabilme yeteneğini artırabilir.
Bellek sorunlarıyla karşılaşıyorsanız ve instance akışınız devre dışıysa, oyununuzu desteklemesi için güncellemeyi düşünün, özellikle 3D dünyanız büyükse. Instance akışı 3D alandaki mesafeye dayanır, bu nedenle daha büyük dünyalar doğal olarak bundan daha fazla fayda sağlar.
Eğer instance akışı etkinleştirildiyse, bunu daha agresif hale getirebilirsiniz. Örneğin, gözden geçirmenizi gerektirebilir:
- Mümkün olduğunca Enum.ModelStreamingMode.Persistent kullanımını azaltın. Uyumluluk önlemi olarak bunu kullanıyorsanız betiklerinizi güncellemeniz gerekebilir.
- Workspace.StreamingMinRadius ve Workspace.StreamingTargetRadius değerlerini azaltın.
Akış seçenekleri ve faydaları hakkında daha fazla bilgi için akış özellikleri bölümüne bakın.
Diğer Yaygın Sorunlar
Varlık çoğaltma - Yaygın bir hata, aynı varlığı birden fazla kez yükleyerek farklı varlık kimlikleri elde etmektir. Bu, aynı içeriğin belleğe birden fazla kez yüklenmesine yol açabilir.
Aşırı varlık hacmi - Varlıklar benzer olmasa bile, aynı varlığın yeniden kullanılması ve bellek tasarrufu sağlama fırsatlarının kaçırıldığı durumlar vardır.
Ses dosyaları - Ses dosyaları, özellikle hepsini bir anda istemcide yüklemek yerine oyunun belirli bir kısmı için yalnızca gerekenleri yüklüyorsanız, hafıza kullanımınıza sürpriz bir katkı sağlayabilir. Stratejiler için, Yükleme süreleri bölümüne göz atın.
Yüksek çözünürlüklü dokular - Bir dokunun grafik bellek tüketimi, diskteki boyutuna bağlı değildir; dokudaki piksel sayısı bellek kullanımını belirler. Örneğin, 1024x1024 piksel dokusu, 512x512 dokusunun grafik belleğinin dört katını tüketir.
Roblox'a yüklenen görüntüler, belirli bir formatta yeniden kodlandığı için, piksel başına daha az byte bir renk modelinde görüntü yüklemenin bellek yararı yoktur. Benzer şekilde, yükleme öncesinde görüntüleri sıkıştırmak veya ihtiyaç duymayan görüntülerden alfa kanalını kaldırmak, diskteki görüntü boyutunu azaltabilir, ancak bellek kullanımını iyileştirmez.
Oyun yüklenirken, motor otomatik olarak düşük kaliteli dokularla başlar ve daha sonra mevcut cihaz belleğine, kameradan uzaklığa, dokunun kapladığı ekran alanına ve diğer faktörlere göre kaliteyi artırır. Yine de, dokularınızı stratejik olarak boyutlandırmak, oyununuzdaki bellek kullanımını artırabilir.
Düşürme
Varlıkları yalnızca bir kez yükleyin - Nesneler arasında aynı varlık kimliğini yeniden kullanın ve aynı varlıkların, özellikle meshlerin ve görüntülerin birden fazla kez ayrı olarak yüklenmediğinden emin olun.
Çift varlıkları bulun ve düzeltin - İki kez farklı kimliklerle yüklenen özdeş mesh parçaları ve dokularını arayın.
- Benzer varlıkları otomatik olarak algılamak için API yoktur; bu nedenle, yerinizdeki tüm görüntü varlık kimliklerini (ister manuel olarak ister bir betikle) toplamak, bunları indirmek ve harici karşılaştırma araçlarıyla karşılaştırmak size yardımcı olabilir.
- Mesh parçaları için en iyi strateji, benzersiz mesh kimliklerini alıp boyutlarına göre düzenlemektir; bu sayede çiftleri manuel olarak tanımlayabilirsiniz.
- Farklı renkler için ayrı dokular kullanmak yerine, tek bir doku yükleyin ve SurfaceAppearance.Color özelliğini kullanarak ona çeşitli tonlar uygulayın.
Harita varlıklarını ayrı olarak içe aktarın - Bütün bir haritayı bir kerede içe aktarmak yerine, haritadaki varlıkları ayrı ayrı içe aktarın ve yeniden inşa edin. İçe aktarıcı, meshlerin yeniden çoğaltılmasını sağlamaz, bu yüzden bir haritayı büyük bir büyüklükte ayrı zemin karolarıyla içe aktarırsanız, her bir parça ayrı bir varlık olarak içe aktarılacaktır (aynı olmalarına rağmen). Bu, zamanla performans ve bellek sorunlarına yol açabilir; her mesh, ayrı ayrı değerlendirilir ve bellek ve çizim çağrıları alır.
Görüntülerin piksel sayısını gereksinimlerden daha fazla sınırlandırın. Bir görüntü ekranın büyük bir alanını kaplamıyorsa, genelde 512x512 pikselden daha fazla olması gerekmez. Çoğu küçük görüntü için 256x256 pikselin altında olmalıdır.
Trim sheet'leri kullanın 3D haritalarda maksimum doku yeniden kullanımını sağlamak için. Trim sheet'leri oluşturma adımları ve örnekleri için, Trim sheet'leri oluşturun bölümüne göz atın.
Ayrıca, birçok küçük UI görüntüsünü tek bir görüntü olarak yüklemek için sprite sheet'leri kullanmayı düşünebilirsiniz. Ardından, ImageLabel.ImageRectOffset ve ImageLabel.ImageRectSize'yi kullanarak sheet'in kısımlarını görüntüleyebilirsiniz.
Yükleme Süreleri
Birçok oyun, özel yükleme ekranları uygular ve varlıkları arka planda indirilmeleri için ContentProvider:PreloadAsync() yöntemini kullanır.
Bu yaklaşımın avantajı, oyununuzun önemli kısımlarının tam olarak yüklenmesini sağlamaktır; bu sayede pürüzsüz çalışır. Ancak, ortak bir hata, gerçekten gerekli olanlardan daha fazla varlığı ön yüklemek için bu yöntemin aşırı şekilde kullanılmasını içerir.
Kötü bir uygulama örneği, tüm Workspace'ı yüklemektir. Bu, dokuların belirmesini önleyebilir, ancak yükleme sürelerini önemli ölçüde artırır.
Benzer bir uygulama, tüm talep edilen varlıkların yüklenmesinin tamamlandığından emin olmak için ContentProvider.RequestQueueSize'yi kullanmaktır. Ancak bu, aynı yükleme sürelerini önemli ölçüde artırma sorununu ortaya çıkarır ve dalgalanan doğası nedeniyle güvenilir bir yöntem değildir.
Bunun yerine, yalnızca ContentProvider:PreloadAsync() yöntemini gereken durumlarda kullanın; bunlar şunları içerir:
- Yükleme ekranındaki görüntüler.
- Oyun menünüzde, buton arka planları ve simgeleri gibi önemli görüntüler.
- Başlangıç veya doğma alanındaki önemli varlıklar.
Eğer büyük bir varlık grubunu yüklemeniz gerekiyorsa, bir Yüklemeyi Atla butonu sağlamanızı öneririz.