Bitki referans projesi

*Bu içerik, yapay zekâ (beta) kullanılarak çevrildi ve hatalar içerebilir. Sayfayı İngilizce görüntülemek için buraya tıkla.

Bitki, oyuncuların tohum ektiği ve suladığı bir referans oyunudur, böylece daha sonra bitkileri hasat edip satabilirler.

Bitki proje afişi

Proje, Roblox'ta bir oyun geliştirirken karşılaşabileceğiniz yaygın kullanım durumlarına odaklanmaktadır. Uygun olduğunda, çeşitli uygulama seçimlerinin nedenleri, trade-off'lar ve uzlaşmalar hakkında notlar bulacaksınız, böylece kendi oyunlarınız için en iyi kararı verebilirsiniz.

Dosyayı alın

  1. Bitki oyun sayfasına gidin.
  2. butonuna tıklayın ve Stüdyo'da Düzenle seçeneğine tıklayın.

Kullanım durumları

Bitki aşağıdaki kullanım durumlarını kapsamaktadır:

  • Oturum verileri ve oyuncu verisi kalıcılığı
  • UI görünüm yönetimi
  • İstemci-sunucu ağ iletişimi
  • İlk Kullanıcı Deneyimi (FTUE)
  • Sert ve yumuşak para alımları

Buna ek olarak, bu proje birçok oyuna uygulanabilir daha dar bir problem setini de çözmektedir, bunlar arasında:

  • Oyuncuya bağlı bir alanda özelleştirme
  • Oyuncu karakterinin hareket hızını yönetme
  • Karakterlerin etrafında dolaşan bir nesne oluşturma
  • Bir karakterin dünyada hangi bölümde olduğunu tespit etme

Bu oyunda, çok küçük, çok niş veya ilginç bir tasarım zorluğuna çözüm göstermeyen birkaç kullanım durumu olduğunu unutmayın; bunlar kapsanmamıştır.

Proje yapısı

Bir oyun oluştururken ilk karar, proje yapısını nasıl oluşturacağınızdır; bu, esasen belirli örneklerin veri modelinde nereye yerleştirileceği ve hem istemci hem de sunucu kodu için giriş noktalarının nasıl organize edileceği ile ilgilidir.

Veri modeli

Aşağıdaki tablo, veri modelindeki hangi konteyner hizmetlerinde örneklerin yerleştirildiğini tanımlamaktadır.

HizmetÖrnek türleri
Workspace

Oyuncuya ait olmayan dünya parçalarını temsil eden statik modelleri içerir. Bu örnekleri çalışma zamanında dinamik olarak oluşturmanız, değiştirmeniz veya yok etmeniz gerekmediğinden, burada bırakmak kabul edilebilir.

Ayrıca, oyuncuların çiftlik modellerinin çalışma zamanında ekleneceği boş bir Folder bulunmaktadır.

Lighting

Atmosferik ve aydınlatma efektleri.

ReplicatedFirst

Yükleme ekranını görüntülemek ve oyunu başlatmak için gereken en küçük örnek alt kümesini içerir. ReplicatedFirst'te yerleştirilen daha fazla örnek, ReplicatedFirst'teki kodun çalışabilmesi için replikasyon süresini uzatır.

  • Örnekler klasöründe yükleme ekranı GUI'si bulunmaktadır.
  • Kaynak klasöründe yükleme ekranı kodu ve oyunun geri kalanının yüklenmesini beklemek için gereken kod bulunmaktadır. start LocalScript, projedeki tüm istemci tarafı kodu için giriş noktasıdır.
ReplicatedStorage

İstemci ve sunucu üzerinde erişim gerektiren tüm örnekler için bir depolama konteyneri olarak hizmet eder.

  • Bağımlılıklar klasöründe projenin kullandığı bazı üçüncü taraf kütüphaneleri bulunmaktadır.
  • Örnekler klasöründe geniş bir önceden yapılmış örnek yelpazesi bulunmaktadır.
  • Kaynak klasöründe yükleme süreci için gerekli olmayan ve hem istemci hem de sunucudan erişilebilir olması gereken tüm kod bulunmaktadır.
