Charaktersteuerungsbibliothek

*Dieser Inhalt wurde mit KI (Beta) übersetzt und kann Fehler enthalten. Um diese Seite auf Englisch zu sehen, klicke hier.

Die Charaktersteuerungsbibliothek (CCL) ist ein modulares Framework zum Erstellen von Charakterbewegungen und -verhalten durch Attribute und Luau-Skripte. Diese Architektur ersetzt starre Humanoid-Zustandsmaschinen durch ein flexibles, erweiterbares System für Charaktermechaniken.

CCL aktivieren

Die CCL ist optional über das Fenster Avatar-Einstellungen von Studio aktivierbar. Um sie zu aktivieren:

  1. Aktivieren Sie die CCL-Beta über Datei ⟩ Beta-Funktionen ⟩ AvatarAbilities Character Controller Library.

  2. Öffnen Sie im Tab Avatar die Avatar-Einstellungen.

    Avatar-Einstellungen im Toolbar von Studio angezeigt
  3. Wählen Sie den Tab Bewegung auf der linken Seite des Fensters und wählen Sie im Abschnitt Fähigkeiten die Character Controller Library aus.

    Umschalter für die Character Controller Library im Fenster Avatar-Einstellungen
  4. Alle Standardfähigkeiten wie Laufen, Springen und Klettern sind standardmäßig aktiviert. Um eine davon zur Laufzeit zu deaktivieren, deaktivieren Sie das entsprechende Kontrollkästchen.

Fähigkeiten

Fähigkeiten bewerten, was ein Charakter tun kann, wie die Fähigkeit zu rennen, zu springen, zu klettern und zu schwimmen. Anstatt sich auf eine feste Menge von vom Engine definierten Charakterzuständen wie die in Enum.HumanoidStateType zu verlassen, bestimmen CCL-Fähigkeiten dynamisch, was ein Charakter tun kann und wie er auf die Eingaben des Spielers reagieren sollte.

Strukturell ist eine Fähigkeit eine eigenständige Luau-Tabelle, die hauptsächlich Folgendes spezifiziert:

TabellenfelderZweck
NameDie einzigartige Identität der Fähigkeit; Bedingungen und Konflikte beziehen sich namentlich darauf. Das Registrieren von zwei Fähigkeiten mit demselben Name führt zu einem Fehler. Für einige ähnliche Fähigkeiten geben Sie jeder einen anderen Name und teilen sich ein gemeinsames Label in Labels. Der Name des ModuleScript bestimmt den einzigartigen Konfigurationsschlüssel.
Labels, TimedLabelsBenannte Bits in einer gemeinsamen 64-Bit-Maske, die als Koordinationsbus zwischen Fähigkeiten fungiert; siehe Labels.
StartsWhen, RunsWhileBedingungen, die definieren, wann die Fähigkeit gestartet werden soll und wann sie aktiv bleiben soll; siehe Bedingungen.
Blocks, Stops, Suspends, ExclusiveGroupWie mit Konflikten zwischen Fähigkeiten umgegangen wird, die nicht gleichzeitig aktiv sein können.
InputDie Eingabe, die die Fähigkeit auslöst. Input.Mode steuert, wie die Eingabe die Fähigkeit startet und stoppt; RunsWhile enthält nur Weltbedingungen, niemals die Eingabe selbst; siehe Eingaben.
Config, StateStandardkonfigurationswerte und replizierter Zustand für jede Fähigkeitsregistrierung. Rückrufe lesen die Konfiguration aus abilityCtx.Config und lesen oder schreiben den replizierten Zustand über abilityCtx.State.
OnSetup, OnStart, OnStop, OnUpdate, OnTeardownLebenszyklus-Rückrufe, in denen das tatsächliche Verhalten der Fähigkeit programmiert wird; siehe Rückrufe.

Labels

Ein Label ist ein benanntes Bit in einer gemeinsamen 64-Bit-Maske, die als Koordinationsbus zwischen Fähigkeiten fungiert. Im Wesentlichen:

  • Eine aktive Fähigkeit sendet ihre Labels und TimedLabels an die Weltmaske.
  • Die Bedingungen der Fähigkeit (StartsWhen, RunsWhile) testen die Weltmaske und reagieren.
  • Die Konflikte der Fähigkeit definieren, welche anderen Fähigkeiten beim Aktivieren blockiert, gestoppt oder ausgesetzt werden.

