動畫圖形編輯器是一個視覺化的基於節點的工具,賦予技術藝術家和動畫師在 Roblox Studio 中直接構建複雜的動畫邏輯。透過提供一個簡化的介面來創建混合樹等行為,它消除了在角色運動中對手動腳本的傳統依賴。
此系統與您現有的動畫工作流程協同工作:
- 動畫編輯器: 繼續使用 動畫編輯器 作為您創作單獨片段和微調關鍵幀及曲線的主要工具。
- 動畫圖形編輯器: 使用這個新工作區將這些片段組織到邏輯樹中,以驅動複雜的遊戲行為。
旨在增強協作,視覺圖形允許開發人員快速檢查、調試和了解動畫師創建的邏輯。當藝術家專注於完善互動運動時,開發人員仍然可以以程式方式訪問動畫圖形節點,以便直接控制混合的動畫和狀態。
建立圖形
要開始為可動畫角色構建邏輯,請通過 Studio 功能區中的角色標籤訪問動畫圖形編輯器。以下步驟演示如何初始化一個骨架並使用預設的走路和揮手動畫構建基本的節點網絡。
要深入了解實用應用,您可以探索 動畫圖形參考檔,該檔案包含基礎和複雜的實現範例。
要創建您自己的動畫圖形,類似於參考中提供的基本示例,請使用以下步驟:
在 Studio 中,通過導航至 角色 標籤並選擇 角色 ⟩ 我的角色 添加一個可動畫的骨架。

通過導航至 角色 標籤中的 圖形編輯器 打開動畫圖形編輯器。

在 3D 視口中選擇可動畫的骨架,然後選擇 創建圖形。
在圖形編輯器中,右鍵單擊並選擇 Clip。

在新的 Clip 節點中,設置動畫 ID。
選擇 動畫 ID 下拉菜單。
要提交特定的動畫資產 ID,請單擊 導入。

在 動畫 ID 字段中,添加預設的走路動畫:507777826。
選擇 導入。
通過重複步驟 4-5 添加另一個片段節點,使用預設的揮手動畫:507770239。

在圖形編輯器中,右鍵單擊並選擇 添加。

將 Clip 節點連接到添加節點,將右上角的輸出連接器拖至適當的端口:
- 將含有走路動畫的 Clip 節點連接到 基礎 端口。
- 將含有揮手動畫的 Clip 節點連接到 附加 端口。

從添加節點將右上角的輸出連接器連接到圖形輸出 姿勢 端口。

(可選) 為您的 Speed 變數分配參數。
單擊並拖動綠色速度端口到空白區域。將顯示一個新參數節點。

在圖形編輯器的左上方,使用參數窗格快速修改您節點中的參數。您也可以以 程式方式 訪問此參數。

按下 播放按鈕 測試動畫。