ServerScriptService

Projede tüm sunucu tarafı kodu için giriş noktası olarak hizmet eden bir Script içerir.

ServerStorage

İstemciye replikasyona ihtiyaç duymayan tüm örnekler için bir depolama konteyneri olarak hizmet eder.

  • Örnekler klasöründe bir şablon Çiftlik modeli bulunmaktadır. Bu model, oyuncu oyuna katıldığında Workspace'te bir kopyası yerleştirilir ve tüm oyunculara replikasyon yapılır.
  • Kaynak klasöründe yalnızca sunucuya özel tüm kod bulunmaktadır.
SoundService

Oyundaki ses efektleri için kullanılan Sound nesnelerini içerir. SoundService altında, bu Sound nesnelerinin bir konumu yoktur ve 3D uzayda simüle edilmezler.

Giriş noktaları

Çoğu proje, tüm kod tabanında içe aktarılabilen yeniden kullanılabilir ModuleScripts içinde kodu organize eder. ModuleScripts yeniden kullanılabilir, ancak kendi başlarına çalışmazlar; bir Script veya LocalScript tarafından içe aktarılmaları gerekir. Birçok Roblox projesi, oyundaki bir davranış veya belirli bir sisteme ait olan her biri için çok sayıda Script ve LocalScript nesnesine sahip olacaktır ve bu da birden fazla giriş noktası oluşturur.

Bitki mikro oyunu için, tüm istemci kodu için giriş noktası olan tek bir LocalScript ve tüm sunucu kodu için giriş noktası olan tek bir Script aracılığıyla farklı bir yaklaşım uygulanmıştır. Projeniz için doğru yaklaşım gereksinimlerinize bağlıdır, ancak tek bir giriş noktası, sistemlerin yürütülme sırasını kontrol etme konusunda daha fazla kontrol sağlar.

Aşağıdaki listeler, her iki yaklaşımın trade-off'larını tanımlamaktadır:

  • Tek bir Script ve tek bir LocalScript, sırasıyla sunucu ve istemci kodunu kapsar.
  • Farklı sistemlerin başlatılma sırasını kontrol etme konusunda daha fazla kontrol sağlar çünkü tüm kod tek bir betikten başlatılır.
  • Sistemler arasında nesneleri referansla geçirebilirsiniz.

Yüksek seviyeli sistem mimarisi

Projede yer alan üst düzey sistemler aşağıda detaylandırılmıştır. Bu sistemlerden bazıları diğerlerinden önemli ölçüde daha karmaşıktır ve birçok durumda işlevsellikleri diğer sınıfların hiyerarşisi boyunca soyutlanmıştır.

Bitki proje sistemleri mimarisi diyagramı

Bu sistemlerin her biri bir "singleton"dır; yani, birden fazla örneği olamaz. Bunun yerine, ilgili istemci veya sunucu start betiği tarafından başlatılır. Daha fazla bilgi için singleton deseni hakkında daha sonra bu kılavuzda okuyabilirsiniz.

Sunucu

Aşağıdaki sistemler sunucu ile ilişkilidir.

SistemAçıklama
  • Tüm RemoteEvent ve RemoteFunction örneklerini oluşturur.
  • İstemciden mesaj göndermek ve dinlemek için yöntemler sunar.
  • Çalışma zamanında istemciden alınan argümanlar için tür doğrulaması yapar.
PlayerDataServer
  • DataStoreService kullanarak kalıcı oyuncu verilerini kaydeder ve yükler.
  • Oyuncu verilerini bellekte saklar ve değişiklikleri istemciye replik eder.
  • Oyuncu verilerine abone olma, sorgulama ve güncelleme için sinyaller ve yöntemler sunar.
Pazar
  • İstemciden yumuşak para işlemlerini yönetir.
  • Hasat edilen bitkileri satmak için bir yöntem sunar.