In der folgenden Konfiguration wird das Label "CanFallDown" an die Weltmaske gesendet, wenn Running aktiv ist. Die Fähigkeit FallingDown mit ihrer Bedingung von StartsWhen = All( "CanFallDown", "Stunned" ) wird automatisch zu einem Kandidaten, aber "Stunned" muss ebenfalls an die Weltmaske gesendet werden, bevor FallingDown auftritt.

Laufende Fähigkeit
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" }, -- Labels werden gesendet, wenn die Fähigkeit aktiv ist
StartsWhen = Sensor.Ground,
RunsWhile = Sensor.Ground,
}
FallingDown Fähigkeit
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" ), -- Labels, die notwendig sind, damit die Fähigkeit startet
Blocks = { Ability.Running }
}

Labels können auch auf eine zeitlich gesteuerte Weise gesendet oder konsumiert werden, indem das TimedLabels-Wörterbuch verwendet wird.

SchlüsselBeschreibung
TimedLabels.OnStartWörterbuch, das Labels (Schlüssel) und zugehörige Dauer enthält. Label(s) werden gesendet, wenn die Fähigkeit startet und laufen automatisch ab, wenn ihre Dauer endet. Zum Beispiel, OnStart = { Dashing = 1 } sendet das Dashing-Label für 1 Sekunde, wenn die Fähigkeit startet.
TimedLabels.OnStopWörterbuch, das Labels (Schlüssel) und zugehörige Dauer enthält. Label(s) werden gesendet, wenn die Fähigkeit stoppt und laufen automatisch ab, wenn ihre Dauer endet. Zum Beispiel, OnStop = { DashCooldown = 2 } sendet das DashCooldown-Label für 2 Sekunden, wenn die Fähigkeit stoppt.
TimedLabels.ConsumesListe von Labels, die entfernt (verbraucht) werden sollen, wenn die Fähigkeit aktiviert wird. Zum Beispiel, wenn ein Kampfspiel es Spielern erlaubt, nach dem Blocken eines Angriffs des Gegners einen Konterangriff auszuführen, könnte die CounterAttack-Fähigkeit sowohl StartsWhen = "AfterBlock" als auch TimedLabels = { Consumes = { "AfterBlock" } } enthalten, um eine doppelte Auslösung der CounterAttack-Fähigkeit zu verhindern.
Zeitlich gesteuerte Labels
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 },
},
}

Bedingungen

Eine Bedingung ist ein oder mehrere Labels, Sensoren oder ein Eingabeverweis, die von StartsWhen und RunsWhile verwendet werden. Bedingungen werden zur Laufzeit in Bitmaskenoperationen kompiliert und die Auswertung erfolgt in Ganzzahlen — keine Tabellenabfragen und keine Stringvergleiche.

ZielSyntaxBeispiel
Eine erforderliche Bedingung.StartsWhen = Sensor.Ground
UND-Logik für den Fall, dass alle Labels in der Weltmaske existieren und alle Sensoren aktiv sind.All()StartsWhen = All( "CanFallDown", "Stunned" )
ODER-Logik für den Fall, dass irgendeines der Labels in der Weltmaske existiert oder irgendeiner der Sensoren aktiv ist.Any()StartsWhen = Any( "WallClimbing", "Climbing" )
Negation, sodass die Labels nicht in der Weltmaske existieren können und die Sensoren nicht aktiv sein können.Not()RunsWhile = Not("Stunned")

Die bedingte Auswertung kann für komplexere Logik kombiniert werden, wie z.B. All()-Verkettungen plus Not(), um anzuzeigen, dass ein Sensor aktiv sein muss, während ein Label nicht vorhanden sein darf:

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") ),
}

Konflikte

Einige Fähigkeiten können nicht aktiv sein, wenn eine andere Fähigkeit aktiv ist; zum Beispiel können Charaktere nicht springen, während sie schwimmen, und sie können nicht rennen, während sie fallen. Die Engine löst diese Konflikte deklarativ innerhalb der Definition einer Fähigkeit:

