Karakter Kontrol Kütüphanesi (CCL), karakter hareketi ve davranışlarını nitelikler 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 ne 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 ne yapabileceğini ve oyuncu girdisine nasıl yanıt vermesi gerektiğini belirler.
Yapısal olarak, bir yetenek, esasen aşağıdakileri belirten kendi kendine yeterli bir Luau tablosudur:
| Tablo Alanları | Amaç |
|---|---|
| Name | Yeteneklerin benzersiz kimliği; koşullar ve çelişkiler adla referans verir. Aynı Name ile iki yetenek kaydetmek bir hata fırlatır. Benzer birkaç yetenek için, her birine farklı bir Name verin ve Labels içinde ortak bir etiket paylaşın. ModuleScript adı, 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. |
| StartsWhen, RunsWhile | Yeteneklerin ne zaman başlayacağını ve ne zaman çalışmaya devam edeceğini tanımlayan koşullar; koşullar için bakın. |
| Blocks, Stops, Suspends, ExclusiveGroup | Bir anda aktif olamayacak yetenekler arasındaki çelişkileri nasıl yöneteceğinizi tanımlar. |
| Input | Yetenekleri tetikleyen girdi. Input.Mode, girdinin yeteneği nasıl başlatıp durdurduğunu kontrol eder; RunsWhile yalnızca dünya koşullarını tutar, asla girdi kendisini değil; girdiler için bakın. |
| 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'den okur ve çoğaltılmış durumu abilityCtx.State aracılığıyla okur veya yazar. |
| OnSetup, OnStart, OnStop, OnUpdate, OnTeardown | Yeteneklerin gerçek davranışının betimlendiği yaşam döngüsü geri çağırmaları; geri çağırmalar için bakın. |
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 kurulumda, 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 FallingDown gerçekleşmeden önce "Stunned" etiketinin de 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şlatmak 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 | Etiketleri (anahtarları) ve ilişkili süreleri içeren sözlük. Yetenek başladığında etiket(ler) yayılır ve süreleri sona erdiğinde otomatik olarak sona erer. Örneğin, OnStart = { Dashing = 1 } yetenek başladığında Dashing etiketini 1 saniye yayar. |
| TimedLabels.OnStop | Etiketleri (anahtarları) ve ilişkili süreleri içeren sözlük. Yetenek durduğunda etiket(ler) yayılır ve süreleri sona erdiğinde otomatik olarak sona erer. Ö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üşü yok ve dize karşılaştırması yok.
| Hedef | 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 ve bir etiketin mevcut olmaması gerektiğini belirtmek için All() zincirleme artı Not():
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şamaz. 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 silahlarının dürbününden dikkatlice 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 yeteneği 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, tutucunun adı/etiketi hedef alan Stops tanımlarsa, öncelikten bağımsız olarak kazanır.
Aşağıdaki kurulumda, üç 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 koşmayı zorla durdurur (Stops = { Ability.Sprinting }), böylece Sprinting'i kesip geçebilir, önceliği (150) daha düşük olmasına rağmen.
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 onu 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 StartsWhen'e AND olarak ekler.
Mode, bu girdinin yeteneği nasıl başlatıp durdurduğunu tanımlar. RunsWhile asla girdi kendisini içermez; yalnızca dünya koşullarını tutar, örneğin yerde veya suda olma gibi, bu nedenle Mode, girdiyle tetiklenen başlatma ve durdurma için tek kaynaktır:
Mod Başlatır Girdiden Durdurur Press Basıldığında. Asla. Yetenek, bir çelişki, kendi RunsWhile'ı veya Stop() çağrısı aracılığıyla kendini sonlandırır. Hold Basıldığında. Serbest bırakıldığında. Hold ile Repeats Basıldığında. Serbest bırakma, yeniden ateş etmeyi sona erdirir, zaten uçuşta olan döngüyü değil. Toggle Açıldığında. Kapatıldığında. Press, dash, saldırı ve atma gibi ayrık eylemler için uygundur. Hold ve Toggle, sprint, nişan alma, blok yapma, çömelme ve havada durma gibi sürekli eylemler için uygundur. Hold ile Repeats, kendiliğinden durup basılı tutulduğunda yeniden ateş eden eylemler için uygundur, örneğin tekrar zıplama.
Repeats (boolean, yalnızca Hold) yeteneğin her döngüde kendini sonlandırmasını ve girdi basılı kaldıkça yeniden ateş etmesini sağlar, böylece sürekli olarak tüm süre boyunca çalışmaz.
OutlivesInputWhile (Hold/Toggle yalnızca) yeteneğin serbest bırakma veya kapatma sonrasında çalışmaya devam edeceği bir koşuldır; koşul temizlenene kadar durur. Bir yeteneğin belirli bir dünya koşulu altında girdisinden daha uzun sürmesi gerektiğinde kullanın.
ActionSlot, Girdi Eylem Sistemi içinde InputActions ve InputBindings listesi ile ilişkilendirilmiş bir eylem slotunu 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 durakladığında, aktif olduğunda veya kullanılamadığında dokunmatik düğme için Roblox varlık kimliklerini belirtir.
RunsWhile yalnızca dünya koşullarını tutar. Derleyici, girdinin etkisini yeteneğin gerçek devamına arka planda Mode'a göre oluşturur, bu nedenle girdi kendisini StartsWhen veya RunsWhile'a koymak bir hata fırlatır (orada Rule.Input'e referans vermeyin). Hold ve Toggle yetenekleri zaten serbest bırakıldığında veya kapatıldığında durur, bu nedenle bunu RunsWhile'da tekrarlamanıza gerek yoktur:
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 Glide: AvatarAbilities.AbilityDefinition = {
Name = "Glide",
Input = { InputName = "Glide", Mode = "Hold", ActionSlot = 6 },
StartsWhen = Not(Sensor.Ground),
RunsWhile = Not(Sensor.Ground),
}Bir Hold veya Toggle yeteneğinin girdisinden daha uzun sürmesini sağlamak için, RunsWhile'a girdi eklemek yerine OutlivesInputWhile'ı ayarlayın. Aşağıdaki Crouching yeteneği, oyuncu çömelme girdisini serbest bıraktığında çömelmeye devam eder, üstünde bir şey kaldığı sürece:
local AvatarAbilities = require("@rbx/AvatarAbilities")
local Identifiers = AvatarAbilities.Identifiers
local Sensor = Identifiers.Sensor
local Crouching: AvatarAbilities.AbilityDefinition = {
Name = "Crouching",
Input = { InputName = "Crouch", Mode = "Hold", OutlivesInputWhile = Sensor.Ceiling, ActionSlot = 3 },
RunsWhile = Sensor.Ground,
}Sensörler
Bir sensör, motorun sizin için okuduğu dünya hakkında adlandırılmış bir değerdir. Genellikle sensörleri okumak yerine yazarsınız. Kolaylık olması açısından, birkaç sensör önceden kaydedilmiştir:
| Sensör | Açıklama |
|---|---|
| Sensor.Ground | Bir yüzeyde durmak |
| Sensor.IsMoving | Hareket girişi uygulanıyor |
| Sensor.MoveInput | Hareket vektörü |
| Sensor.Ceiling | Üstte bir şey var |
| Sensor.Climb | Tırmanılabilir bir yüzey menzil içinde |
| Sensor.Water / Sensor.WaterSurface | Suda / yüzeyde |
| Sensor.Sit | Oturmakta |
| Sensor.Tipped | Yıkılmış |
| Sensor.Tool | Bir Tool tutmakta |
| 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 belirli bir 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ığı şeyleri 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öneticinin ö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 yalnızca okunabilir yapılandırma değerleri.
- abilityCtx.State — DataModel aracılığıyla ç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 — Geri alma veya 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.