Çarpışma Grubu Yöneticisi
  • Oyuncu karakteri modellerini çarpışma gruplarına atar.
  • Oyuncu karakterlerinin bitki arabalarıyla çarpışmamasını sağlamak için çarpışma gruplarını yapılandırır.
FarmManagerServer
  • Oyuncu oyuna katıldığında oyuncunun çiftlik modelini oyuncu verilerinden yeniden oluşturur.
  • Bir oyuncu oyundan ayrıldığında çiftlik modelini kaldırır.
  • Bir oyuncunun çiftliği değiştiğinde oyuncu verilerini günceller.
  • Belirli bir oyuncuya ait Çiftlik sınıfına erişim sağlamak için bir yöntem sunar.
PlayerObjectsContainer
  • Bir oyuncunun yaşam döngüsü ile ilişkili çeşitli nesneleri oluşturur ve bunları almak için bir yöntem sağlar.
TagPlayers
FtueManagerServer
  • FTUE sırasında her aşamayı yürütür ve tamamlanmasını bekler.
CharacterSpawner
  • Karakterler öldüğünde yeniden doğurur. Players.CharacterAutoLoads devre dışı bırakıldığı için, oyuncunun verileri yüklenene kadar doğurma duraklatılır.

İstemci

Aşağıdaki sistemler istemci ile ilişkilidir.

SistemAçıklama
  • Sunucunun tüm RemoteEvent ve RemoteFunction örneklerini oluşturmasını bekler.
  • Sunucuya ve sunucudan mesaj göndermek ve dinlemek için yöntemler sunar.
  • Çalışma zamanında parametre türü doğrulamasını uygular.
  • Uzaktan işlevler üzerinde pcall() çalıştırır.
PlayerDataClient
  • Yerel oyuncunun verilerini bellekte saklar.
  • Oyuncu verilerindeki değişiklikleri sorgulamak ve bunlara abone olmak için yöntemler ve sinyaller sunar.
MarketClient
  • Sunucudan yumuşak para ile bir öğe satın almak için bir yöntem sunar.
LocalWalkJumpManager
  • Bir karakterin WalkSpeed veya JumpHeight değerlerini çarpanlar aracılığıyla değiştirmek için yöntemler sunar, böylece bu değerleri birden fazla yerden değiştirirken çakışmaları önler.
FarmManagerClient
  • Belirli CollectionService etiketlerinin örneklere uygulanmasını dinler ve bu örneklere davranış ekleyen "bileşenler" oluşturur. "Bileşen", bir CollectionService etiketi bir örneğe eklendiğinde oluşturulan ve kaldırıldığında yok edilen bir sınıfı ifade eder; bunlar çiftlikteki CTA istemleri ve çiftlik durumunu oyuncuya ileten çeşitli sınıflar için kullanılır.
UISetup
  • Tüm UI katmanlarını başlatır.
  • Belirli katmanların yalnızca dünyanın fiziksel bölümlerinde görünür olmasını yapılandırır.
  • Menülerin etkinleştirildiği zaman özel bir kamera efekti bağlar.
FtueManagerClient
  • İstemcide FTUE aşamalarını yapılandırır.
CharacterSprint
  • Bir oyuncu karakteri çiftliğinin dışındayken WalkSpeed değerini artırmak için LocalWalkJumpManager'ı kullanır.

İstemci-sunucu iletişimi

Çoğu Roblox oyunu, istemci ve sunucu arasında bir iletişim unsuru içerir. Bu, istemcinin sunucudan belirli bir eylemi gerçekleştirmesini istemesi ve sunucunun istemciye güncellemeleri replik etmesi gibi durumları içerebilir.

Bu projede, istemci-sunucu iletişimi, takip edilmesi gereken özel kural sayısını azaltmak için RemoteEvent ve RemoteFunction nesnelerinin kullanımını sınırlayarak mümkün olduğunca genel tutulmuştur. Bu proje, tercih sırasına göre aşağıdaki yöntemleri kullanmaktadır:

Oyuncu veri sistemi aracılığıyla replikasyon

