roblox-characters
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseRoblox characters
Roblox 角色
Treat a as the durable identity and each as a replaceable session with its own
references, connections, animation tracks, and cleanup. Targets Roblox's rolling platform APIs.
PlayerCharacter将 视为持久身份,而每个 都是可替换的会话,拥有独立的引用、连接、动画轨道和清理逻辑。本文档针对 Roblox 滚动更新的平台 API 编写。
PlayerCharacterWhen to use
适用场景
- Use for player-character lifecycle, Humanoid state/movement, rigs, animations, tools, accessories, custom characters, death, or respawn defects.
- Use whenever code stores a Character/Humanoid/root reference longer than one spawn.
When not to use: general physics queries and constraints belong to ; remote
trust belongs to ; camera logic belongs to .
roblox-physicsroblox-networkingcamera-systems- 适用于玩家角色生命周期、Humanoid 状态/移动、rigs、动画、工具、配饰、自定义角色、死亡或重生相关问题的场景。
- 当代码存储 Character/Humanoid/根节点引用的时长超过一次生成周期时使用。
不适用场景: 通用物理查询与约束属于 范畴;远程信任相关内容属于 ;相机逻辑属于 。
roblox-physicsroblox-networkingcamera-systemsWorkflow
工作流程
- Inspect the character contract. Check avatar settings, ,
StarterCharacter,StarterCharacterScripts, R6/R15 support, existing Animate/controller scripts, tools, tags, collision groups, and server/client ownership.CharacterAutoLoads - Separate scopes. Player-scope state survives respawn; character-scope state does not. Put character connections/tracks/resources in one cleanup scope and destroy it on removal.
- Bind existing and future characters. Connect , then bind
CharacterAddedif present. Do not assume event subscription alone sees a character that already spawned.player.Character - Resolve required components defensively. Wait with a timeout where replication warrants it;
validate , root,
Humanoid, and rig assumptions. Abort if that character is no longer current before applying delayed work.Animator - Choose movement ownership. Use Humanoid movement for standard avatars; use
,
AssemblyLinearVelocity, or aBasePart:ApplyImpulse()/LinearVelocityconstraint only for mechanics that need physical control. Keep gameplay authority and network ownership implications explicit.AlignPosition - Own animation lifecycle. Load via the rig's ; store tracks/connections; use named markers for gameplay timing only with server validation; stop/disconnect on character cleanup.
Animator - Verify lifecycle stress. Spawn, die, reset, rapid-respawn, swap rig if supported, equip/drop tools, leave during setup, and run with at least two players when character interactions matter.
- 检查角色约定。 检查 avatar 设置、、
StarterCharacter、StarterCharacterScripts、R6/R15 支持、现有的 Animate/控制器脚本、工具、标签、碰撞组以及服务端/客户端所有权。CharacterAutoLoads - 分离作用域。 玩家作用域的状态在重生后仍然保留;角色作用域的状态则不会。将角色的连接/轨道/资源放在同一个清理作用域中,并在角色移除时销毁该作用域。
- 绑定现有和未来的角色。 连接 事件,然后如果
CharacterAdded已存在则绑定它。不要认为仅通过事件订阅就能捕获到已经生成的角色。player.Character - 防御式解析所需组件。 在需要复制的场景下使用带超时的等待;验证 、根节点、
Humanoid以及 rig 假设是否成立。在执行延迟工作前,如果该角色已不再是当前角色,则中止操作。Animator - 选择移动控制权。 标准 avatar 使用 Humanoid 移动;仅在需要物理控制的机制中使用 、
AssemblyLinearVelocity或BasePart:ApplyImpulse()/LinearVelocity约束。明确游戏玩法的权威归属以及网络所有权的影响。AlignPosition - 掌控动画生命周期。 通过 rig 的 加载动画;存储轨道/连接;仅在服务端验证的前提下,将命名标记用于游戏玩法计时;在角色清理时停止动画/断开连接。
Animator - 验证生命周期压力场景。 测试生成、死亡、重置、快速重生、(如支持)切换 rig、装备/丢弃工具、在设置过程中离开等场景,并且在涉及角色交互时至少用两名玩家进行测试。
Pattern: replaceable character scope
模式:可替换角色作用域
lua
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local generation = 0
local connections: {RBXScriptConnection} = {}
local currentCharacter: Model? = nil
local function clearCharacter()
generation += 1
for _, connection in connections do connection:Disconnect() end
table.clear(connections)
currentCharacter = nil
end
local function bindCharacter(character: Model)
-- Guard BEFORE teardown. A stale invocation (see the CharacterAdded/defer race below) must not
-- clear a binding that is already current, or nothing ends up bound at all.
if player.Character ~= character then return end
clearCharacter()
currentCharacter = character
local thisGeneration = generation
local humanoid = character:WaitForChild("Humanoid", 10)
local root = character:WaitForChild("HumanoidRootPart", 10)
-- Re-check after the yields: a respawn during WaitForChild bumps generation and makes this call stale.
if not humanoid or not root or generation ~= thisGeneration then return end
table.insert(connections, humanoid.Died:Connect(function()
if generation ~= thisGeneration then return end
setCharacterUiEnabled(false)
end))
attachCurrentCharacterSystems(character, humanoid, root)
end
player.CharacterRemoving:Connect(function(character)
if currentCharacter == character then clearCharacter() end
end)
player.CharacterAdded:Connect(bindCharacter)
if player.Character then task.defer(bindCharacter, player.Character) endUse the project's cleanup utility when one exists; do not introduce a new framework for three
connections. Server systems repeat this binding per and clear player-scope tables on
.
PlayerPlayerRemovinglua
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local generation = 0
local connections: {RBXScriptConnection} = {}
local currentCharacter: Model? = nil
local function clearCharacter()
generation += 1
for _, connection in connections do connection:Disconnect() end
table.clear(connections)
currentCharacter = nil
end
local function bindCharacter(character: Model)
-- Guard BEFORE teardown. A stale invocation (see the CharacterAdded/defer race below) must not
-- clear a binding that is already current, or nothing ends up bound at all.
if player.Character ~= character then return end
clearCharacter()
currentCharacter = character
local thisGeneration = generation
local humanoid = character:WaitForChild("Humanoid", 10)
local root = character:WaitForChild("HumanoidRootPart", 10)
-- Re-check after the yields: a respawn during WaitForChild bumps generation and makes this call stale.
if not humanoid or not root or generation ~= thisGeneration then return end
table.insert(connections, humanoid.Died:Connect(function()
if generation ~= thisGeneration then return end
setCharacterUiEnabled(false)
end))
attachCurrentCharacterSystems(character, humanoid, root)
end
player.CharacterRemoving:Connect(function(character)
if currentCharacter == character then clearCharacter() end
end)
player.CharacterAdded:Connect(bindCharacter)
if player.Character then task.defer(bindCharacter, player.Character) end如果项目已有清理工具,请使用现有工具;不要为了三个连接就引入新框架。服务端系统需要为每个 重复此绑定逻辑,并在 时清理玩家作用域的表。
PlayerPlayerRemovingPattern: animation through Animator and markers
模式:通过 Animator 和标记实现动画
lua
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://1234567890"
local track = animator:LoadAnimation(animation)
local markerConnection = track:GetMarkerReachedSignal("Commit"):Connect(function(parameter)
playLocalSwingEffect(parameter) -- presentation; server still validates any hit
end)
track:Play(0.1)
-- On character teardown:
markerConnection:Disconnect()
track:Stop(0.1)
animation:Destroy()For rigs without a , use an with an . Do not use the
deprecated convenience path as a substitute for owning the actual Animator and track lifecycle.
HumanoidAnimationControllerAnimatorlua
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://1234567890"
local track = animator:LoadAnimation(animation)
local markerConnection = track:GetMarkerReachedSignal("Commit"):Connect(function(parameter)
playLocalSwingEffect(parameter) -- presentation; server still validates any hit
end)
track:Play(0.1)
-- On character teardown:
markerConnection:Disconnect()
track:Stop(0.1)
animation:Destroy()对于没有 的 rig,请使用带有 的 。不要使用已弃用的便捷路径来替代对实际 Animator 和轨道生命周期的管理。
HumanoidAnimatorAnimationControllerMovement and rig rules
移动与 rig 规则
- Do not hardcode R15 limb names if R6 is supported. Prefer attachments, tags, or a rig-type
adapter; branch on only where topology materially differs.
Humanoid.RigType - is the usual character assembly root, not a universal guarantee for every custom model. Define the custom rig contract and validate it at spawn.
HumanoidRootPart - Prefer /standard controls for ordinary avatar locomotion. Directly changing
Humanoid:Move()is an instantaneous physical action; use forces/constraints or impulses when continuous or instantaneous physics is the real intent.AssemblyLinearVelocity - Never grant damage or movement authority because a client owns its character physics. Validate cross-player consequences on the server.
- Tools move between Backpack and Character during equip; listen to lifecycle/state rather than
assuming one fixed parent. Modify accessories/appearance through current character APIs and
preserve an up-to-date applied when editing avatar appearance.
HumanoidDescription
- 如果支持 R6,不要硬编码 R15 的肢体名称。优先使用附件、标签或 rig 类型适配器;仅在拓扑结构存在实质差异时,才根据 进行分支处理。
Humanoid.RigType - 是通常的角色装配根节点,但并非对所有自定义模型都通用。请定义自定义 rig 的约定,并在生成时进行验证。
HumanoidRootPart - 普通 avatar 移动优先使用 /标准控制。直接修改
Humanoid:Move()是瞬时物理操作;如果实际需求是连续或瞬时物理效果,请使用力/约束或冲量。AssemblyLinearVelocity - 绝不要因为客户端拥有其角色的物理所有权,就授予其伤害或移动权限。所有跨玩家的影响都必须在服务端进行验证。
- Tools 在装备时会在 Backpack 和 Character 之间移动;请监听生命周期/状态,而不是假设父对象是固定的。通过当前角色 API 修改配饰/外观,并在编辑 avatar 外观时保留最新的已应用 。
HumanoidDescription
Common failures
常见问题
| Symptom | Likely cause | Remedy |
|---|---|---|
| works once, breaks after reset | cached character/Humanoid/root | rebuild per |
| callbacks fire twice after deaths | old character connections survived | character-scoped cleanup and generation/current checks |
| delayed load edits wrong rig | async work outlived spawn | compare current Character/generation after every yield |
| animation visible only locally or not at all | wrong Animator/context/asset ownership | inspect rig Animator, execution side, permissions, and replication |
| hit marker awards impossible hit | animation marker trusted as authority | use marker for timing/presentation; server validates combat state |
| R6/custom rig errors | R15 names assumed | define rig contract; attachments/adapter; test each supported rig |
| tool disappears from system | fixed Backpack/Character parent assumed | handle equip/unequip ancestry and character replacement |
| custom force fights Humanoid | two controllers own motion | choose one movement authority per state and restore cleanly |
| 症状 | 可能原因 | 解决方法 |
|---|---|---|
| 仅工作一次,重置后失效 | 缓存了 character/Humanoid/root | 每次 |
| 死亡后回调触发两次 | 旧角色的连接未被清理 | 角色作用域清理 + 世代/当前角色检查 |
| 延迟加载修改了错误的 rig | 异步工作的生命周期超过了角色生成周期 | 每次 yield 后比较当前 Character/世代 |
| 动画仅在本地可见或完全不可见 | Animator/上下文/资产所有权错误 | 检查 rig 的 Animator、执行端、权限和复制情况 |
| 命中标记触发了不可能的命中 | 将动画标记视为权威来源 | 标记仅用于计时/表现;战斗状态由服务端验证 |
| R6/自定义 rig 报错 | 假设了 R15 的命名 | 定义 rig 约定;使用附件/适配器;测试每种支持的 rig |
| 工具从系统中消失 | 假设了 Backpack/Character 是固定父对象 | 处理装备/卸下的父级变更以及角色替换 |
| 自定义力与 Humanoid 冲突 | 两个控制器同时控制运动 | 每个状态选择一个移动控制方,并干净地恢复 |
Resources
参考资源
- Read for server binding, death vs removal, rig and animation verification, custom characters, and the lifecycle stress matrix.
references/lifecycle-and-animation.md
- 阅读 了解服务端绑定、死亡与移除的区别、rig 与动画验证、自定义角色以及生命周期压力测试矩阵。
references/lifecycle-and-animation.md
Related skills
相关技能
- — forces, constraints, assemblies, collision, and network ownership.
roblox-physics - — server validation of character actions and stale requests.
roblox-networking - — action mapping and responsive movement intent.
input-systems - — camera behavior following replaceable characters.
camera-systems
- —— 力、约束、装配、碰撞与网络所有权。
roblox-physics - —— 角色操作的服务端验证与过期请求处理。
roblox-networking - —— 动作映射与响应式移动意图。
input-systems - —— 跟随可替换角色的相机行为。
camera-systems
Primary references
主要参考资料
https://create.roblox.com/docs/charactershttps://create.roblox.com/docs/animation/usinghttps://create.roblox.com/docs/characters/appearance
https://create.roblox.com/docs/charactershttps://create.roblox.com/docs/animation/usinghttps://create.roblox.com/docs/characters/appearance