嘗試測試不同的權重、速度、播放模式和其他動畫。欲了解更多有關單個節點的信息,請參見 節點參考。
API 集成
創建和部署動畫圖形遵循標準的 Roblox 動畫管道。在動畫圖形編輯器中選擇一個骨架後,會創建一個新的 AnimationGraphDefinition 資產。該資產作為您的節點、連接和參數的容器。當您的邏輯完成後,您發布圖形以獲取標準的資產 ID。
在您的腳本中,您可以通過將它們加載到 Animator 上來與這些圖形交互,就像傳統動畫一樣。要驅動圖形的內部邏輯,使用 AnimationTrack:SetParameter() 將實時值(例如運動速度或狀態布林)直接傳遞到圖形的變量中。
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://123456789" -- 您的已發布圖形 ID
local animationTrack = animator:LoadAnimation(animation)
animationTrack:Play()
-- 通過運行服務的動態參數更新
game:GetService("RunService").Stepped:Connect(function(_, dt)
local currentSpeed = humanoidRootPart.AssemblyLinearVelocity.Magnitude
animationTrack:SetParameter("humanoidSpeed", currentSpeed)
end)
節點參考
每個動畫圖形節點作為邏輯閘或數據源,對動畫數據進行處理,然後再到達角色骨架。本節提供動畫圖形編輯器中功能塊的技術細分。所有節點當前都輸出一個動畫姿勢。
每個節點部分包括:
- 定義 – 節點的目的和在圖形中的角色的摘要。
- 輸入 – 進入節點的數據流。多個輸入表示為 Input1、Input2、…、InputN。
- 輸入屬性 – 直接與特定輸入相關的設置(例如,在 Blend1D 節點上將空閒輸入指定為位置 0.5)。
- 事件數據 – 由節點發送或消耗的事件,以觸發內部圖形邏輯或外部 Luau 腳本。此行為可能會在測試版開發過程中發生變化。
全局事件規則
對於所有節點和 轉換,默認適用以下規則:
- 事件從源節點向上傳播,經過圖形。每個事件攜帶一個權重,表示其源在最終混合中的影響。如果權重在任何時候達到零,則事件被靜音。
- 沒有自定義事件邏輯的節點將所有事件通過而不變;進行混合或選擇輸入的節點可能會縮放權重或阻止非主輸入的事件(見每個節點事件部分)。
- 觸發器事件到達圖形頂部可以通過 AnimationTrack:GetMarkerReachedSignal() 觀察。
Clip