oyuncu veri sistemi, verilerin oyuncuyla ilişkilendirilmesine olanak tanır ve bu veriler kaydetme oturumları arasında kalıcıdır. Bu sistem, istemciden sunucuya replikasyon sağlar ve verileri sorgulamak ve değişikliklere abone olmak için kullanılabilecek bir dizi API sunar; bu da sunucudan istemciye oyuncu durumundaki değişiklikleri replikasyon için idealdir.

Örneğin, istemciye kaç parası olduğunu bildirmek için özel bir UpdateCoins RemoteEvent ateşlemek yerine, aşağıdaki çağrıyı yapabilir ve istemcinin PlayerDataClient.updated olayına abone olmasına izin verebilirsiniz.

PlayerDataServer.setValue(player, "coins", 5)

Elbette, bu yalnızca sunucudan istemciye replikasyon için ve oturumlar arasında kalıcı olmasını istediğiniz değerler için yararlıdır, ancak bu, projedeki birçok durum için geçerlidir, bunlar arasında:

  • Mevcut FTUE aşaması
  • Oyuncunun envanteri
  • Oyuncunun sahip olduğu para miktarı
  • Oyuncunun çiftliğinin durumu

Özellikler aracılığıyla replikasyon

Sunucunun belirli bir Instance için istemciye özel bir değeri replik etmesi gerektiği durumlarda, özellikleri kullanabilirsiniz. Roblox, özellik değerlerini otomatik olarak replik eder, bu nedenle bir nesneyle ilişkili durumu replik etmek için herhangi bir kod yolu sürdürmeniz gerekmez. Bir diğer avantajı, bu replikasyonun nesneyle birlikte gerçekleşmesidir.

Bu, çalışma zamanında oluşturulan örnekler için özellikle yararlıdır, çünkü veri modeline ebeveyn olmadan önce yeni bir örneğe ayarlanan özellikler, nesneyle birlikte atomik olarak replik edilir. Bu, bir RemoteEvent veya StringValue aracılığıyla ek verilerin replikasyonunu "beklemek" için kod yazma gereksinimini ortadan kaldırır.

Ayrıca, hem istemciden hem de sunucudan veri modelinden doğrudan özellikleri okuyabilir ve GetAttribute() yöntemi ile değişikliklere abone olabilirsiniz; GetAttributeChangedSignal() yöntemi ile.

Bitki projesinde, bu yaklaşım, bitkilerin mevcut durumunu istemcilere replikasyon da dahil olmak üzere birçok şey için kullanılmaktadır.

Etiketler aracılığıyla replikasyon

CollectionService, bir Instance'e bir dize etiketi uygulamanıza olanak tanır. Bu, örnekleri kategorize etmek ve bu kategoriyi istemciye replik etmek için yararlıdır.

Örneğin, CanPlant etiketi, sunucuda belirli bir saksının bir bitki alabileceğini belirtmek için uygulanır.

Ağ modülü aracılığıyla doğrudan mesajlaşma

Önceki seçeneklerin hiçbiri geçerli olmadığında, modülü aracılığıyla özel ağ çağrıları kullanabilirsiniz. Bu, projede istemci-sunucu iletişimine izin veren tek seçenektir ve bu nedenle istemci taleplerini iletmek ve sunucu yanıtı almak için en yararlısıdır.

Bitki doğrudan ağ çağrılarını, aşağıdaki istemci talepleri için kullanmaktadır:

  • Bir bitki sulama
  • Bir tohum ekme
  • Bir öğe satın alma

Bu yaklaşımın dezavantajı, her bir bireysel mesajın bazı özel yapılandırmalar gerektirmesidir; bu da projenin karmaşıklığını artırabilir, ancak bu, özellikle sunucudan istemciye iletişimde mümkün olduğunca kaçınılmıştır.

Sınıflar ve singleton'lar

Bitki projesindeki sınıflar, Roblox'taki örnekler gibi oluşturulabilir ve yok edilebilir. Sınıf sözdizimi, nesne yönelimli programlama için idiyomatik Lua yaklaşımından esinlenmiştir ve katı tür kontrolü desteğini sağlamak için bir dizi değişiklik içermektedir.

