roblox-characters-animation
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCharacters and animation
角色与动画
Character basics
角色基础
- A player character is a with a
Model,Humanoid(the root; move the character withHumanoidRootPart), R15 body parts, and ancharacter:PivotTo(cframe)LocalScript.Animate - Defaults (walk speed, jump, health, R6/R15, collisions, body scaling) are configured in Studio's
Avatar Settings window and (
StarterPlayer,CharacterWalkSpeedorCharacterJumpHeight+CharacterUseJumpPower).CharacterJumpPower - Custom character: put a named
ModelinStarterCharacter. Custom per-player spawns:StarterPlayer, thenPlayers.CharacterAutoLoads = falsewhen ready (e.g. after data loads).player:LoadCharacterAsync()(non-Async) is deprecated.LoadCharacter - Characters are destroyed and recreated on death/respawn: bind per-character logic in .
CharacterAdded - Client-set /
WalkSpeedare trivially exploitable; enforce limits on the server or use server authority (JumpHeight,roblox-security).roblox-physics
- 玩家角色是一个 ,包含
Model、Humanoid(根部件;使用HumanoidRootPart移动角色)、R15 身体部件和character:PivotTo(cframe)LocalScript。Animate - 默认值(步行速度、跳跃、生命值、R6/R15、碰撞、身体缩放)在 Studio 的 Avatar Settings 窗口和 (
StarterPlayer、CharacterWalkSpeed或CharacterJumpHeight+CharacterUseJumpPower)中配置。CharacterJumpPower - 自定义角色:将名为 的
StarterCharacter放入Model。每位玩家的自定义生成方式:设置StarterPlayer,然后在准备好时(例如数据加载完成后)调用Players.CharacterAutoLoads = false。player:LoadCharacterAsync()(非 Async 版本)已弃用。LoadCharacter - 角色死亡/重生时会被销毁并重新创建:在 中绑定每个角色的逻辑。
CharacterAdded - 客户端设置的 /
WalkSpeed很容易被作弊者利用;应在服务器上强制执行限制,或采用服务器权威机制(JumpHeight、roblox-security)。roblox-physics
Health and damage (server)
生命值与伤害(服务器)
luau
--!strict
local Players = game:GetService("Players")
local function damage(target: Model, amount: number, source: Player?)
local humanoid = target:FindFirstChildOfClass("Humanoid")
if not humanoid or humanoid.Health <= 0 then
return
end
humanoid:SetAttribute("LastDamagedBy", if source then source.UserId else 0)
humanoid:TakeDamage(amount) -- respects ForceField; use Health -= amount to bypass
end
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
local humanoid = character:WaitForChild("Humanoid") :: Humanoid
humanoid.MaxHealth = 150
humanoid.Health = 150
humanoid.Died:Once(function()
local killerId = humanoid:GetAttribute("LastDamagedBy")
print(`{player.Name} died (killer {killerId})`)
end)
end)
end)
return damage- Disable default regen by deleting/replacing the script via
Health.StarterCharacterScripts - + ragdoll constraints for ragdolls.
Humanoid.BreakJointsOnDeath = false - States: ,
humanoid:ChangeState(Enum.HumanoidStateType.Jumping),SetStateEnabled(state, false).StateChanged,MoveDirection,FloorMaterial,RootPartare read-only helpers.SeatPart - walks NPCs (times out after 8 s; re-issue for long paths — see
humanoid:MoveTo(position)).roblox-npc-ai
luau
--!strict
local Players = game:GetService("Players")
local function damage(target: Model, amount: number, source: Player?)
local humanoid = target:FindFirstChildOfClass("Humanoid")
if not humanoid or humanoid.Health <= 0 then
return
end
humanoid:SetAttribute("LastDamagedBy", if source then source.UserId else 0)
humanoid:TakeDamage(amount) -- respects ForceField; use Health -= amount to bypass
end
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
local humanoid = character:WaitForChild("Humanoid") :: Humanoid
humanoid.MaxHealth = 150
humanoid.Health = 150
humanoid.Died:Once(function()
local killerId = humanoid:GetAttribute("LastDamagedBy")
print(`{player.Name} died (killer {killerId})`)
end)
end)
end)
return damage- 要禁用默认生命恢复,请通过 删除或替换
StarterCharacterScripts脚本。Health - 配合布娃娃约束可实现布娃娃效果。
Humanoid.BreakJointsOnDeath = false - 状态:、
humanoid:ChangeState(Enum.HumanoidStateType.Jumping)、SetStateEnabled(state, false)。StateChanged、MoveDirection、FloorMaterial、RootPart是只读辅助属性。SeatPart - 可使 NPC 行走(8 秒后超时;长路径需重新发起调用——参见
humanoid:MoveTo(position))。roblox-npc-ai
Appearance
外观
luau
--!strict
local Players = game:GetService("Players")
local function applyUniform(player: Player)
local character = player.Character
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
if not humanoid then
return
end
local ok, description = pcall(function()
return Players:GetHumanoidDescriptionFromUserIdAsync(player.UserId)
end)
if not ok then
return
end
description.Shirt = 123456 -- asset ids
description.Pants = 654321
description.HeightScale = 1.05
pcall(function()
humanoid:ApplyDescriptionAsync(description) -- server-side; replicates
end)
end
return applyUniformPlayer:LoadCharacterWithHumanoidDescriptionAsync(description)ApplyDescriptionGetHumanoidDescriptionFromUserIdluau
--!strict
local Players = game:GetService("Players")
local function applyUniform(player: Player)
local character = player.Character
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
if not humanoid then
return
end
local ok, description = pcall(function()
return Players:GetHumanoidDescriptionFromUserIdAsync(player.UserId)
end)
if not ok then
return
end
description.Shirt = 123456 -- asset ids
description.Pants = 654321
description.HeightScale = 1.05
pcall(function()
humanoid:ApplyDescriptionAsync(description) -- server-side; replicates
end)
end
return applyUniformPlayer:LoadCharacterWithHumanoidDescriptionAsync(description)ApplyDescriptionGetHumanoidDescriptionFromUserIdAnimation playback
动画播放
luau
--!strict
local function playAttack(character: Model, animation: Animation): AnimationTrack?
local humanoid = character:FindFirstChildOfClass("Humanoid")
local animator = humanoid and humanoid:FindFirstChildOfClass("Animator")
if not animator then
return nil
end
local track = animator:LoadAnimation(animation) -- Humanoid:LoadAnimation is deprecated
track.Priority = Enum.AnimationPriority.Action
track.Looped = false
track:GetMarkerReachedSignal("Hit"):Connect(function(param)
print("hit frame reached", param) -- apply damage window, play sound, etc.
end)
track:Play(0.1) -- fade time
return track
end
return playAttack- Where to play: the local player's own character → play on the client (replicates automatically via its Animator); NPCs → play on the server (or on clients for purely cosmetic, high-count NPCs).
- Load each once per Animator and reuse the track; don't call
Animationevery time an action happens (there's a per-Animator track limit). Exception: server authority (query live tracks).LoadAnimation - Priorities: . Blend with
Core < Idle < Movement < Action < Action2 < Action3 < Action4, change speed withAdjustWeight, stop withAdjustSpeed.Stop(fadeTime) - Events: ,
track.Stopped, markers viatrack.Ended(GetMarkerReachedSignalis superseded).KeyframeReached - Animation assets must be owned by (or shared with, via asset permissions) the experience's owner — otherwise they silently fail to play in live servers.
- Replace defaults by editing the script's
Animate/StringValuechildren (Animation) onanimate.run.RunAnim.AnimationId, or ship a customCharacterAddedinAnimate.StarterCharacterScripts - Procedural: (look-at, foot planting, reaching) instead of hand-written joint math.
IKControl
luau
--!strict
local function playAttack(character: Model, animation: Animation): AnimationTrack?
local humanoid = character:FindFirstChildOfClass("Humanoid")
local animator = humanoid and humanoid:FindFirstChildOfClass("Animator")
if not animator then
return nil
end
local track = animator:LoadAnimation(animation) -- Humanoid:LoadAnimation is deprecated
track.Priority = Enum.AnimationPriority.Action
track.Looped = false
track:GetMarkerReachedSignal("Hit"):Connect(function(param)
print("hit frame reached", param) -- apply damage window, play sound, etc.
end)
track:Play(0.1) -- fade time
return track
end
return playAttack- 在哪里播放:本地玩家自己的角色 → 在客户端播放(通过其 Animator 自动复制);NPC → 在服务器上播放(对于纯视觉效果且数量较多的 NPC,也可以在客户端播放)。
- 每个 对每条
Animator只应加载一次并重复使用对应的 track;不要在每次动作发生时都调用Animation(每个 Animator 的 track 数量有限)。例外:服务器权威场景(查询当前播放的 track)。LoadAnimation - 优先级:。使用
Core < Idle < Movement < Action < Action2 < Action3 < Action4进行混合,使用AdjustWeight调整速度,使用AdjustSpeed停止。Stop(fadeTime) - 事件:、
track.Stopped,以及通过track.Ended触发标记(GetMarkerReachedSignal已被取代)。KeyframeReached - 动画资产必须归体验的所有者所有,或通过资产权限与所有者共享,否则在正式服务器中会静默播放失败。
- 要替换默认动画,可在 时编辑
CharacterAdded脚本的Animate/StringValue子项(Animation),或者在animate.run.RunAnim.AnimationId中提供自定义StarterCharacterScripts。Animate - 程序化动画:使用 (看向目标、脚部固定、伸手动作),代替手写关节数学计算。
IKControl
Tweening
补间动画
luau
--!strict
local TweenService = game:GetService("TweenService")
local door = Instance.new("Part")
door.Anchored = true
door.Parent = workspace
local info = TweenInfo.new(0.6, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
local open = TweenService:Create(door, info, { CFrame = door.CFrame * CFrame.new(0, 8, 0) })
open.Completed:Once(function(state)
print("door tween finished:", state)
end)
open:Play()- Tween anchored parts or UI. For unanchored/physics objects use constraints.
- Tweening on the server replicates every frame and stutters: for visual-only motion, tween on each client (the server sets the final state or an attribute clients react to).
- Models: tween a and call
CFrameValuein itsmodel:PivotTo(value)handler, or tween the primary part with the rest welded to it.Changed - for custom interpolation;
TweenService:GetValue(alpha, style, direction)for follow motion.SmoothDamp
luau
--!strict
local TweenService = game:GetService("TweenService")
local door = Instance.new("Part")
door.Anchored = true
door.Parent = workspace
local info = TweenInfo.new(0.6, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
local open = TweenService:Create(door, info, { CFrame = door.CFrame * CFrame.new(0, 8, 0) })
open.Completed:Once(function(state)
print("door tween finished:", state)
end)
open:Play()- 对已锚定部件或 UI 使用 Tween。对于未锚定或受物理影响的物体,应使用约束。
- 在服务器上执行补间会逐帧同步并产生卡顿:对于纯视觉运动,应让每个客户端分别执行补间(由服务器设置最终状态或客户端可响应的属性)。
- Model:对 执行补间,并在其
CFrameValue处理器中调用Changed;也可以补间主部件,并将其余部件焊接至该主部件。model:PivotTo(value) - 使用 实现自定义插值;使用
TweenService:GetValue(alpha, style, direction)实现跟随运动。SmoothDamp
Tools
工具
ToolStarterPackBackpackHandleRequiresHandle = falseEquippedUnequippedActivatedActivatedToolStarterPackBackpackHandleRequiresHandle = falseEquippedUnequippedActivatedActivatedCharacter Controller Library (beta)
Character Controller Library(beta)
Roblox's CCL () replaces the fixed Humanoid state machine with
composable abilities (Running, Jumping, Climbing, custom Dash...) coordinated by labels, sensors,
conditions (/ with //), conflicts (//),
and lifecycle callbacks. Enable it via File → Beta Features and Avatar Settings → Movement →
Abilities. Only use it when the project has opted in; APIs may change while in beta.
Sketch: references/character-controller-library.md.
require("@rbx/AvatarAbilities")StartsWhenRunsWhileAllAnyNotBlocksStopsSuspendsRoblox 的 CCL()使用可组合的 abilities(Running、Jumping、Climbing、自定义 Dash 等)替代固定的 Humanoid 状态机。这些 abilities 通过标签、传感器、条件(/,配合 //)、冲突关系(//)和生命周期回调进行协调。通过 File → Beta Features 和 Avatar Settings → Movement → Abilities 启用。仅当项目选择启用该功能时使用;beta 期间 API 可能发生变化。
大纲:references/character-controller-library.md。
require("@rbx/AvatarAbilities")StartsWhenRunsWhileAllAnyNotBlocksStopsSuspendsRelated skills
相关 skill
roblox-npc-airoblox-physicsroblox-inputroblox-securityroblox-game-systemsroblox-npc-airoblox-physicsroblox-inputroblox-securityroblox-game-systems