Biblioteca del Controlador de Personajes

*Este contenido se traduce usando la IA (Beta) y puede contener errores. Para ver esta página en inglés, haz clic en aquí.

La Biblioteca del Controlador de Personajes (CCL) es un marco modular para construir el movimiento y comportamientos de personajes a través de atributos y scripts de Luau. Esta arquitectura reemplaza las máquinas de estado rígidas de Humanoid con un sistema flexible y extensible para la mecánica de personajes.

Habilitar CCL

El CCL es opcional a través de la ventana de Configuración de Avatar de Studio. Para habilitarlo:

  1. Habilita la beta del CCL a través de Archivo ⟩ Funciones Beta ⟩ Biblioteca de Controladores de Personajes de Avatar.

  2. Desde la pestaña Avatar, abre Configuración de Avatar.

    Configuración de Avatar indicada en la barra de herramientas de Studio
  3. Selecciona la pestaña Movimiento en el lado izquierdo de la ventana y, en la sección Habilidades, selecciona Biblioteca de Controladores de Personajes.

    Interruptor de Biblioteca de Controladores de Personajes en la ventana de Configuración de Avatar
  4. Todas las habilidades estándar como Correr, Saltar y Escalar están habilitadas por defecto. Para deshabilitar cualquiera de ellas en tiempo de ejecución, desmarca la casilla asociada.

Habilidades

Las habilidades evalúan lo que un personaje puede hacer, como la capacidad de correr, saltar, escalar y nadar. En lugar de depender de un conjunto fijo de estados de personaje definidos por el motor, como los de Enum.HumanoidStateType, las habilidades de CCL determinan dinámicamente lo que un personaje puede hacer y cómo debe responder a la entrada del jugador.

Estructuralmente, una habilidad es una tabla de Luau autocontenida que especifica principalmente lo siguiente:

Campos de la TablaPropósito
NameLa identidad única de la habilidad; condiciones y conflictos la referencian por nombre. Registrar dos habilidades con el mismo Name genera un error. Para algunas habilidades similares, dale a cada una un Name diferente y comparte una etiqueta común en Labels. El nombre del ModuleScript determina la clave de configuración única.
Labels, TimedLabelsBits nombrados en una máscara compartida de 64 bits que actúa como el bus de coordinación entre habilidades; ver etiquetas.
StartsWhen, RunsWhileCondiciones que definen cuándo iniciar la habilidad y cuándo mantenerla activa, respectivamente; ver condiciones.
Blocks, Stops, Suspends, ExclusiveGroupCómo manejar conflictos entre habilidades que no pueden estar activas al mismo tiempo.
InputLa entrada que activa la habilidad. Input.Mode controla cómo la entrada inicia y detiene la habilidad; RunsWhile solo contiene condiciones del mundo, nunca la entrada misma; ver entradas.
Config, StateValores de configuración predeterminados y estado replicado para cada registro de habilidad. Los callbacks leen la configuración de abilityCtx.Config y leen o escriben el estado replicado a través de abilityCtx.State.
OnSetup, OnStart, OnStop, OnUpdate, OnTeardownCallbacks del ciclo de vida donde se scriptan el comportamiento real de la habilidad; ver callbacks.

Etiquetas

Una etiqueta es un bit nombrado en una máscara compartida de 64 bits que actúa como el bus de coordinación entre habilidades. Esencialmente:

  • Una habilidad activa transmite sus Labels y TimedLabels a la máscara del mundo.
  • Las condiciones de la habilidad (StartsWhen, RunsWhile) prueban la máscara del mundo y reaccionan.
  • Los conflictos de la habilidad definen qué otras habilidades están bloqueadas, detenidas o suspendidas al activarse.

En la siguiente configuración, la etiqueta "CanFallDown" se transmite a la máscara del mundo cuando Running está activa. La habilidad FallingDown con su condición de StartsWhen = All( "CanFallDown", "Stunned" ) se convierte automáticamente en una candidata, pero "Stunned" también debe ser transmitida a la máscara del mundo antes de que ocurra FallingDown.

Habilidad de Correr
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" }, -- Etiquetas transmitidas cuando la habilidad está activa
StartsWhen = Sensor.Ground,
RunsWhile = Sensor.Ground,
}
Habilidad de Caer
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" ), -- Etiquetas necesarias para que la habilidad comience
Blocks = { Ability.Running }
}