KonfliktschlüsselZweck
BlocksWährend die besitzende Fähigkeit aktiv ist, können die aufgeführten anderen Fähigkeiten nicht gestartet werden. Zum Beispiel könnte eine ScopeAim-Fähigkeit Blocks = { Ability.Running, Ability.Jumping } enthalten, um zu verhindern, dass Charaktere während des sorgfältigen Zielens durch das Visier ihrer Waffe rennen oder springen.
StopsWenn die besitzende Fähigkeit startet, werden die aufgeführten anderen Fähigkeiten sofort gestoppt und müssen erneut ausgelöst werden. Zum Beispiel könnte eine Hover-Fähigkeit Stops = { Ability.Running } enthalten, um die Laufbewegung eines Charakters sofort zu stoppen, wenn er zu schweben beginnt.
SuspendsWenn die besitzende Fähigkeit startet, pausieren die aufgeführten anderen Fähigkeiten und setzen sich automatisch fort, wenn die besitzende Fähigkeit stoppt. Zum Beispiel könnte eine benutzerdefinierte Sprintfähigkeit Suspends = { Ability.Running } enthalten, sodass das Laufen 🄐 beim Sprintstart pausiert, 🄑 während des Sprints blockiert wird und 🄒 beim Sprintstopp fortgesetzt wird.

Ein weiterer einzigartiger Konfliktschlüssel ist ExclusiveGroup, der mehrere Fähigkeiten in eine Gruppe einordnet, wobei jede einen Priority-Wert hat. Nur eine Fähigkeit pro Gruppe kann aktiv sein, und die höhere Priorität gewinnt. Wenn ein Herausforderer jedoch Stops erklärt, das auf den Namen/Label des Halters abzielt, gewinnt es unabhängig von der Priorität.

In der folgenden Konfiguration werden drei Fähigkeiten (Sprinting, Crouching, Stagger) zu einer exklusiven Gruppe Locomotion hinzugefügt. Sprinting hat die höchste Priorität (200), sodass es über Crouching (100) gewinnt und die beiden niemals gleichzeitig aktiv sind. Stagger stoppt jedoch das Sprinten gewaltsam (Stops = { Ability.Sprinting }), sodass es Sprinting unterbrechen und übertreffen kann, obwohl seine Priorität (150) niedriger ist.

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 },
}
-- Eine Fähigkeit mit niedrigerer Priorität kann eine Fähigkeit mit höherer Priorität durch das Stoppen übersteuern
local Stagger: AvatarAbilities.AbilityDefinition = {
Name = "Stagger",
ExclusiveGroup = { Name = "Locomotion", Priority = 150 },
Stops = { Ability.Sprinting },
}

Eingaben

