Karakter Kontrol Kütüphanesi (CCL), karakter hareketi ve davranışlarını özellikler ve Luau betikleri aracılığıyla oluşturmak için modüler bir çerçevedir. Bu mimari, katı Humanoid durum makinelerini, karakter mekaniği için esnek ve genişletilebilir bir sistemle değiştirmektedir.
CCL'yi Etkinleştir
CCL, Studio'nun Avatar Ayarları penceresi aracılığıyla isteğe bağlı olarak etkinleştirilir. Bunu etkinleştirmek için:
Dosya ⟩ Beta Özellikleri ⟩ AvatarAbilities Karakter Kontrolcü Kütüphanesi üzerinden CCL beta'sını etkinleştirin.
Avatar sekmesinden, Avatar Ayarları'nı açın.

Pencerenin sol tarafında Hareket sekmesini seçin ve Yetenekler bölümünde Karakter Kontrolcü Kütüphanesi'ni seçin.

Koşma, Zıplama ve Tırmanma gibi standart yeteneklerin hepsi varsayılan olarak etkinleştirilmiştir. Bunlardan herhangi birini çalışma zamanında devre dışı bırakmak için, ilgili kutucuğu işaretini kaldırın.
Yetenekler
Yetenekler, bir karakterin koşma, zıplama, tırmanma ve yüzme gibi neler yapabileceğini değerlendirir. Enum.HumanoidStateType gibi motor tarafından tanımlanan sabit bir karakter durumu setine güvenmek yerine, CCL yetenekleri dinamik olarak bir karakterin neler yapabileceğini ve oyuncu girdisine nasıl yanıt vermesi gerektiğini belirler.
Yapısal olarak, bir yetenek, esasen aşağıdakileri belirten kendine ait bir Luau tablosudur:
| Tablo Alanları | Amaç |
|---|---|
| Name | Yetenek için bir etiket biti tahsis edilen isim, böylece koşullar ve çelişkiler yeteneği referans alabilir. Birden fazla yetenek tanımı aynı ismi kullanabilir. ModuleScript ismi, benzersiz yapılandırma anahtarını belirler. |
| Labels, TimedLabels | Yetenekler arasında koordinasyon otobüsü işlevi gören paylaşılan 64-bit maskesinde adlandırılmış bitler; etiketler için bakınız. |
| StartsWhen, RunsWhile | Yetenek ne zaman başlayacağını ve ne zaman devam edeceğini tanımlayan koşullar; koşullar için bakınız. |
| Blocks, Stops, Suspends, ExclusiveGroup | Bir anda aktif olamayacak yetenekler arasındaki çelişkileri nasıl yöneteceğinizi tanımlar. |
| Input | Yeteneği tetikleyen girdi. CCL bunu StartsWhen içine enjekte eder ve RunsWhile'ı atladığınızda, varsayılan devam koşulu olarak kullanır; girdiler için bakınız. |
| Config, State | Her yetenek kaydı için varsayılan yapılandırma değerleri ve çoğaltılmış durum. Geri çağırmalar, yapılandırmayı abilityCtx.Config'ten okur ve çoğaltılmış durumu abilityCtx.State üzerinden okur veya yazar. |
| OnSetup, OnStart, OnStop, OnUpdate, OnTeardown | Yeteneğin gerçek davranışının betimlendiği yaşam döngüsü geri çağırmaları; geri çağırmalar için bakınız. |
Etiketler
Bir etiket, yetenekler arasında koordinasyon otobüsü işlevi gören paylaşılan 64-bit maskesinde adlandırılmış bir bittir. Temelde:
- Aktif bir yetenek, Labels ve TimedLabels'ını dünya maskesine yayar.
- Yetenek çelişkileri, etkinleştirildiğinde hangi diğer yeteneklerin engellendiğini, durdurulduğunu veya askıya alındığını tanımlar.
Aşağıdaki yapılandırmada, Running aktif olduğunda "CanFallDown" etiketi dünya maskesine yayılır. FallingDown yeteneği, StartsWhen = All( "CanFallDown", "Stunned" ) koşuluyla otomatik olarak bir aday haline gelir, ancak "Stunned"'ın da FallingDown gerçekleşmeden önce dünya maskesine yayılması gerekir.
local AvatarAbilities = require("@rbx/AvatarAbilities")
local Identifiers = AvatarAbilities.Identifiers
local Ability = Identifiers.Ability
local Rule = AvatarAbilities.Rule
local Sensor = Identifiers.Sensor
local All, Any, Not = Rule.All, Rule.Any, Rule.Not
local Running: AvatarAbilities.AbilityDefinition = {
Name = Ability.Running,
Labels = { "CanFallDown" }, -- Yetenek aktifken yayılan etiketler
StartsWhen = Sensor.Ground,
RunsWhile = Sensor.Ground,
}local AvatarAbilities = require("@rbx/AvatarAbilities")
local Identifiers = AvatarAbilities.Identifiers
local Ability = Identifiers.Ability
local Rule = AvatarAbilities.Rule
local Sensor = Identifiers.Sensor
local All, Any, Not = Rule.All, Rule.Any, Rule.Not
local FallingDown: AvatarAbilities.AbilityDefinition = {
Name = Ability.FallingDown,
StartsWhen = All( "CanFallDown", "Stunned" ), -- Yetenek başlaması için gerekli etiketler
Blocks = { Ability.Running }
}Etiketler ayrıca TimedLabels sözlüğünü kullanarak zamanlı bir şekilde yayılabilir veya tüketilebilir.
| Anahtar | Açıklama |
|---|---|
| TimedLabels.OnStart | Yetenek başladığında yayılan etiketler (anahtarlar) ve ilişkili süreleri içeren sözlük. Örneğin, OnStart = { Dashing = 1 } yetenek başladığında Dashing etiketini 1 saniye yayar. |
| TimedLabels.OnStop | Yetenek durduğunda yayılan etiketler (anahtarlar) ve ilişkili süreleri içeren sözlük. Örneğin, OnStop = { DashCooldown = 2 } yetenek durduğunda DashCooldown etiketini 2 saniye yayar. |
| TimedLabels.Consumes | Yetenek etkinleştirildiğinde kaldırılacak (tüketilecek) etiketlerin listesi. Örneğin, bir dövüş oyunu, oyuncuların rakiplerinin saldırısını engelledikten sonra karşı saldırı yapmalarına izin veriyorsa, CounterAttack yeteneği hem StartsWhen = "AfterBlock" hem de TimedLabels = { Consumes = { "AfterBlock" } } içerebilir, böylece CounterAttack yeteneğinin çift tetiklenmesini önler. |
local AvatarAbilities = require("@rbx/AvatarAbilities")
local Identifiers = AvatarAbilities.Identifiers
local Rule = AvatarAbilities.Rule
local Sensor = Identifiers.Sensor
local All, Any, Not = Rule.All, Rule.Any, Rule.Not
local Dash: AvatarAbilities.AbilityDefinition = {
Name = "Dash",
StartsWhen = All( Sensor.Ground, Not("DashCooldown") ),
RunsWhile = "Dashing",
TimedLabels = {
OnStart = { Dashing = 1 },
OnStop = { DashCooldown = 2 },
},
}Koşullar
Bir koşul, StartsWhen ve RunsWhile tarafından kullanılan bir veya daha fazla etiket, sensör veya bir girdi referansıdır. Koşullar, çalışma zamanında bitmask işlemlerine derlenir ve değerlendirme tam sayı matematiğidir — tablo yürüyüşü yoktur ve dize karşılaştırmaları yoktur.
| Amaç | Sözdizimi | Örnek |
|---|---|---|
| Bir gerekli koşul. | StartsWhen = Sensor.Ground | |
| VE mantığı, tüm etiketlerin dünya maskesinde mevcut olduğu ve tüm sensörlerin aktif olduğu durumlar için. | All() | StartsWhen = All( "CanFallDown", "Stunned" ) |
| VEYA mantığı, herhangi etiketin dünya maskesinde mevcut olduğu veya herhangi sensörün aktif olduğu durumlar için. | Any() | StartsWhen = Any( "WallClimbing", "Climbing" ) |
| Olumsuzlama, böylece etiketler dünya maskesinde bulunamaz ve sensörler aktif olamaz. | Not() | RunsWhile = Not("Stunned") |
Koşullu değerlendirme, daha karmaşık mantıklar için birleştirilebilir, örneğin bir sensörün aktif olması gerektiğini belirtmek için All() zincirleme artı Not() kullanarak bir etiketin mevcut olmaması gerektiğini belirtebilirsiniz:
local AvatarAbilities = require("@rbx/AvatarAbilities")
local Identifiers = AvatarAbilities.Identifiers
local Rule = AvatarAbilities.Rule
local Sensor = Identifiers.Sensor
local All, Any, Not = Rule.All, Rule.Any, Rule.Not
local Dive: AvatarAbilities.AbilityDefinition = {
Name = "Dive",
StartsWhen = All( Sensor.WaterSurface, Not("Recovering") ),
}Çelişkiler
Bazı yetenekler, başka bir yetenek aktifken aktif olamaz; örneğin, karakterler yüzme sırasında zıplayamaz ve düşerken koşamazlar. Motor, bu çelişkileri bir yeteneğin tanımı içinde açıklayıcı bir şekilde çözer:
| Çelişki Anahtarı | Amaç |
|---|---|
| Blocks | Sahip olunan yetenek aktifken, listelenen diğer yetenekler başlayamaz. Örneğin, bir ScopeAim yeteneği, karakterlerin dikkatlice silahlarının dürbününden nişan alırken koşmalarını veya zıplamalarını önlemek için Blocks = { Ability.Running, Ability.Jumping } içerebilir. |
| Stops | Sahip olunan yetenek başladığında, listelenen diğer yetenekler zorla durdurulur ve yeniden tetiklenmelidir. Örneğin, bir Hover yeteneği, karakterin havada durmaya başladığında koşma hareketini hemen durdurmak için Stops = { Ability.Running } içerebilir. |
| Suspends | Sahip olunan yetenek başladığında, listelenen diğer yetenekler askıya alınır ve ardından sahip olunan yetenek durduğunda otomatik olarak devam eder. Örneğin, özel bir sprint yeteneği, koşmanın 🄐 sprint başlangıcında askıya alınmasını, 🄑 orta sprintte engellenmesini ve 🄒 sprint durduğunda devam etmesini sağlamak için Suspends = { Ability.Running } içerebilir. |
Bir diğer benzersiz çelişki anahtarı ExclusiveGroup'tur; bu, bir grup içinde birden fazla yetenek yerleştirir ve her birine bir Priority değeri atar. Her grup için yalnızca bir yetenek aktif olabilir ve daha yüksek öncelik kazanır. Ancak, bir rakip, sahibinin ismine/etiketine yönelik Stops bildirirse, öncelikten bağımsız olarak kazanır.
Aşağıdaki yapılandırmada, üç yetenek (Sprinting, Crouching, Stagger) bir Locomotion özel grubuna eklenmiştir. Sprinting en yüksek önceliğe (200) sahiptir, bu nedenle Crouching'i (100) geçer ve ikisi aynı anda çalışmaz. Ancak, Stagger sprinti zorla durdurur (Stops = { Ability.Sprinting }), bu nedenle önceliği (150) daha düşük olmasına rağmen Sprinting'i kesip geçebilir.
local AvatarAbilities = require("@rbx/AvatarAbilities")
local Identifiers = AvatarAbilities.Identifiers
local Ability = Identifiers.Ability
local Rule = AvatarAbilities.Rule
local Sensor = Identifiers.Sensor
local All, Any, Not = Rule.All, Rule.Any, Rule.Not
local Sprinting: AvatarAbilities.AbilityDefinition = {
Name = Ability.Sprinting,
ExclusiveGroup = { Name = "Locomotion", Priority = 200 },
}
local Crouching: AvatarAbilities.AbilityDefinition = {
Name = Ability.Crouching,
ExclusiveGroup = { Name = "Locomotion", Priority = 100 },
}
-- Daha düşük öncelikli bir yetenek, daha yüksek öncelikli bir yeteneği durdurarak geçebilir
local Stagger: AvatarAbilities.AbilityDefinition = {
Name = "Stagger",
ExclusiveGroup = { Name = "Locomotion", Priority = 150 },
Stops = { Ability.Sprinting },
}Girdiler
Bir yeteneğin Input tanımı, yeteneği etkinleştirmek için kullanılan girişi belirtir. Girdi davranışını, eylem slotunu ve isteğe bağlı dokunmatik düğme simgelerini yapılandıran anahtar-değer çiftlerini alır.
local AvatarAbilities = require("@rbx/AvatarAbilities")
local Identifiers = AvatarAbilities.Identifiers
local Rule = AvatarAbilities.Rule
local Sensor = Identifiers.Sensor
local All, Any, Not = Rule.All, Rule.Any, Rule.Not
local Dash: AvatarAbilities.AbilityDefinition = {
Name = "Dash",
Input = { InputName = "Dash", Mode = "Press", ActionSlot = 5 }
}InputName, mantıksal bir isimdir, bir anahtar değil. CCL, bir girdi sensörü oluşturur ve her zaman bunu StartsWhen'e ekler. StartsWhen'e Rule.Input eklemeyin.
Mode, bu girdinin nasıl yorumlanacağını tanımlar:
Mod Davranış Kullanım Durumları Press Girdi basıldığında yetenek etkinleştirilmesi denenir. Otomatik olarak StartsWhen koşuluna enjekte edilir. Dash, saldırı ve fırlatma gibi ayrık eylemler. Hold Girdi tutulduğunda yetenek çalışır; bırakıldığında, oluşturulan girdi sensörü RunsWhile koşulu olduğunda durur. Sürekli eylemler, sprint, nişan alma ve bloklama gibi. Toggle Her basış, yeteneği açar veya kapatır, oluşturulan girdi sensörü RunsWhile koşulu olduğunda. Açılıp kapatılan duruşlar veya hareketler, örneğin eğilme veya havada durma. Repeat Hold gibi, ancak her döngüde yeniden tetikler. Kendiliğinden durabilen ve tutulduğunda yeniden ateş edilebilen eylemler. ActionSlot, Girdi Eylem Sistemi içinde InputActions ve InputBindings ile ilişkili bir eylem slotu tanımlar.
Birçok eylem slotu girdi bağlaması Roblox tarafından önceden tanımlanmıştır ve gelecekte Girdi Eylem Yöneticisi, eylem slotları için varsayılan girdi bağlamalarını istediğiniz gibi yeniden yapılandırmanıza olanak tanıyacaktır. ActionSlot'u 0 olarak ayarlamak, bir sonraki mevcut boş slotu seçecektir. Mobil cihazlarda, 1-7 slotları ekrandaki butonlara yerleştirilir (aşağıdaki diyagrama bakın).
Slot Klavye & Fare Oyun Kumandası Dokunma Varsayılan Atama 1 Space ButtonA ① Zıpla 2 LeftShift ButtonL1 ② Koş 3 LeftControl ButtonB ③ Çömel 4 R ButtonX ④ 5 MouseLeftButton ButtonR2 ⑤ 6 Q ButtonY ⑥ 7 X ButtonR1 ⑦ 8 C ButtonL2 9 F DPadLeft 10 G DPadRight 11 V DPadDown 
CustomIcon, CustomIconActive ve CustomIconInvalid, yetenek boşta, aktif veya kullanılamazken dokunmatik düğme için Roblox varlık kimliklerini belirtir.
RunsWhile'ı atladığınızda, CCL oluşturulan girdi sensörünü devam koşulu olarak kullanır. RunsWhile tanımladığınızda, bu varsayılanı değiştirir. Girdisi etkin olmadığında durması gereken bir Hold veya Toggle yeteneği için, özel koşulda Rule.Input işaretçisini doğrudan dahil edin. Rule.Input bir değerdir, bir fonksiyon değil:
local AvatarAbilities = require("@rbx/AvatarAbilities")
local Rule = AvatarAbilities.Rule
local Sensor = AvatarAbilities.Identifiers.Sensor
local All, Any, Not = Rule.All, Rule.Any, Rule.Not
local Input = Rule.Input
local Glide: AvatarAbilities.AbilityDefinition = {
Name = "Glide",
Input = { InputName = "Glide", Mode = "Hold", ActionSlot = 6 },
StartsWhen = Not(Sensor.Ground),
RunsWhile = All(Not(Sensor.Ground), Input),
}Sensörler
Bir sensör, motorun sizin için okuduğu dünya hakkında adlandırılmış bir değerdir. Genellikle sensörleri okumayı, yazmayı tercih edersiniz. Kolaylık olması açısından, birkaç sensör önceden kaydedilmiştir:
| Sensör | Açıklama |
|---|---|
| Sensor.Ground | Bir yüzeyin üzerinde durmak |
| Sensor.IsMoving | Hareket girişi uygulanıyor |
| Sensor.MoveInput | Hareket vektörü |
| Sensor.Ceiling | Doğrudan üstte bir şey var |
| Sensor.Climb | Tırmanılabilir bir yüzeyin menzilinde olması |
| Sensor.Water / Sensor.WaterSurface | Suda / yüzeyde olmak |
| Sensor.Sit | Oturmak |
| Sensor.Tipped | Yıkılmış olmak |
| Sensor.Tool | Bir Tool tutmak |
| Sensor.LookDirectionInput | Komut verilen bakış yönü |
| Sensor.RotateToLookDirectionInput | Karakterin komut verilen bakış yönüne dönecek olup olmadığı |
Geri Çağırmalar
Yetenek geri çağırma fonksiyonları, belirli davranışları betimlemenizi sağlar:
Özel yetenekleri sunucuda kaydetseniz de, geri çağırmaları hem tahmin edilen istemci simülasyonunda hem de yetkili sunucu simülasyonunda çalışır. Geri çağırma davranışını belirleyici tutun, böylece her iki simülasyon da aynı sonucu üretir.
| Geri Çağırma | Çalışır | Kullanım Durumları |
|---|---|---|
| OnSetup(managerCtx, abilityCtx) | Bir kez, yetenek kaydedildiğinde. | Referansları önbelleğe almak, durumu başlatmak vb. |
| OnStart(managerCtx, abilityCtx, hadLabel) | Yetenek her etkinleştirildiğinde. | Bir etki uygulamak, örneğin bir itme. hadLabel() fonksiyonu, etkinleştirme başladığında belirtilen etiketin mevcut olup olmadığını bildirir, çelişki çözümlemesinden önce. |
| OnUpdate(managerCtx, abilityCtx) | Her aktif karede. | Zamanlayıcılar veya kare başına kuvvetler gibi sürekli işler. |
| OnStop(managerCtx, abilityCtx) | Her devre dışı bırakmada, isteğe bağlı veya zorla. | OnStart()'ın yaptığı her şeyi geri almak. |
| OnTeardown(managerCtx, abilityCtx) | Yetenek kaldırıldığında. | Bağlantıları kesmek, örnekleri yok etmek vb. |
Her geri çağırma fonksiyonunun ilk parametresi, paylaşılan karakter ve yönetici özellikleri ile birlikte bir ManagerContext nesnesidir:
- managerCtx.AbilityManager — Bir yeteneğin kendi geri çağırmaları içinde yetenek ekleyip, kaldırabilmesi ve sorgulayabilmesi için yöneticinin kesilmiş bir görünümü.
- managerCtx.BodyParts — Karakterin vücut parçaları, her uzuv için çarpışmayı açıp kapatmaya yardımcı olur.
- managerCtx.ControllerManager — Karakterin fizik kontrolü için ControllerManager. Kayıtlı bir yetenek fizik gerektirmediğinde nil olabilir.
- managerCtx.RootCFrame — Kök parçanın CFrame'i, çerçevenin başlangıcında bir kez anlık görüntü alınarak kaydedilir, böylece geri çağırmalar her biri kendileri almak zorunda kalmaz.
- managerCtx.RootLookVector — Karakterin kök parçasının baktığı yön.
- managerCtx.RootUpVectorY — Kök parçanın yukarı vektörünün Y bileşeni.
- managerCtx.TaskSynchronize() — Paralel geri çağırma desteği etkinleştirildiğinde, DataModel erişiminden önce bir geri çağırmayı senkronize eder. Şu anda, OnUpdate paralel bir bağlamda çalışmaz, bu nedenle bu fonksiyonun etkisi yoktur. Tam Paralel Luau desteği gelecekteki bir güncelleme için planlanmaktadır.
İkinci parametre, mevcut yetenek kaydı için motor tarafından yönetilen tablolar içeren bir AbilityContext nesnesidir:
- abilityCtx.Config — Bu yetenek kaydı için salt okunur yapılandırma değerleri.
- abilityCtx.State — DataModel üzerinden çoğaltılan değiştirilebilir durum. Sunucu Yetkisi bu değerleri geri alma ve yeniden simülasyon sırasında geri yükler.
- abilityCtx.Local — Çoğaltılmayan veya geri alma işlemine katılmayan değiştirilebilir geçici durum.
Özel geri çağırma verilerini abilityCtx.State veya abilityCtx.Local içinde saklayın. abilityCtx'ye doğrudan özel alanlar yazmak bir hatadır.