Las etiquetas también pueden ser transmitidas o consumidas de manera temporal utilizando el diccionario TimedLabels.

ClaveDescripción
TimedLabels.OnStartDiccionario que contiene etiquetas (claves) y duraciones asociadas. La(s) etiqueta(s) se transmiten cuando la habilidad comienza y expiran automáticamente cuando su duración termina. Por ejemplo, OnStart = { Dashing = 1 } transmite la etiqueta Dashing durante 1 segundo cuando la habilidad comienza.
TimedLabels.OnStopDiccionario que contiene etiquetas (claves) y duraciones asociadas. La(s) etiqueta(s) se transmiten cuando la habilidad se detiene y expiran automáticamente cuando su duración termina. Por ejemplo, OnStop = { DashCooldown = 2 } transmite la etiqueta DashCooldown durante 2 segundos cuando la habilidad se detiene.
TimedLabels.ConsumesLista de etiquetas para eliminar (consumir) cuando la habilidad se activa. Por ejemplo, si un juego de lucha permite a los jugadores contraatacar después de bloquear un ataque del oponente, la habilidad CounterAttack puede contener tanto StartsWhen = "AfterBlock" como TimedLabels = { Consumes = { "AfterBlock" } } para evitar la activación doble de la habilidad CounterAttack.
Etiquetas Temporales
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 },
},
}

Condiciones

Una condición es una o más etiquetas, sensores o una referencia de entrada, utilizadas por StartsWhen y RunsWhile. Las condiciones se compilan en operaciones de bitmask en tiempo de ejecución y la evaluación es matemáticas enteras — sin recorridos de tablas y sin comparaciones de cadenas.

ObjetivoSintaxisEjemplo
Una condición requerida.StartsWhen = Sensor.Ground
Logica AND para cuando todas las etiquetas existen en la máscara del mundo y todos los sensores están activos.All()StartsWhen = All( "CanFallDown", "Stunned" )
Logica OR para cuando cualquiera de las etiquetas existe en la máscara del mundo o cualquiera de los sensores está activo.Any()StartsWhen = Any( "WallClimbing", "Climbing" )
Negación de tal manera que las etiquetas no pueden existir en la máscara del mundo y los sensores no pueden estar activos.Not()RunsWhile = Not("Stunned")

La evaluación condicional se puede combinar para una lógica más compleja, como encadenar All() más Not() para indicar que un sensor debe estar activo mientras que una etiqueta debe no existir:

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

Conflictos

Algunas habilidades no pueden estar activas cuando otra habilidad lo está; por ejemplo, los personajes no pueden saltar mientras nadan, y no pueden correr mientras caen. El motor resuelve estos conflictos de manera declarativa dentro de la definición de una habilidad:

Clave de ConflictoPropósito
BlocksMientras la habilidad propietaria esté activa, las otras habilidades listadas no pueden comenzar. Por ejemplo, una habilidad ScopeAim podría contener Blocks = { Ability.Running, Ability.Jumping } para evitar que los personajes corran o salten mientras apuntan cuidadosamente a través de la mira de su arma.
StopsCuando la habilidad propietaria comienza, las otras habilidades listadas se detienen forzosamente y deben volver a activarse. Por ejemplo, una habilidad Hover podría contener Stops = { Ability.Running } para detener inmediatamente el movimiento de carrera de un personaje cuando comienza a flotar.
SuspendsCuando la habilidad propietaria comienza, las otras habilidades listadas se pausan y luego se reanudan automáticamente cuando la habilidad propietaria se detiene. Por ejemplo, una habilidad de sprint personalizada podría contener Suspends = { Ability.Running } para que correr 🄐 se pause al iniciar el sprint, 🄑 se bloquee durante el sprint, y 🄒 se reanude al detener el sprint.

Otra clave de conflicto única es ExclusiveGroup que coloca múltiples habilidades en un grupo, cada una con un valor de Priority. Solo una habilidad por grupo puede estar activa y la de mayor prioridad gana. Sin embargo, si un retador declara Stops apuntando al nombre/etiqueta del poseedor, gana independientemente de la prioridad.