Örnekleme

Projede birçok sınıf, bir veya daha fazla Instances ile ilişkilidir. Belirli bir sınıfın nesneleri, Roblox'ta Instance.new() kullanarak örneklerin oluşturulmasıyla tutarlı bir new() yöntemi kullanılarak oluşturulur.

Bu desen, genellikle sınıfın veri modelinde fiziksel bir temsili olduğu nesneler için kullanılır ve sınıfın işlevselliğini genişletir. İyi bir örnek, iki belirli Attachment nesnesi arasında bir Beam nesnesi oluşturan BeamBetween'dir ve bu ekleri, ışının her zaman yukarıya bakmasını sağlamak için yönlendirilmiş tutar. Bu örnekler, ReplicatedStorage'te önceden yapılmış bir versiyondan klonlanabilir veya new()'a bir argüman olarak geçirilebilir ve nesne içinde self altında saklanabilir.

Karşılık gelen örnekler

Yukarıda belirtildiği gibi, bu projedeki birçok sınıfın bir veri modeli temsili vardır; bu, sınıfla ilişkili ve onun tarafından manipüle edilen bir örnektir.

Bu örnekleri bir sınıf nesnesi oluşturulduğunda yaratmak yerine, kod genellikle Clone() ile ReplicatedStorage veya ServerStorage altında saklanan önceden yapılmış bir versiyonu klonlamayı tercih eder. Bu örneklerin özelliklerini serileştirmek ve sınıfın new() işlevlerinde sıfırdan oluşturmak mümkün olsa da, bu, nesneleri düzenlemeyi çok zahmetli hale getirir ve okuyucunun anlamasını zorlaştırır. Ayrıca, bir örneği klonlamak, yeni bir örnek oluşturup özelliklerini çalışma zamanında özelleştirmekten genellikle daha hızlı bir işlemdir.

Bileşim

Luau'da metatable'lar kullanarak kalıtım mümkün olsa da, proje bunun yerine sınıfların bileşim yoluyla birbirini genişletmesine izin vermeyi tercih etmektedir. Sınıfları bileşim yoluyla birleştirirken, "çocuk" nesnesi sınıfın new() yönteminde örneklendirilir ve self altında bir üye olarak dahil edilir.

Bunun bir örneğini, Button sınıfını saran CloseButton sınıfında görebilirsiniz.

Temizlik

Bir Instance'in Destroy() yöntemi ile yok edilebileceği gibi, örneklendirilebilen sınıflar da yok edilebilir. Proje sınıflarının yok edici yöntemi, kod tabanındaki yöntemler arasında camelCase tutarlılığı için küçük d ile destroy()'dur ve projenin sınıfları ile Roblox örnekleri arasında ayırt edici bir özellik sağlar.

destroy() yönteminin rolü, nesne tarafından oluşturulan herhangi bir örneği yok etmek, bağlantıları kesmek ve çocuk nesneler üzerindeki destroy()'yi çağırmaktır. Bu, bağlantılar için özellikle önemlidir çünkü aktif bağlantılara sahip örnekler, nesneye veya nesneye olan bağlantılara hiçbir referans kalmadığında bile Luau çöp toplayıcısı tarafından temizlenmez.

Singleton'lar

Singleton'lar, adından da anlaşılacağı gibi, yalnızca bir nesnenin var olabileceği sınıflardır. Bunlar, projenin Roblox'un Hizmetleri ile eşdeğeridir. Singleton nesnesine bir referans saklamak ve bunu Luau kodunda dolaştırmak yerine, Bitki ModuleScript'in gereksinimlerinin döndürülen değerini önbelleğe aldığını kullanır. Bu, farklı yerlerden aynı singleton ModuleScript'i gereksinim duyduğunuzda tutarlı bir şekilde aynı döndürülen nesneyi sağlar. Bu kuralın tek istisnası, farklı ortamların (istemci veya sunucu) ModuleScript'e erişmesidir.

