Bu kılavuz, oyunda örnek akışı verimli ve etkili bir şekilde kullanmak için birkaç teknik özetlemektedir. Akış oyunları tasarlamak için "tek tip çözüm" yoktur, ancak bu yüksek seviyeli adımları takip etmek sizi büyük ölçüde hedefinize ulaştıracaktır.
Akış özellikleri
StreamingEnabled Studio'daki Workspace nesnesi için açıldığında, ilgili özelliklerini aşağıdaki önerilen değerlere ayarlayın:
| Özellik | Öneri |
|---|---|
| EnableSLIMAvatars | Uygun olduğunda R15 avatarlarını hafif, animasyonlu temsilciler olarak renderlamak için Enabled kullanın. Daha fazla bilgi için SLIM avatarlarına bakın. |
| ModelStreamingBehavior | BasePart alt nesneleri olan Models için en verimli akışı sağlamak üzere Improved kullanın. |
| StreamingIntegrityMode | Gereksiz veya çok sık duraklatmadan oyun oynama bütünlüğünü dengelemek için PauseOutsideLoadedArea kullanın. |
| StreamingMinRadius | Düşük seviye cihazlar için oyunun ne kadar küçültülebileceğini maksimize etmek üzere varsayılan 64 değerini kullanın. |
| StreamingTargetRadius | Yüksek seviye cihazlardaki oyuncular için görünürlük ile makul bir bellek ayak izi arasında iyi bir denge sağlamak için varsayılan 1024 değerini kullanın. |
| StreamOutBehavior | İstemcinin içeriği agresif bir şekilde çöp toplamasına izin vermek için Opportunistic kullanın, bu da bellek kullanımını önemli ölçüde azaltır ve bellek yetersizliği nedeniyle çökme olasılığını azaltır. |
Model detay seviyesi
Model.LevelOfDetail, akışta olmayan Model içeriğini hafif kompozit veya sahte ağlarla doldurmaya yardımcı olur ve dünyayı görsel olarak tamamlanmış hale getirir. SLIM (Ölçeklenebilir Hafif Etkileşimli Modeller) özellikle etkilidir, çünkü oyuncular genellikle bir SLIM ağını tam olarak akışa alınmış orijinalinden ayırt edemezler.
En iyi sonuçlar için:
- Mekansal ve mantıksal olarak ilişkili parçaları gruplandırın, örneğin bir arabanın tüm parçaları.
- Statik ağlar ve parçalar içeren modellerde LevelOfDetail değerini SLIM olarak ayarlayın. Çalışma zamanında değiştirilen veya animasyon oynatılan modeller desteklenmez.
- Her modelin mekansal boyutunu ~64 kübik studun altında tutun, böylece tüm gerçek modelin birlikte akışa alınma olasılığını artırın. Bir modelin çok büyük boyutları varsa, onu daha küçük modüler modellere ayırın ve her birine uygun bir LevelOfDetail uygulayın.
Model yapısı
Model detay seviyesini ayarlamanın ötesinde, Models yapısı ve ayarları akışın ne kadar iyi performans gösterdiği üzerinde önemli bir etkiye sahiptir. Mevcut bir oyunu geliştirirken veya dönüştürürken:
Mantıksal gruplama için atomik modeller kullanın — Bir betik, bir model içindeki tüm parçalara erişim gerektiriyorsa, ModelStreamingMode değerini Atomic olarak ayarlayın. Bu, istemci tarafı betiklerinin modelin içindeki örneklere aşırı WaitForChild() kullanmadan güvenli bir şekilde erişmesine olanak tanır (ancak bu tür betikler yine de genel atomik model için WaitForChild() kullanmalıdır).
Kalıcı modelleri en aza indirin — Kalıcı modeller, katılım sonrası yüklenir ve asla akıştan çıkmaz, kalıcı olarak bellek kaplar. Bir modelin ModelStreamingMode değerini yalnızca her zaman mevcut ve betiklere erişilebilir olması gerekirse Persistent olarak ayarlayın.
Kapsayıcı modelleri parçalayın — Yaygın bir akış dışı modelleme deseni, birçok NPC, nesne veya benzeri grupları içeren tek bir büyük Modeldır. Akış altında, kapsayıcı modeller akış verimliliğini azaltır ve model detay seviyesi için optimal değildir; bu, yakın gruplandırılmış örneklerle en iyi şekilde çalışır. Kapsayıcı modelleri, fiziksel olarak yakın veya mantıksal olarak ilişkili parçalara sahip daha küçük modellere ayırın.
SLIM avatarları
Akışta olmayan alanın dışındaki platform avatarları varsayılan olarak görünmez, ancak Workspace.EnableSLIMAvatars etkinleştirildiğinde, uygun olduğunda R15 avatarları hafif, animasyonlu temsilciler olarak renderlanır. Etkili bir şekilde, motor:
- Gerçek bir avatar modeli akıştan çıktığında bir SLIM versiyonu renderlar.
- Mevcut kaynaklara bağlı olarak SLIM ve tam çözünürlüklü temsiller arasında geçiş yapar, hatta akış yarıçapı içinde bile.
- Sahne önemine ve mevcut bant genişliğine bağlı olarak SLIM animasyonlarını kısıtlar.
SLIM avatarları, bir gövde, dinamik bir kafa, standart veya gelişmiş R15 iskeleti ve katı/katmanlı aksesuarlarla R15 oyuncu karakterlerini destekler. R6 avatarları, NPC'ler ve özel oranlara sahip avatarlar hariçtir. Desteklenen ve hariç tutulan avatar yapılandırmalarının tam listesi, performans verileri ve sorun giderme ipuçları için SLIM avatarlarına bakın.
Betik desenleri
Aşağıdaki betik desenleri en çok akıştan etkilenir. Doğru strateji, kodun amacına bağlıdır, bu nedenle her desen uygun olduğunda birden fazla seçenek listeler.
Alt nesnelere doğrudan indeksleme
Workspace alt nesnelerine . operatörü ile indeksleme, yol üzerindeki herhangi bir örnek akışta değilse bir hata fırlatır. FindFirstChild(), FindFirstChildWhichIsA() ve FindFirstChildOfClass() için de aynı durum geçerlidir; eğer çocuk akışta değilse nil döner.
local house1 = workspace:FindFirstChild("House1") -- "House1" akışta değilse nil
local door = workspace.House1.Door -- "House1" veya "Door" akışta değilse bozulurBenzer bir desen, Player.CharacterAdded bağlantısı içinde Humanoid veya diğer karakter alt nesnelerine doğrudan erişmektir. Akış altında, karakter modeli Workspace'a tüm alt nesneleri çoğaltılmadan önce yerleştirilir, bu nedenle doğrudan indeksleme başarısız olur.
local Players = game:GetService("Players")
local player = Players.LocalPlayer
player.CharacterAdded:Connect(function(character)
local humanoid = character.Humanoid
end)Eğer betik bir örneksiz ilerleyemezse, WaitForChild() ile bekleyin:
local house1 = workspace:WaitForChild("House1")
local door = house1:WaitForChild("Door")Uzakta gönderilen örnekler
Bir RemoteEvent/RemoteFunction sinyali ve referans verdiği örnek bağımsız olarak hareket eder, bu nedenle sinyal, istemcide örnek mevcut olmadan önce ulaşabilir veya örnek hiç mevcut olmayabilir. İki olası neden şunlardır:
Akış altında, bir parça/modelin sunucuda oluşturulması ile istemcilere çoğaltılması arasında hafif bir gecikme olabilir. Etkili bir şekilde, bir RemoteEvent/RemoteFunction ile referans verilen bir parça, akışta olsa bile henüz mevcut olmayabilir.
Sunucudan istemciye bir parça/model referansı göndermek, örneğin alıcı istemciye çoğaltılmış olmasını gerektirir. Bir örnek yolunu bir dize olarak göndermek de aynı sorunu taşır, çünkü yol istemcide mevcut olmayan bir konuma çözülüyor olabilir:
İstemci Betiğilocal ReplicatedStorage = game:GetService("ReplicatedStorage")local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")remoteEvent.OnClientEvent:Connect(function(data)local checkpoint = data.checkpoint -- "checkpoint" akışta değilse hata verirlocal level = workspace.Levels[data.levelPath] -- Yol akışta değilse hata verirend)
Eğer alıcı istemci betiği ilerlemek için örneğe ihtiyaç duyuyorsa, kullanmadan önce WaitForChild() ekleyin. Bu, örnek asla akışa alınmazsa sonsuz bir süre bekleyebilir, bu nedenle WaitForChild()'in ikinci parametresi olarak bir zaman aşımı eklemeyi düşünün.
İstemci senkronizasyonu
İstemci tarafı senkronizasyonu bir istisna olarak ele alınmalıdır, standart bir tasarım deseni olarak değil. Sadece istemciye özel kopyalar veya yerel olarak örnekleri yeniden ebeveynlemek ciddi sorunlar yaratabilir. Kodunuzu, bu tür değişikliklerin istemcide kalıcı olmasına dayanan yerler için denetleyin.
Örneğin, bir örneği yerel olarak ReplicatedStorage'dan Workspace'a yeniden ebeveynlemek, o örneği akıştan çıkmaya uygun hale getirebilir. Benzer şekilde, bir örneği yerel olarak (Instance:Clone()) ReplicatedStorage'dan Workspace'a kopyalamak, sunucu çoğaltma hattının bir parçası olmayan istemciye özel bir kopya oluşturur ve orijinal sunucuya ait örnekten güncelleme almaz.
Aynı kavram, sunucuya ait bir nesne için istemcide Instance:Destroy() çağrıldığında da geçerlidir. Bu, örneği yerel olarak kaldırır, ancak sunucuda hala mevcut olduğundan, uygun olduğunda orijinal durumu ile tekrar akışa alınacaktır.
Proaktif akış
Bir oyuncunun bir sonraki varış noktasının tahmin edilebildiği durumlarda, geçici yükleme için alanları akışa almak üzere sunucu tarafında Player:RequestStreamAroundAsync() çağrıları yapın veya açıkça serbest bırakılana kadar yüklenmesi gereken alanlar için Player:AddReplicationFocus() kullanın.
Örneğin, bir oyuncu karakteri uzak bir konumdaki başka bir oyuncunun evine CFrame değişikliği ile teleport olmaya hazırlanıyorsa, pop-in'i en aza indirmek ve daha pürüzsüz bir geçiş sağlamak için varış alanını önceden yükleyebilirsiniz. Aşağıdaki betik, bir istemciden sunucuya uzaktan olay ateşleyerek bir oyuncu karakterini taşımak için bir ön yükleme yöntemi kullanır. Eğer ön yükleme isteği başarılı olursa, işlev döndüğünde hedef konum etrafındaki minimum yarıçap istemcide mevcut olmalıdır.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local teleportEvent = ReplicatedStorage:WaitForChild("TeleportEvent")
local function teleportPlayer(player, teleportTarget)
-- Hedef konum etrafında akış talep et
player:RequestStreamAroundAsync(teleportTarget)
-- Karakteri teleport et
local character = player.Character
if character and character.Parent then
local currentPivot = character:GetPivot()
character:PivotTo(currentPivot * CFrame.new(teleportTarget))
end
end
-- İstemci uzaktan olayı ateşlediğinde teleport işlevini çağır
teleportEvent.OnServerEvent:Connect(teleportPlayer)Örnek özellik okumaları
Bir örnek akıştan çıktığında, özellik güncellemeleri o istemciye artık çoğaltılmaz. BasePart.Position gibi özellikleri okumak devam eder, ancak son çoğaltılan değeri döner ve bu değer keyfi olarak eski olabilir.
local Players = game:GetService("Players")
local player = Players.LocalPlayer
-- "target" akıştan çıkmışsa konum eski olabilir
local dist = (target.Position - player.Character.HumanoidRootPart.Position).MagnitudeMantığı sunucuya taşıyın, çünkü sunucu tarafı betikleri her zaman tüm örnekleri görür. Bu, mesafe kontrolleri ve diğer konum hassasiyetine sahip mantık için genellikle en güvenilir seçenektir.
Kritik yolda beklemek
Bazı akış dışı oyunlar haritalarını ReplicatedStorage'dan Workspace'a kopyalayarak yükler ve ardından istemcide bir yükleme ekranını kapatmadan önce bekler. Akış altında bu sonsuz bir süre bekler — istemcinin karakteri henüz doğmamıştır, bu nedenle çoğaltma odaklanması yoktur ve mekansal harita örneği asla akışa alınmaz.
Yükleme ekranı mantığını, belirli bir mekansal örneğin mevcut olmasına bağlı olmayacak şekilde taşıyın; örneğin, karakter doğduğunda ve hemen çevresindeki alan akışa alındığında hazır olunduğunu bildirin.
Sinyal değişikliği yönetimi
Instance.ChildAdded/Instance.ChildRemoved gibi sinyaller ve CollectionService sinyalleri, akışa girme/çıkma sırasında da tetiklenir ve gerçek doğum/çıkarma olaylarından ayırt edilemez. Alıcı betikler sinyalin kendisinden farkı anlayamaz, bu nedenle bir sinyalin "gerçek" bir olaya karşılık geldiğini varsayan mantık güncellenmelidir.
Akışa girme ve/veya akıştan çıkma ile tetiklenen herhangi bir sinyal dinleyicisi için betikleri denetleyin. Örneğin, bir düşman NPC'si dünyaya ilk girdiğinde ses veya görsel efektler oynatıyorsanız, her düşmana ilk doğumda Spawned gibi bir özellik atayın ve düşmanın gelecekteki akışlarına aynı ses/efektleri tekrar oynatmayı atlayın.
local CollectionService = game:GetService("CollectionService")
local TAG_NAME = "Enemy"
CollectionService:GetInstanceAddedSignal(TAG_NAME):Connect(function(enemy)
if not enemy:GetAttribute("Spawned") then
-- İlk doğum için düşmana "Spawned" özelliğini ayarlayın
enemy:SetAttribute("Spawned", true)
-- Bu ilk doğum için ses/görsel efektleri oynatın
playSpawnEffects(enemy)
end
end)Koleksiyonlar üzerinde yineleme
İstemci tarafı koleksiyon yinelemeleri, Instance:GetChildren() ve Instance:GetDescendants() yalnızca akışta olan alt nesnelerin alt kümesini döner. Bu, ana nesne her zaman çoğaltılsa bile geçerlidir; örneğin, Workspace altında doğrudan bulunan bir Folder'ın mekansal alt nesneleri akışa girip çıkabilir.
local Players = game:GetService("Players")
local player = Players.LocalPlayer
-- "Homes" klasörü her zaman çoğaltılır ancak çocukları akışa girip çıkar
-- Bu döngü, şu anda akışta olmayan evleri atlayabilir
for _, home in workspace.Homes:GetChildren() do
if home.Settings.Owner.Value == player.Name then
return home
end
endTam bir listeleme gerekiyorsa, sunucuda tarama yapın ve sonucu gerekirse bir RemoteEvent aracılığıyla oyuncuya iletin.
Mekansal sorgular
İstemci tarafı mekansal sorgular, WorldRoot:Raycast(), WorldRoot:GetPartBoundsInBox() ve Model:GetBoundingBox() yalnızca akışta olan içeriği yansıtır. Bunun bir sorun olup olmadığı, sorgunun ne için kullanıldığına bağlıdır.
Sonucun tam dünyayı yansıtması gereken sorgular için sunucuyu kullanın; örneğin, bir oyuncunun uzak bir hedefe görüş hattı olup olmadığını kontrol eden bir ışın izleme.
Diğer desenler
Aşağıdaki desenler de geçerli olabilir ve dikkatlice değerlendirilmelidir:
Bir Sound veya AudioPlayer, 3D bir nesneye ebeveyn olduğunda, o nesne akıştan çıktığında durur. Akıştan bağımsız olarak devam etmesi gereken ortam sesleri için, yayıcıyı bir kalıcı modele veya akış dışı bir kapsayıcıya ebeveynleyin.
Oyun içi Kullanıcı Arayüzü nesneleri, BillboardGui veya SurfaceGui gibi, ayrıca Beams veya Highlights gibi görsel efektler akıştan çıkan bir nesne veya bağlantı ile birlikte renderlamayı durdurur. Bu, istenen bir davranış olabilir, ancak bunu doğrulamalısınız.
BasePart.Touched olayları, ProximityPrompts, DragDetectors ve ClickDetectors, istemcide ilgili parça/model akışta değilse çalışmaz. Etkileşim her mesafeden mümkün olmalıysa, modelin kalıcı olması gerekir veya etkileşim için farklı bir mekanizma gereklidir.
PathfindingService ve istemci tarafı yol bulma için, yol bulucu yalnızca istemcide akışta olan geometrileri görür ve sunucuda var olan engellerden geçebilir. Stratejiler için, Yol Bulma - Stratejiler bölümüne bakın.
Gerçekçi test koşulları
Skripler güncellendikten sonra, oyunu kapsamlı bir şekilde test edin. Akış hataları genellikle akış alanlarının kenarlarında veya geçişler sırasında ortaya çıkar, bu nedenle yalnızca doğum noktasında veya hedef yarıçapında test etmek yeterli değildir.
Workspace.StreamingTargetRadius değerini minimum değeri (64) olarak ayarlayın. Bazı akış hataları yalnızca akış alanı küçük olduğunda görünür.
Oyunun tam geçiş desenlerini oynayın, uzak alanlar arasında teleport edin ve ayrıldıktan sonra alanları yeniden ziyaret edin. Bu, akışa girme ve akıştan çıkma durumlarını en çok zorlayan durumlardır.
Aktif akış ayarlarını, şu anda yüklü bölgeleri ve çalışma zamanı akış durumunu izlemek için akış hata ayıklama üst bilgisi kullanın.
Hatalar için Çıktı penceresini ve Geliştirici Konsolu penceresini izleyin, çünkü birçok betik deseni hatalar üretir ve sessiz bir şekilde yanlış davranış gösterir. Özellikle attempt to index nil with ... biçimindeki hatalara dikkat edin; bu genellikle bir WaitForChild() çağrısının eksik olduğunu gösterir.
Tools ekipmanlarını giyin ve etkinleştirin, silah ateşleyin ve farklı oyun etkileşimlerini tetikleyin.
AI akış dönüşüm becerisi
Akış dönüşümü ve optimizasyonu konusunda yardımcı olmak için Roblox, oyununuzu değerlendiren, önerilen yapılandırmaları uygulayan ve uyumluluk sorunlarını temizleyen bir AI akış becerisi sunmaktadır:
- Akış ayarlarını önerilen temel değerlere yapılandırır.
- Uygun olduğunda modellerin detay seviyesini SLIM olarak ayarlar.
- Optimal boyutlar ve görsel kalite elde etmek için model yapılarını yeniden yapılandırır.
Oyununuza AI becerisini kullanmak için:
- ÖNEMLİOyununuza yedek alın. Dönüşüm süreci karmaşık olabilir, bu nedenle beceriyi çalıştırmadan önce her zaman bir yedek kaydetmelisiniz (Dosya ⟩ Roblox'a Yayınla) .
Bu beceriyi doğrudan Assistant'ta veya Studio'daki Model Bağlam Protokolü (MCP) aracılığıyla tercih ettiğiniz herhangi bir LLM kullanarak çalıştırabilirsiniz. Büyük bağlam pencerelerine sahip daha yüksek kaliteli AI modelleri önerilir; tipik bir dönüşüm için bir frontier modeli 20-30 dakika sürebilir ve yaklaşık 200.000 token bağlamı kullanabilir.
- Oyunuzu Studio'da açın.
- Assistant Ayarları ⟩ Beceriler'i açın ve rbx-convert-to-streaming'in açık olduğundan emin olun.
- Assistant'ı (veya MCP aracılığıyla bağlı LLM'nizi) beceriyi kullanması için yönlendirin.