En la siguiente configuración, tres habilidades (Sprinting, Crouching, Stagger) se añaden a un grupo exclusivo Locomotion. Sprinting tiene la mayor prioridad (200) por lo que gana sobre Crouching (100) y las dos nunca se ejecutan al mismo tiempo. Sin embargo, Stagger detiene forzosamente el sprint (Stops = { Ability.Sprinting }), por lo que puede interrumpir y superar a Sprinting a pesar de que su prioridad (150) es más baja.

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 },
}
-- Una habilidad de menor prioridad puede anular una habilidad de mayor prioridad al detenerla
local Stagger: AvatarAbilities.AbilityDefinition = {
Name = "Stagger",
ExclusiveGroup = { Name = "Locomotion", Priority = 150 },
Stops = { Ability.Sprinting },
}

Entradas

La definición de Input de una habilidad especifica la entrada utilizada para intentar activar la habilidad. Toma pares clave-valor que configuran el comportamiento de entrada, el slot de acción y los íconos de botón táctil opcionales.

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 es un nombre lógico, no una clave. La CCL genera un sensor de entrada y siempre lo ANDa en StartsWhen.

  • Mode define cómo esta entrada inicia y detiene la habilidad. RunsWhile nunca contiene la entrada misma; solo contiene condiciones del mundo, como estar en el suelo o en el agua, por lo que Mode es la única fuente de inicio y detención impulsada por la entrada:

    ModoIniciaDetiene Desde la Entrada
    PressAl presionar.Nunca. La habilidad se termina a sí misma a través de un conflicto, su propio RunsWhile, o llamando a Stop().
    HoldAl presionar.Al soltar.
    Hold con RepeatsAl presionar.El soltar termina el re-disparo, no el ciclo ya en vuelo.
    ToggleAl activar.Al desactivar.

    Press es adecuado para acciones discretas como dash, ataque y lanzamiento. Hold y Toggle son adecuados para acciones sostenidas como sprint, apuntar, bloquear, agacharse y levitar. Hold con Repeats es adecuado para acciones que se detienen solas y se re-disparan mientras se mantienen, como saltos repetidos.

  • Repeats (booleano, solo Hold) hace que la habilidad se termine a sí misma en cada ciclo y se re-dispare mientras la entrada se mantenga, en lugar de ejecutarse continuamente durante toda la duración de la presión.

  • OutlivesInputWhile (solo Hold/Toggle) es una condición bajo la cual la habilidad sigue funcionando más allá de la liberación o desactivación, deteniéndose una vez que la condición se despeja. Úsalo cuando una habilidad deba durar más que su entrada bajo una condición del mundo específica.

  • ActionSlot define un slot de acción que está asociado con una lista de InputActions y InputBindings dentro del Sistema de Acción de Entrada.

    Varios vínculos de entrada de ranura de acción están predefinidos por Roblox y, en el futuro, el Administrador de Acciones de Entrada te permitirá reconfigurar los vínculos de entrada predeterminados para las ranuras de acción según desees. Establecer ActionSlot en 0 elegirá la siguiente ranura vacía disponible. En dispositivos móviles, las ranuras 1-7 se llenan con botones en la pantalla (ver diagrama a continuación).

    RanuraTeclado y RatónControladorTáctilAsignación Predeterminada
    1SpaceButtonA①Saltar
    2LeftShiftButtonL1②Correr
    3LeftControlButtonB③Agacharse
    4RButtonX④
    5MouseLeftButtonButtonR2⑤
    6QButtonY⑥
    7XButtonR1⑦
    8CButtonL2
    9FDPadLeft
    10GDPadRight
    11VDPadDown
  • CustomIcon, CustomIconActive y CustomIconInvalid especifican IDs de activos de Roblox para el botón táctil cuando la habilidad está inactiva, activa o no disponible, respectivamente.

RunsWhile solo contiene condiciones del mundo. El compilador compone el efecto de la entrada en la continuación real de la habilidad detrás de escena basado en Mode, por lo que poner la entrada misma en StartsWhen o RunsWhile genera un error (no referencies Rule.Input allí). Las habilidades Hold y Toggle ya se detienen al soltar o desactivar por defecto, por lo que no necesitas duplicar eso en RunsWhile:

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

Para hacer que una habilidad Hold o Toggle dure más que su entrada bajo una condición del mundo, establece OutlivesInputWhile en lugar de agregar la entrada a RunsWhile. La siguiente habilidad Crouching mantiene la posición agachada después de que el jugador libera la entrada de agacharse, siempre que algo permanezca por encima:

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