Singleton'lar, örneklendirilebilir sınıflardan, new() yöntemine sahip olmamalarıyla ayırt edilir. Bunun yerine, nesne ve yöntemleri ile durumu doğrudan ModuleScript aracılığıyla döndürülür. Singleton'lar örneklendirilmediğinden, self sözdizimi kullanılmaz ve yöntemler yerine nokta (.) ile çağrılır.

Katı tür çıkarımı

Luau kademeli tipleri destekler, bu da kodunuzun bazı veya tümüne isteğe bağlı tür tanımlamaları eklemenize olanak tanır. Bu projede, her betik için strict tür kontrolü kullanılır. Bu, Roblox'un Betik Analizi aracının en az izin veren seçeneğidir ve bu nedenle tür hatalarını çalışma zamanından önce yakalama olasılığı en yüksektir.

Tipli sınıf sözdizimi

Lua'da sınıf oluşturma için belirlenen yaklaşım iyi belgelenmiştir, ancak güçlü Luau tipleri için iyi bir şekilde uygun değildir. Luau'da, bir sınıfın türünü almanın en basit yolu typeof() yöntemidir:

type ClassType = typeof(Class.new())

Bu çalışır, ancak sınıfınızın yalnızca çalışma zamanında var olan değerlerle başlatıldığı durumlarda, örneğin Player nesneleri gibi çok yararlı değildir. Ayrıca, idiyomatik Lua sınıf sözdiziminde, bir sınıf self üzerinde bir yöntem tanımlamanın her zaman o sınıfın bir örneği olacağı varsayımı yapılır; bu, tür çıkarım motorunun yapabileceği bir varsayım değildir.

Katı tür çıkarımını desteklemek için, Bitki projesi, idiyomatik Lua sınıf sözdiziminden bir dizi şekilde farklı bir çözüm kullanmaktadır; bunların bazıları sezgisel hissettirmeyebilir:

  • self tanımı, hem tür tanımında hem de yapıcıda tekrarlanır. Bu, bakım yükü getirir, ancak iki tanımın birbirinden senkronize olmaması durumunda uyarılar verilecektir.
  • Sınıf yöntemleri bir nokta ile tanımlanır, böylece self açıkça ClassType türünde olarak tanımlanabilir. Yöntemler, beklenildiği gibi bir iki nokta (:) ile çağrılabilir.
--!strict
local MyClass = {}
MyClass.__index = MyClass
export type ClassType = typeof(setmetatable(
{} :: {
property: number,
},
MyClass
))
function MyClass.new(property: number): ClassType
local self = {
property = property,
}
setmetatable(self, MyClass)
return self
end
function MyClass.addOne(self: ClassType)
self.property += 1
end
return MyClass

Mantıksal korumalardan sonra türleri dönüştürme

Yazma zamanında, bir değerin türü bir koruma koşul ifadesinden sonra daraltılmaz. Örneğin, aşağıdaki korumadan sonra, optionalParameter'ın türü number olarak daraltılmaz.

--!strict
local function foo(optionalParameter: number?)
if not optionalParameter then
return
end
print(optionalParameter + 1)
end

Bunu hafifletmek için, bu korumalardan sonra türü açıkça dönüştürülmüş yeni değişkenler oluşturulur.

--!strict
local function foo(optionalParameter: number?)
if not optionalParameter then
return
end
local parameter = optionalParameter :: number
print(parameter + 1)
end

Veri Modeli hiyerarşilerini geçme

Bazı durumlarda, kod tabanı, çalışma zamanında oluşturulan nesnelerin bir ağacının veri modeli hiyerarşisini geçmek zorundadır. Bu, tür kontrolü için ilginç bir zorluk sunar. Yazma zamanında, bir tür olarak genel bir veri modeli hiyerarşisi tanımlamak mümkün değildir. Sonuç olarak, veri modeli yapısı için mevcut olan tek tür bilgisi, üst düzey örneğin türüdür.