引用 AnimationClip 資產。這作為圖形中的葉節點,生成原始動畫數據,並將其輸入到其他節點以便混合、選擇或修改。
- 輸入
- 無
- 屬性
屬性 類型 描述 Clip 資產 ID 要播放的動畫資產(例如 rbxassetid://12345)。 播放模式 Enum.AnimationNodePlayMode 定義片段結束後的行為。
- 循環(默認): 當片段完成後,自動從頭開始。
- 往返: 從開始播放到結束,然後立即反向從結束播放到開始。
- 一次並保持: 播放一次,並在完成後保持最終姿勢。
- 一次並重置: 播放一次,並在完成後回到初始開始姿勢。
反轉 布林 控制播放方向。 速度 數字 播放速度的乘數。0.0 暫停圖形,1.0 是正常速度,2.0 是兩倍速度。 修剪 布林 切換片段的持續時間是否應被截斷。 修剪開始 數字 播放應該開始的絕對時間戳(以秒為單位)。 修剪結束 數字 播放應該終止的絕對時間戳(以秒為單位)。 - 事件數據
- 事件處理: 無。這是一個沒有子節點的葉節點。
- 事件發射: 讀取嵌入動畫片段的自定義標記(例如 "Footstep"、"WeaponSwing"),並在它們發生的確切幀上將它們作為命名事件發射。如果片段被修剪,則僅在定義的 [TrimStart, TrimEnd] 區間內(包含)發射標記。
Select

透過選擇屬性在任意數量的輸入之間進行選擇。每當當前選擇變化時,它會觸發一個新的 轉換。
- 輸入
- Input1...InputN
- 屬性
屬性 類型 描述 選擇 字符串 要選擇的輸入的唯一 ID,與輸入連接的名稱匹配(例如 "Walk")。 - 事件數據
- 事件處理: 來自當前選擇的輸入的事件以未改變的權重通過。
- 事件發射: 僅通過當前選擇的輸入的所有事件。在轉換期間,事件發射遵循 全局事件規則。
PrioritySelect

自上而下評估一組連接的輸入,並播放第一個條件評估為真的輸入。這允許根據特定邏輯進行層次動畫選擇。每當當前選擇變化時,它會觸發一個新的 轉換。
- 輸入
- Input1...InputN
- 觸發 (布林): 必須為真的邏輯條件,才能激活此輸入。在當前版本中,這與布林參數相連接。
- 可中斷 (Enum.AnimationNodeInterruptible): 定義這個活躍動畫何時可以被更高優先級的輸入中斷的規則。
- 始終(默認): 此輸入可以隨時被更高優先級的條件中斷。
- 完成: 當前動畫必須完成播放,然後更高優先級的輸入才能接管。
- 觸發: 僅在 InterruptibleTrigger 設置為 true 時,此輸入可被中斷。
- 可中斷觸發 (布林): 只有在 可中斷 設置為 觸發 時才可用。當這個特定表達式為真的時候,可以對輸入進行中斷。
- 屬性
屬性 類型 描述 DefaultInterruptible Enum.AnimationNodeInterruptible 應用於所有輸入的基線中斷規則。每個輸入都可以使用自己的 可中斷 輸入屬性來覆蓋這個值。 DefaultInterruptibleTrigger 布林 當一個輸入的已解決 可中斷 模式為 觸發 時使用的基線觸發值。每個輸入都可以使用自己的 可中斷觸發 輸入屬性來覆蓋這個值。 - 事件數據
- 事件處理: 來自當前選擇的輸入的事件以未改變的權重通過。
- 事件發射: 僅通過當前選擇的輸入的所有事件。在轉換期間,事件發射遵循 全局事件規則。
Sequence

根據定義的等待條件以特定順序激活連接的輸入。每當當前選擇變化時,它會觸發一個新的 轉換。
- 輸入
- Input1...InputN
- WaitFor (Enum.AnimationNodeWaitFor): 指定必須滿足的條件,以便序列進入下一個輸入。
- 完成(默認): 當前輸入完成週期後,進入下一個輸入。進入的行為取決於連接的輸入:
- 一次播放片段: 當片段完成後進入。
- 迴圈片段: 在完整的迴圈完成後進入。
- 具有無限迴圈的序列: 在所有輸入完成一個完整週期後進入。
- 具有無限迴圈的序列: 在所有迴圈完成後進入。
- 觸發: 當自定義邏輯表達式評估為真時,激活下一個輸入。
- WaitForTrigger (布林): 只有當 WaitFor 設置為 觸發 時才可用。
- 屬性
屬性 類型 描述 迴圈數 數字 循環整個序列的次數(默認為 1)。值為 0 表示無限迴圈。一旦達到計數,該節點根據最後一個輸入的迴圈或保持設置來執行。 默認等待條件 Enum.AnimationNodeWaitFor 應用於所有輸入的基線等待條件。每個輸入都可以使用自己的 WaitFor 輸入屬性來覆蓋這個值。 - 事件數據
- 事件處理: 來自當前活躍輸入的事件以未改變的權重通過。
- 事件發射: 僅通過當前活躍輸入的所有事件。在轉換期間,事件發射遵循 全局事件規則。
RandomSequence

隨機選擇並播放其連接的輸入之一。當當前選擇的動畫完成後,該節點隨機選擇另一個要播放的輸入。為每個輸入分配特定的權重以影響被選中的概率。每當當前選擇變化時,它會觸發一個新的 轉換。
- 輸入
- Input1...InputN
- 權重 (數字): 確定這個輸入被選中的概率;更高的權重增加選中概率。
- 屬性
屬性 類型 描述 播放計數 數字 節點將播放的輸入數量,然後停止。一旦達到,該節點根據最後一個輸入的迴圈或保持設置來執行。默認為 0 為無限。 種子 數字 用來初始化隨機數生成器 (RNG) 的值,確保序列在不同客戶端之間保持一致。默認為 -1 為隨機種子。 - 事件數據
- 事件處理: 來自當前活躍輸入的事件以未改變的權重通過。
- 事件發射: 僅通過當前活躍輸入的所有事件。在轉換期間,事件發射遵循 全局事件規則。
Over

將 Over 姿勢層疊到基礎姿勢上。當與掩蔽節點結合使用時,Over 姿勢中被掩蔽的關節完全顯示出 Base 姿勢,創造透明覆蓋效果。
- 輸入
- 基礎: 背景或底層,通常是類似於運動或靜止的全身動畫。
- Over: 要應用於基礎的前景或頂層,例如手勢或工具使用動畫。
- 屬性
屬性 類型 描述 權重 數字 用於減弱 Over 姿勢的混合權重。默認為 1.0(完全覆蓋)且不受限制。 - 事件數據
- 事件處理:
- 節點監聽來自 Base 和 Over 輸入的事件。
- 事件發射:
- 基本事件: 基礎輸入的所有事件均不經修改直接通過。
- Over 事件: 來自 Over 輸入的事件依據權重屬性進行縮放。
- 在權重 0.5 時,Over 事件在半數權重下傳播
- 在權重 0 時,它們會被靜音。
Add

將 附加 姿勢添加到 基礎 姿勢,並依據特定的 權重(不受限制)進行調整。
- 輸入
- 基礎: 主要的動畫姿勢。
- 附加: 層疊到基礎上的姿勢。
- 屬性
屬性 類型 描述 權重 數字 確定施加於基礎上的附加姿勢的強度。 - 事件數據
- 事件處理: 節點監聽來自 Base 和 Additive 輸入的事件。
- 事件發射: 來自基礎和附加輸入的所有事件以未改變的方式通過。
Subtract

通過從目標姿勢中減去相對的基礎姿勢 () 將動畫轉換為附加姿勢。結果依據特定的 權重(不受限制)進行調整。
- 輸入
- A: 目標動畫姿勢。
- B: 要減去的相對基礎姿勢。
- 屬性
屬性 類型 描述 權重 數字 確定施加於結果的減法效果的強度。 - 事件數據
- 事件處理: 節點監聽來自 輸入 A 和 輸入 B 的事件。
- 事件發射: 來自 輸入 A 和 輸入 B 的所有事件以未改變的方式通過。
Blend1D

在單個軸上對最接近當前輸入位置的兩個動畫姿勢進行線性插值。
- 輸入
- Input1...InputN
- 位置 (數字): 混合軸上每個後續輸入的具體坐標。
- 屬性
屬性 類型 描述 位置 數字 用於抽樣動畫的在混合軸上的當前活躍值。如果 位置 超出定義的輸入位置範圍,則該節點將使用最接近的兩個輸入進行外推。 相位同步 Enum.AnimationNodePhaseSync 配置是否應同步子輸入的時間。
- 同步(默認): 正常化同步。該節點根據活躍輸入的加權平均值計算一個 "虛擬持續時間"。調整每個輸入節點的時間步驟,使所有子節點收斂於同一相位,保持不同長度的動畫保持同步。
- 不同步: 標準混合,讓片段以自己的播放速度獨立前進。
- 事件數據
- 事件處理: 節點監聽來自所有當前活躍子節點的事件。
- 事件發射: 僅從權重最高的活躍輸入傳播,並根據其混合權重進行縮放。來自次要輸入的事件將被靜音。
Blend2D

根據在 2D 坐標空間中的兩個輸入參數混合多個動畫姿勢。這讓 Blend1D 節點能夠處理更複雜的情況,例如根據運動方向和速度同時混合。
- 輸入
- Input1...InputN
- X (數字): 每個後續輸入的 X 坐標。
- Y (數字): 每個後續輸入的 Y 坐標。
- 屬性
屬性 類型 描述 輸入模式 Enum.AnimationNodeBlend2DInputMode 定義用於評估混合空間的坐標系:
- 笛卡爾(默認): 使用標準的 2D 網格坐標。X 和 Y 代表在混合空間中的當前位置。
- 極座標: 使用角度和大小值。X 代表以弧度計算的方向,而 Y 代表運動的大小或強度。方向的權重大於大小,因此相似角度但大小不同的輸入混合得更平滑,而不同角度的輸入則混合得較差。
X 數字 當前 X 坐標(笛卡爾)或以弧度表示的方向(極). Y 數字 當前 Y 坐標(笛卡爾)或大小(極). 相位同步 Enum.AnimationNodePhaseSync 配置是否應同步子輸入的時間。
- 同步(默認): 正常化同步。該節點根據活躍輸入的加權平均值計算一個 "虛擬持續時間"。調整每個輸入節點的時間步驟,使所有子節點收斂於同一相位,保持不同長度的動畫保持同步。
- 不同步: 標準混合,讓片段以自己的播放速度獨立前進。
- 事件數據
- 事件處理: 節點監聽來自所有當前活躍子節點的事件。
- 事件發射: 僅從權重最高的活躍輸入傳播,並根據其混合權重進行縮放。來自次要輸入的事件將被靜音。
Mask

對輸入姿勢應用預先定義的掩蔽。掩蔽由佈局中的每個物體(例如關節)的權重定義,允許精確控制或 "羽化" 動畫。
- 輸入
- 姿勢: 要進行掩蔽的動畫姿勢。
- 屬性
屬性 類型 描述 掩蔽 ObjectValue 一個 ObjectValue (作為 Mask AnimationNodeDefinition 的直接子項生成) 定義了掩蔽權重。它可以有兩種功能:
- 直接: ObjectValue 本身包含將 rigs 物件名稱映射到特定權重值的屬性。
創建掩蔽時,您可以選擇一個 rig schema (HumanoidRigDescription 或 選擇器) 來填充層次結構。
- HumanoidRigDescription: 對於人形角色標準化掩蔽。
- 選擇器: 允許用戶在工作區中選擇任何特定的 rig 來填充掩蔽層次。
反轉 布林 當設置為 true 時,應用權重值為 1 - weight。這允許在不創建新資產的情況下反向重用掩蔽。 - 事件數據
- 事件處理: 節點監聽所有來自輸入 姿勢 的事件。
- 事件發射: 所有來自輸入 姿勢 的事件均以未改變的方式通過。
Speed

修改進入動畫姿勢的播放速度。
- 輸入
- 姿勢: 將修改播放速度的動畫姿勢或子圖。
- 屬性
屬性 類型 描述 速度 數字 應用於時間增量 () 的乘數。0.0 暫停圖形,1.0 是正常速度,2.0 是兩倍速度。 - 事件數據
- 事件處理: 節點監聽來自輸入 姿勢 的事件。
- 事件發射: 所有來自輸入 姿勢 的事件以未改變的方式通過。請注意,儘管可視播放速度發生變化,但所發射事件(例如標記)的時間將根據修改過的播放速度相應縮放。
GraphOutput

表示圖形的最終評估姿勢。這個節點自動包含在動畫圖形編輯器中的所有新圖形中。它的存在確保該圖形始終有效且始終產生一個動畫姿勢。
- 輸入
- 姿勢: 要應用於骨架的最終處理過的動畫數據。
- 屬性
- 無
- 事件數據
- 事件處理: 節點監聽所有從最後一個連接的輸入傳遞的事件。
- 事件發射: 此節點作為動畫管道的出口,不會將信號發射回圖形中。
轉換
動畫圖形中的幾個節點(例如 Select、Priority Select、Sequence 和 Random Sequence)管理在切換活動輸入時動畫如何混合。為了防止節點參考中的冗餘,這些行為由標準化的轉換屬性組定義。
默認轉換

應用於節點,每當它切換到新的活動輸入時的基線混合行為。
- DefaultTransitionDuration (數字): 完全混合到新姿勢所需的時間(以秒為單位)。
- DefaultTransitionCurve (Enum.PoseEasingStyle): 在混合期間應用的緩和函數。目前僅支持 Enum.PoseEasingStyle.Linear 和 Enum.PoseEasingStyle.CubicV2。
轉換覆蓋
具體於輸入的鏈接屬性,這些屬性會超越默認轉換。當節點轉換為該特定輸入時將應用這些屬性。
- TransitionOverrideDuration (數字): 覆蓋默認轉換持續時間。
- TransitionOverrideCurve (Enum.PoseEasingStyle): 覆蓋默認轉換曲線。當前僅支持 Enum.PoseEasingStyle.Linear 和 Enum.PoseEasingStyle.CubicV2。
複製
動畫圖形參數對每個 AnimationTrack 是本地的,並且不會自動複製。在未來的更新中此情況可能會改變,但目前建議的做法是:
- 客戶端 → 伺服器: 使用 RemoteEvent 將參數從擁有者客戶端發送到伺服器,並以固定的 tick 速率進行傳送。
- 伺服器 → 其他客戶端: 實例 屬性 自動複製到所有客戶端。
玩家角色
一個客戶端腳本驅動玩家角色。由於只有擁有者客戶端知道當前遊戲狀態(運動輸入、人體狀態等),因此參數必須從擁有者客戶端流動到伺服器,然後流入所有其他客戶端。
設置
在 StarterCharacterScripts 下創建:
- 用於客戶端動畫和參數驅動的 LocalScript。
- 用於伺服器端複製的 Script。
- 用於客戶端與伺服器之間通信的 RemoteEvent。
客戶端腳本
擁有者客戶端從遊戲事件驅動參數並定期將其發送到伺服器。其他客戶端則從伺服器腳本讀取複製的屬性。
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:FindFirstChildOfClass("Animator") or humanoid
-- 加載動畫圖形
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://YOUR_GRAPH_ID" -- 替換為您的已發布圖形 ID
local track = animator:LoadAnimation(animation)
track:Play()
local isLocalCharacter = Players:GetPlayerFromCharacter(character) == Players.LocalPlayer
if not isLocalCharacter then
-- 從伺服器腳本讀取複製參數
local animateServer = script.Parent:WaitForChild("AnimateServer")
for attribute, value in animateServer:GetAttributes() do
track:SetParameter(attribute, value)
end
animateServer.AttributeChanged:Connect(function(attribute)
track:SetParameter(attribute, animateServer:GetAttribute(attribute))
end)
return
end
-- 本地玩家: 從遊戲驅動參數
local params = {}
local function setParam(key, value)
track:SetParameter(key, value)
params[key] = value
end
-- 示例: 從人體狀態驅動參數
humanoid.Running:Connect(function(speed)
setParam("Speed", speed)
setParam("State", if speed < 0.1 then "Idle" else "Moving")
end)
-- 以固定 tick 速率將參數發送到伺服器
local replicateEvent = script.Parent:WaitForChild("ReplicateEvent")
local TICK_RATE = 1 / 20
local lastSendTime = 0
RunService.Stepped:Connect(function(gameTime)
if gameTime - lastSendTime > TICK_RATE then
lastSendTime = gameTime
replicateEvent:FireServer(params)
end
end)
伺服器腳本
接收來自擁有者客戶端的參數,驅動伺服器端動畫圖形,並將值作為屬性傳播以供其他客戶端複製。
local Players = game:GetService("Players")
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:FindFirstChildOfClass("Animator") or humanoid
-- 在伺服器上加載相同的動畫圖形
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://YOUR_GRAPH_ID" -- 與客戶端相同的圖形 ID
animation.Parent = script
local track = animator:LoadAnimation(animation)
track:Play()
-- 接收來自擁有者客戶端的參數並通過屬性複製
local replicateEvent = script.Parent:WaitForChild("ReplicateEvent")
replicateEvent.OnServerEvent:Connect(function(player, params)
if Players:GetPlayerFromCharacter(character) ~= player then
return
end
for key, value in params do
track:SetParameter(key, value)
script:SetAttribute(key, value)
end
end)
NPCs
由於伺服器擁有 NPC 動畫,因此只需要伺服器到客戶端的複製。驅動伺服器上的動畫圖形,將參數作為屬性寫入伺服器腳本,並使用之前顯示的相同 Instance.AttributeChanged 模式在客戶端讀取它們。
延遲
其他客戶端會看到動畫的延遲為 tick 週期(20Hz 最大延遲可以達到 50ms)加上網絡延遲。您可以通過增加頻率(例如 1/30)來減少 tick 週期,但代價是增加更高的網絡流量。20Hz 是合理的預設值;動畫混合的容忍範圍很廣,小的延遲很難被注意到。