Sensores

Un sensor es un valor nombrado sobre el mundo que el motor lee por ti. Normalmente leerás sensores en lugar de escribirlos. Para conveniencia, varios sensores están pre-registrados:

SensorDescripción
Sensor.GroundDe pie sobre una superficie
Sensor.IsMovingSe está aplicando entrada de movimiento
Sensor.MoveInputEl vector de movimiento en sí
Sensor.CeilingAlgo está directamente encima
Sensor.ClimbUna superficie escalable está al alcance
Sensor.Water / Sensor.WaterSurfaceEn el agua / en la superficie
Sensor.SitSentado
Sensor.TippedSe ha caído
Sensor.ToolSosteniendo un Tool
Sensor.LookDirectionInputLa dirección de mirada ordenada
Sensor.RotateToLookDirectionInputSi el personaje debe rotar hacia la dirección de mirada ordenada

Callbacks

Las funciones de callback de habilidad te permiten scriptar comportamientos específicos:

Aunque registras habilidades personalizadas en el servidor, sus callbacks se ejecutan tanto en la simulación del cliente predicha como en la simulación del servidor autoritativa. Mantén el comportamiento de los callbacks determinista para que ambas simulaciones produzcan el mismo resultado.

CallbackSe EjecutaCasos de Uso
OnSetup(managerCtx, abilityCtx)Una vez, cuando la habilidad es registrada.Cachear referencias, inicializar estado, etc.
OnStart(managerCtx, abilityCtx, hadLabel)Cada vez que se activa la habilidad.Aplicar un efecto como un impulso. La función hadLabel() informa si una etiqueta específica estaba presente cuando comenzó la activación, antes de la resolución de conflictos.
OnUpdate(managerCtx, abilityCtx)Cada cuadro activo.Trabajo continuo como temporizadores o fuerzas por cuadro.
OnStop(managerCtx, abilityCtx)Cada desactivación, voluntaria o forzada.Deshacer lo que hizo OnStart().
OnTeardown(managerCtx, abilityCtx)Al eliminar la habilidad.Desconectar conexiones, destruir instancias, etc.

El primer parámetro de cada función de callback, managerCtx, es un objeto ManagerContext con propiedades compartidas de personaje y administrador, incluyendo:

  • managerCtx.AbilityOwner — El Model del personaje tal que managerCtx.AbilityOwner.PrimaryPart es la parte raíz.
  • managerCtx.AbilityManager — Una vista reducida del administrador para que una habilidad pueda agregar, eliminar y consultar habilidades desde dentro de sus propios callbacks.
  • managerCtx.BodyParts — Las partes del cuerpo del personaje, con ayudantes para activar y desactivar la colisión por extremidad.
  • managerCtx.ControllerManager — El ControllerManager del personaje para el control de física. Puede ser nil cuando ninguna habilidad registrada requiere física.
  • managerCtx.RootCFrame — El CFrame de la parte raíz, capturado una vez al inicio del cuadro para que los callbacks no tengan que buscarlo cada uno por su cuenta.
  • managerCtx.RootLookVector — Dirección en la que está mirando la parte raíz del personaje.
  • managerCtx.RootUpVectorY — El componente Y del vector hacia arriba de la parte raíz.
  • managerCtx.TaskSynchronize() — Sincroniza un callback antes del acceso al DataModel cuando el soporte de callbacks paralelos está habilitado. Actualmente, OnUpdate no se ejecuta en un contexto paralelo, por lo que esta función no tiene efecto. Se planea soporte completo de Luau paralelo para una futura actualización.

El segundo parámetro, abilityCtx, es un objeto AbilityContext con tablas gestionadas por el motor para el registro actual de la habilidad:

  • abilityCtx.Config — Valores de configuración de solo lectura para este registro de habilidad.
  • abilityCtx.State — Estado mutable que se replica a través del DataModel. La Autoridad del Servidor restaura estos valores durante la reversión y la re-simulación.
  • abilityCtx.Local — Estado mutable temporal que no se replica ni participa en la reversión.

Almacena datos personalizados de callback en abilityCtx.State o abilityCtx.Local. Es un error escribir campos personalizados directamente en abilityCtx.

©2026 Roblox Corporation. Roblox, el logotipo de Roblox y "Powering Imagination" son algunas de nuestras marcas registradas y no registradas en los Estados Unidos y otros países.