Bu zorluğa bir yaklaşım, any türüne dönüştürmek ve ardından ince ayar yapmaktır. Örneğin:

local function enableVendor(vendor: Model)
local zonePart: BasePart = (vendor :: any).ZonePart
end

Bu yaklaşımın sorunu, okunabilirliği etkilemesidir. Bunun yerine, proje, veri modeli hiyerarşilerini geçmek için any türüne içsel olarak dönüştüren getInstance adlı genel bir modül kullanmaktadır.

local function enableVendor(vendor: Model)
local zonePart: BasePart = getInstance(vendor, "ZonePart")
end

Tür motorunun veri modeli anlayışı geliştikçe, bu tür kalıpların artık gerekli olmayabileceği mümkündür.

Kullanıcı arayüzü

Bitki, karmaşık ve basit 2D kullanıcı arayüzlerinin bir dizi örneğini içerir. Bunlar, madeni para sayacı gibi etkileşimsiz gösterim (HUD) öğeleri ve mağaza gibi karmaşık etkileşimli menüler içerir.

UI yaklaşımı

Roblox UI'sını, kullanıcıya ne görmesi gerektiğini tanımlayan bir nesne hiyerarşisi olduğu için HTML DOM'a gevşek bir şekilde karşılaştırabilirsiniz. Roblox UI oluşturma ve güncelleme yaklaşımları, genel olarak emredici ve deklare edici uygulamalar olarak ikiye ayrılır.

YaklaşımAvantajlar ve dezavantajlar
Emredici

Emredici yaklaşımda, UI, Roblox'taki diğer örnek hiyerarşileri gibi ele alınır. UI yapısı, çalışma zamanından önce Stüdyo'da oluşturulur ve veri modeline eklenir, genellikle doğrudan StarterGui içinde. Daha sonra, çalışma zamanında, kod, yaratıcının gerektirdiği durumu yansıtmak için UI'nin belirli parçalarını manipüle eder.

Bu yaklaşım bazı avantajlar sunar. UI'yi Stüdyo'da sıfırdan oluşturabilir ve veri modelinde saklayabilirsiniz. Bu, UI oluşturmayı hızlandırabilecek basit ve görsel bir düzenleme deneyimidir. Emredici UI kodu yalnızca neyin değişmesi gerektiği ile ilgilendiğinden, basit UI değişikliklerini uygulamak da kolaydır.

Önemli bir dezavantaj, emredici UI yaklaşımlarının durumun dönüşümler şeklinde manuel olarak uygulanmasını gerektirmesi nedeniyle, karmaşık durum temsillerinin bulunması ve hata ayıklanmasının çok zor hale gelmesidir. Emredici UI kodu geliştirirken, durum ve UI'nin, beklenmedik bir sırada etkileşime girmesi nedeniyle senkronize olmaması durumunda hataların ortaya çıkması yaygındır.

Emredici yaklaşımlarla ilgili bir diğer zorluk, UI'yi anlamlı bileşenlere ayırmanın daha zor olmasıdır; bu bileşenler bir kez tanımlanabilir ve yeniden kullanılabilir. Tüm UI ağacının düzenleme zamanında tanımlanması nedeniyle, yaygın kalıplar veri modelinin birden fazla bölümünde tekrarlanabilir.

Deklare Edici

Deklare edici yaklaşımda, UI örneklerinin istenen durumu açıkça tanımlanır ve bu durumun verimli bir şekilde uygulanması, Roact veya Fusion gibi kütüphaneler tarafından soyutlanır.

Bu yaklaşımın avantajı, durumun uygulanmasının önemsiz hale gelmesidir ve yalnızca UI'nizin nasıl görünmesini istediğinizi tanımlamanız gerekir. Bu, hataları tanımlamayı ve çözmeyi önemli ölçüde kolaylaştırır.

Temel dezavantaj, tüm UI ağacını kodda deklare etme gerekliliğidir. Roact ve Fusion gibi kütüphaneler bunu kolaylaştırmak için sözdizimine sahiptir, ancak bu yine de zaman alıcı bir süreçtir ve UI'yi oluştururken daha az sezgisel bir düzenleme deneyimi sunar.