Die Input-Definition einer Fähigkeit spezifiziert die Eingabe, die verwendet wird, um zu versuchen, die Fähigkeit zu aktivieren. Sie nimmt Schlüssel-Wert-Paare an, die das Eingabeverhalten, den Aktionsslot und optionale Touch-Button-Icons konfigurieren.

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 ist ein logischer Name, kein Schlüssel. Die CCL generiert einen Eingabesensor und fügt ihn immer in StartsWhen ein.

  • Mode definiert, wie diese Eingabe die Fähigkeit startet und stoppt. RunsWhile enthält niemals die Eingabe selbst; es enthält nur Weltbedingungen, wie z.B. auf dem Boden oder im Wasser zu sein, sodass Mode die einzige Quelle für eingabegesteuertes Starten und Stoppen ist:

    ModusStartetStoppt von Eingabe
    PressBei Druck.Nie. Die Fähigkeit endet selbst durch einen Konflikt, ihre eigene RunsWhile oder durch den Aufruf von Stop().
    HoldBei Druck.Bei Freigabe.
    Hold mit RepeatsBei Druck.Die Freigabe beendet das erneute Auslösen, nicht den bereits in der Luft befindlichen Zyklus.
    ToggleBei Umschalten ein.Bei Umschalten aus.

    Press eignet sich für diskrete Aktionen wie Dash, Angriff und Wurf. Hold und Toggle eignen sich für anhaltende Aktionen wie Sprinten, Zielen, Blocken, Hocken und Schwebens. Hold mit Repeats eignet sich für Aktionen, die sich selbst stoppen und erneut auslösen, während sie gehalten werden, wie z.B. wiederholtes Springen.

  • Repeats (boolean, nur Hold) lässt die Fähigkeit bei jedem Zyklus selbst enden und erneut auslösen, während die Eingabe gehalten wird, anstatt kontinuierlich während des gesamten Haltens zu laufen.

  • OutlivesInputWhile (nur Hold/Toggle) ist eine Bedingung, unter der die Fähigkeit über die Freigabe oder das Umschalten hinaus aktiv bleibt, bis die Bedingung erfüllt ist. Verwenden Sie es, wenn eine Fähigkeit länger als ihre Eingabe unter einer bestimmten Weltbedingung bestehen bleiben soll.

  • ActionSlot definiert einen Aktionsslot, der mit einer Liste von InputActions und InputBindings innerhalb des Input Action Systems verknüpft ist.

    Mehrere Aktionsslot-Eingabebindungen sind von Roblox vordefiniert, und in Zukunft wird der Input Action Manager es Ihnen ermöglichen, die Standard-Eingabebindungen für Aktionsslots nach Belieben neu zu konfigurieren. Das Setzen von ActionSlot auf 0 wählt den nächstverfügbaren leeren Slot aus. Auf mobilen Geräten füllen die Slots 1-7 die Tasten auf dem Bildschirm (siehe Diagramm unten).

    SlotTastatur & MausGamepadBerührungStandardzuweisung
    1SpaceButtonA①Springen
    2LeftShiftButtonL1②Sprinten
    3LeftControlButtonB③Hocken
    4RButtonX④
    5MouseLeftButtonButtonR2⑤
    6QButtonY⑥
    7XButtonR1⑦
    8CButtonL2
    9FDPadLeft
    10GDPadRight
    11VDPadDown
  • CustomIcon, CustomIconActive und CustomIconInvalid geben Roblox-Asset-IDs für die Touch-Schaltfläche an, wenn die Fähigkeit inaktiv, aktiv oder nicht verfügbar ist.

RunsWhile enthält nur Weltbedingungen. Der Compiler fügt die Wirkung der Eingabe hinter den Kulissen in die tatsächliche Fortsetzung der Fähigkeit ein, basierend auf Mode, sodass das Einfügen der Eingabe selbst in StartsWhen oder RunsWhile einen Fehler auslöst (verweisen Sie dort nicht auf Rule.Input). Hold- und Toggle-Fähigkeiten stoppen bereits standardmäßig bei Freigabe oder Umschalten, sodass Sie dies nicht in RunsWhile duplizieren müssen:

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),
}

Um eine Hold- oder Toggle-Fähigkeit zu erstellen, die ihre Eingabe unter einer Weltbedingung überdauert, setzen Sie OutlivesInputWhile, anstatt die Eingabe zu RunsWhile hinzuzufügen. Die folgende Crouching-Fähigkeit bleibt hockend, nachdem der Spieler die Hockeingabe freigibt, solange sich etwas über ihm befindet:

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,
}

Sensoren

Ein Sensor ist ein benannter Wert über die Welt, den die Engine für Sie liest. Sie lesen normalerweise Sensoren, anstatt sie zu schreiben. Zur Vereinfachung sind mehrere Sensoren vorregistriert:

SensorBeschreibung
Sensor.GroundAuf einer Oberfläche stehen
Sensor.IsMovingBewegungseingabe wird angewendet
Sensor.MoveInputDer Bewegungsvektor selbst
Sensor.CeilingEtwas ist direkt über Kopf
Sensor.ClimbEine kletterbare Oberfläche ist in Reichweite
Sensor.Water / Sensor.WaterSurfaceIm Wasser / an der Oberfläche
Sensor.SitGesessen
Sensor.TippedUmgefallen
Sensor.ToolHält ein Tool
Sensor.LookDirectionInputDie angegebene Blickrichtung
Sensor.RotateToLookDirectionInputOb der Charakter sich in die angegebene Blickrichtung drehen soll

Rückrufe

Fähigkeits-Rückruffunktionen ermöglichen es Ihnen, spezifisches Verhalten zu programmieren:

Obwohl Sie benutzerdefinierte Fähigkeiten auf dem Server registrieren, werden ihre Rückrufe sowohl in der vorhergesagten Client-Simulation als auch in der autoritativen Server-Simulation ausgeführt. Halten Sie das Rückrufverhalten deterministisch, damit beide Simulationen dasselbe Ergebnis produzieren.

RückrufWird ausgeführtAnwendungsfälle
OnSetup(managerCtx, abilityCtx)Einmal, wenn die Fähigkeit registriert wird.Referenzen cachen, Zustand initialisieren usw.
OnStart(managerCtx, abilityCtx, hadLabel)Jedes Mal, wenn die Fähigkeit aktiviert wird.Wenden Sie einen Effekt wie einen Impuls an. Die Funktion hadLabel() gibt an, ob ein bestimmtes Label vorhanden war, als die Aktivierung begann, bevor die Konfliktlösung erfolgt.
OnUpdate(managerCtx, abilityCtx)Jeden aktiven Frame.Kontinuierliche Arbeiten wie Timer oder pro-Frame Kräfte.
OnStop(managerCtx, abilityCtx)Jede Deaktivierung, freiwillig oder erzwungen.Was OnStart() getan hat, rückgängig machen.
OnTeardown(managerCtx, abilityCtx)Bei der Entfernung der Fähigkeit.Verbindungen trennen, Instanzen zerstören usw.

Jeder Rückrufparameter managerCtx ist ein ManagerContext-Objekt mit gemeinsamen Charakter- und Manager-Eigenschaften, einschließlich:

  • managerCtx.AbilityOwner — Das Charakter-Model, sodass managerCtx.AbilityOwner.PrimaryPart das Wurzelteil ist.
  • managerCtx.AbilityManager — Eine reduzierte Ansicht des Managers, sodass eine Fähigkeit Fähigkeiten von innen heraus hinzufügen, entfernen und abfragen kann.
  • managerCtx.BodyParts — Die Körperteile des Charakters, mit Hilfsfunktionen zum Ein- und Ausschalten von Kollisionen pro Glied.
  • managerCtx.ControllerManager — Der ControllerManager des Charakters für die physikalische Steuerung. Es kann nil sein, wenn keine registrierte Fähigkeit Physik erfordert.
  • managerCtx.RootCFrame — Der CFrame des Wurzelteils, einmal zu Beginn des Frames aufgenommen, sodass Rückrufe nicht selbst danach suchen müssen.
  • managerCtx.RootLookVector — Richtung, in die das Wurzelteil des Charakters zeigt.
  • managerCtx.RootUpVectorY — Die Y-Komponente des Aufwärtsvektors des Wurzelteils.
  • managerCtx.TaskSynchronize() — Synchronisiert einen Rückruf vor dem Zugriff auf das DataModel, wenn die Unterstützung für parallele Rückrufe aktiviert ist. Derzeit wird OnUpdate nicht in einem parallelen Kontext ausgeführt, sodass diese Funktion keine Auswirkungen hat. Vollständige parallele Luau-Unterstützung ist für ein zukünftiges Update geplant.

Der zweite Parameter, abilityCtx, ist ein AbilityContext-Objekt mit vom Engine verwalteten Tabellen für die aktuelle Fähigkeitsregistrierung:

  • abilityCtx.Config — Nur-Lese-Konfigurationswerte für diese Fähigkeitsregistrierung.
  • abilityCtx.State — Änderbarer Zustand, der durch das DataModel repliziert wird. Server Authority stellt diese Werte während eines Rollbacks und einer Neusimulation wieder her.
  • abilityCtx.Local — Änderbarer Scratch-Zustand, der nicht repliziert oder am Rollback teilnimmt.

Speichern Sie benutzerdefinierte Rückrufdaten in abilityCtx.State oder abilityCtx.Local. Das direkte Schreiben benutzerdefinierter Felder in abilityCtx ist ein Fehler.

©2026 Roblox Corporation. Roblox, das Roblox-Logo und "Powering Imagination" gehören zu unseren eingetragenen und nicht eingetragenen Markenzeichen in den USA und anderen Ländern.