Bitki emredici bir yaklaşım kullanır; çünkü dönüşümlerin doğrudan gösterilmesinin, Roblox'ta UI'nin nasıl oluşturulduğu ve manipüle edildiği hakkında daha etkili bir genel bakış sunduğu düşünülmektedir. Bu, deklare edici bir yaklaşım ile mümkün olmazdı. Bazı tekrarlanan UI yapıları ve mantıkları, emredici UI tasarımında yaygın bir tuzağı önlemek için yeniden kullanılabilir bileşenler haline de soyutlanmıştır.

Yüksek seviyeli mimari

Bitki proje UI mimarisi diyagramı

Katman ve bileşenler

Bitki projesinde, tüm UI yapıları ya bir Layer ya da bir Component'dir.

  • Layer, ReplicatedStorage'te önceden yapılmış UI yapılarının etrafında sarılmış üst düzey bir gruplama singleton'ı olarak tanımlanır. Bir katman, bir dizi bileşen içerebilir veya tamamen kendi mantığını kapsayabilir. Katman örnekleri, envanter menüsü veya HUD'deki madeni para göstergesi gibi örneklerdir.
  • Component, yeniden kullanılabilir bir UI öğesidir. Yeni bir bileşen nesnesi oluşturulduğunda, ReplicatedStorage'ten önceden yapılmış bir şablonu klonlar. Bileşenler, kendileri de başka bileşenler içerebilir. Bileşen örnekleri, genel bir buton sınıfı veya bir öğeler listesi kavramıdır.

Görünüm yönetimi

Yaygın bir UI yönetim sorunu görünüm yönetimidir. Bu proje, kullanıcı girişini dinleyen bir dizi menü ve HUD öğesine sahiptir ve bunların ne zaman görünür veya etkin olacağına dikkatli bir şekilde yönetilmesi gerekmektedir.

Bitki bu sorunu, bir UI katmanının görünür olup olmayacağını yöneten UIHandler sistemi ile ele alır. Oyundaki tüm UI katmanları HUD veya Menu olarak kategorize edilir ve görünürlükleri aşağıdaki kurallara göre yönetilir:

  • Menu ve HUD katmanlarının etkin durumu değiştirilebilir.
  • Etkin HUD katmanları yalnızca hiçbir Menu katmanı etkin değilse gösterilir.
  • Etkin Menu katmanları bir yığında saklanır ve yalnızca bir Menu katmanı aynı anda görünür. Bir Menu katmanı etkinleştirildiğinde, yığının önüne eklenir ve gösterilir. Bir Menu katmanı devre dışı bırakıldığında, yığından kaldırılır ve sıradaki etkin Menu katmanı gösterilir.

Bu yaklaşım sezgisel bir yaklaşımdır çünkü menülerin geçmişle gezilmesine olanak tanır. Bir menü başka bir menüden açıldığında, yeni menü kapatıldığında eski menü tekrar gösterilecektir.

Daha fazla okuma

Bitki projesinin bu kapsamlı incelemesinden sonra, ilgili kavramlar ve konular hakkında daha derinlemesine bilgi edinmek için aşağıdaki kılavuzları keşfetmek isteyebilirsiniz.

  • İstemci-Sunucu Modeli — Roblox'taki istemci-sunucu modelinin bir genel görünümü.
  • Luau — Roblox'un Lua 5.1'den türetilen scripting dili Luau hakkında detaylar.
  • Uzaktan Olaylar ve Geri Çağırmalar — İstemci-sunucu sınırında iletişim için uzaktan ağ olayları ve geri çağırmalar hakkında her şey.
  • UI — Roblox'taki kullanıcı arayüzü nesneleri ve tasarımı hakkında detaylar.
©2026 Roblox Corporation. Roblox, the Roblox logo and Powering Imagination are among our registered and unregistered trademarks in the U.S. and other countries.