<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Animation on 山高月小</title><link>https://blog.dart.xin/tags/animation/</link><description>Recent content in Animation on 山高月小</description><generator>Hugo</generator><language>zh-cn</language><copyright>zwdart</copyright><lastBuildDate>Wed, 04 Nov 2026 09:44:43 +0800</lastBuildDate><atom:link href="https://blog.dart.xin/tags/animation/index.xml" rel="self" type="application/rss+xml"/><item><title>Godot Animation介绍</title><link>https://blog.dart.xin/godot/gd101-animation/</link><pubDate>Wed, 04 Nov 2026 09:44:43 +0800</pubDate><guid>https://blog.dart.xin/godot/gd101-animation/</guid><description>&lt;p&gt;Godot 的动画系统以&lt;strong&gt;简洁但极具深度&lt;/strong&gt;著称。理解它的关键在于建立一个清晰的层次观：&lt;strong&gt;&lt;code&gt;Tween&lt;/code&gt;、&lt;code&gt;AnimationPlayer&lt;/code&gt; 和 &lt;code&gt;AnimationTree&lt;/code&gt; 三者并非替代关系，而是分别针对不同场景、逐级递进的工具&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="-先看全景你该在什么时候用什么"&gt;🗺️ 先看全景：你该在什么时候用什么？&lt;/h3&gt;
&lt;p&gt;社区里一条非常实用的“黄金法则”是：&lt;strong&gt;从 &lt;code&gt;AnimationPlayer&lt;/code&gt; 开始；当你需要动画之间的混合、过渡或分层时，再引入 &lt;code&gt;AnimationTree&lt;/code&gt;&lt;/strong&gt;。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;工具&lt;/th&gt;
&lt;th style="text-align: left"&gt;最适合的场景&lt;/th&gt;
&lt;th style="text-align: left"&gt;关键特征&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;strong&gt;&lt;code&gt;Tween&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;代码驱动的一次性短动画：按钮悬停、屏幕震动、UI 淡入、伤害闪烁&lt;/td&gt;
&lt;td style="text-align: left"&gt;纯代码创建，运行一次后自动释放&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;strong&gt;&lt;code&gt;AnimationPlayer&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;需要在编辑器中“编排”的动画：精灵帧序列、复杂运动、过场动画、UI 过渡&lt;/td&gt;
&lt;td style="text-align: left"&gt;可视化时间轴，可复用，能驱动几乎任何属性&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;strong&gt;&lt;code&gt;AnimationTree&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;需要&lt;strong&gt;状态管理&lt;/strong&gt;或&lt;strong&gt;混合&lt;/strong&gt;的角色动画：&lt;code&gt;idle→walk→run&lt;/code&gt;、8 方向移动、上下半身分层&lt;/td&gt;
&lt;td style="text-align: left"&gt;包裹 &lt;code&gt;AnimationPlayer&lt;/code&gt;，用状态机或混合树来调度播放&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;你的学习路径可以按照 &lt;strong&gt;&lt;code&gt;Tween&lt;/code&gt; → &lt;code&gt;AnimationPlayer&lt;/code&gt; → &lt;code&gt;AnimationTree&lt;/code&gt;&lt;/strong&gt; 的顺序推进，下面逐层展开。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="-第一层tween--代码里的一次性动效"&gt;🌱 第一层：&lt;code&gt;Tween&lt;/code&gt; —— 代码里的“一次性动效”&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Tween&lt;/code&gt; 是三者中最轻量的。它不活在场景树里，而是由代码通过 &lt;code&gt;create_tween()&lt;/code&gt; 创建，专注于将某个属性从当前值平滑插值到目标值。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript" data-lang="gdscript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 让节点在 1 秒内移动到 (500, 300)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;tween&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_tween&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tween&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tween_property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;position&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Vector2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_ease&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Tween&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EASE_OUT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_trans&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Tween&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TRANS_CUBIC&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;核心心智模型&lt;/strong&gt;：&lt;code&gt;Tween&lt;/code&gt; 是“即用即走”的。如果只是一个按钮弹一下、一个面板滑进来，用它最直接，不需要在场景里挂节点，也不需要打开动画面板。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="-第二层animationplayer--你的万能动画剪辑台"&gt;✂️ 第二层：&lt;code&gt;AnimationPlayer&lt;/code&gt; —— 你的万能动画剪辑台&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;AnimationPlayer&lt;/code&gt; 是整个动画系统的&lt;strong&gt;数据基础&lt;/strong&gt;。它本身是一个 &lt;code&gt;Node&lt;/code&gt;，内部可以存放多条&lt;strong&gt;动画片段&lt;/strong&gt;，每条动画由若干&lt;strong&gt;轨道&lt;/strong&gt;组成，轨道上放置&lt;strong&gt;关键帧&lt;/strong&gt;。&lt;/p&gt;
&lt;h4 id="关键概念轨道与关键帧"&gt;关键概念：轨道与关键帧&lt;/h4&gt;
&lt;p&gt;一条&lt;strong&gt;轨道&lt;/strong&gt;绑定到“某个节点的某个属性”（例如 &lt;code&gt;Sprite2D:position&lt;/code&gt;）。&lt;strong&gt;关键帧&lt;/strong&gt;记录该属性在某一时刻的值；两个关键帧之间，引擎会自动插值，让属性平滑变化。&lt;/p&gt;</description><content:encoded><![CDATA[<p>Godot 的动画系统以<strong>简洁但极具深度</strong>著称。理解它的关键在于建立一个清晰的层次观：<strong><code>Tween</code>、<code>AnimationPlayer</code> 和 <code>AnimationTree</code> 三者并非替代关系，而是分别针对不同场景、逐级递进的工具</strong>。</p>
<hr>
<h3 id="-先看全景你该在什么时候用什么">🗺️ 先看全景：你该在什么时候用什么？</h3>
<p>社区里一条非常实用的“黄金法则”是：<strong>从 <code>AnimationPlayer</code> 开始；当你需要动画之间的混合、过渡或分层时，再引入 <code>AnimationTree</code></strong>。</p>
<table>
	<thead>
			<tr>
					<th style="text-align: left">工具</th>
					<th style="text-align: left">最适合的场景</th>
					<th style="text-align: left">关键特征</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: left"><strong><code>Tween</code></strong></td>
					<td style="text-align: left">代码驱动的一次性短动画：按钮悬停、屏幕震动、UI 淡入、伤害闪烁</td>
					<td style="text-align: left">纯代码创建，运行一次后自动释放</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong><code>AnimationPlayer</code></strong></td>
					<td style="text-align: left">需要在编辑器中“编排”的动画：精灵帧序列、复杂运动、过场动画、UI 过渡</td>
					<td style="text-align: left">可视化时间轴，可复用，能驱动几乎任何属性</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong><code>AnimationTree</code></strong></td>
					<td style="text-align: left">需要<strong>状态管理</strong>或<strong>混合</strong>的角色动画：<code>idle→walk→run</code>、8 方向移动、上下半身分层</td>
					<td style="text-align: left">包裹 <code>AnimationPlayer</code>，用状态机或混合树来调度播放</td>
			</tr>
	</tbody>
</table>
<p>你的学习路径可以按照 <strong><code>Tween</code> → <code>AnimationPlayer</code> → <code>AnimationTree</code></strong> 的顺序推进，下面逐层展开。</p>
<hr>
<h3 id="-第一层tween--代码里的一次性动效">🌱 第一层：<code>Tween</code> —— 代码里的“一次性动效”</h3>
<p><code>Tween</code> 是三者中最轻量的。它不活在场景树里，而是由代码通过 <code>create_tween()</code> 创建，专注于将某个属性从当前值平滑插值到目标值。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript" data-lang="gdscript"><span class="line"><span class="cl"><span class="c1"># 让节点在 1 秒内移动到 (500, 300)</span>
</span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="n">tween</span> <span class="o">=</span> <span class="nf">create_tween</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="n">tween</span><span class="o">.</span><span class="nf">tween_property</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&#34;position&#34;</span><span class="p">,</span> <span class="nc">Vector2</span><span class="p">(</span><span class="mi">500</span><span class="p">,</span> <span class="mi">300</span><span class="p">),</span> <span class="mf">1.0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="nf">set_ease</span><span class="p">(</span><span class="nc">Tween</span><span class="o">.</span><span class="n">EASE_OUT</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="nf">set_trans</span><span class="p">(</span><span class="nc">Tween</span><span class="o">.</span><span class="n">TRANS_CUBIC</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>核心心智模型</strong>：<code>Tween</code> 是“即用即走”的。如果只是一个按钮弹一下、一个面板滑进来，用它最直接，不需要在场景里挂节点，也不需要打开动画面板。</p>
<hr>
<h3 id="-第二层animationplayer--你的万能动画剪辑台">✂️ 第二层：<code>AnimationPlayer</code> —— 你的万能动画剪辑台</h3>
<p><code>AnimationPlayer</code> 是整个动画系统的<strong>数据基础</strong>。它本身是一个 <code>Node</code>，内部可以存放多条<strong>动画片段</strong>，每条动画由若干<strong>轨道</strong>组成，轨道上放置<strong>关键帧</strong>。</p>
<h4 id="关键概念轨道与关键帧">关键概念：轨道与关键帧</h4>
<p>一条<strong>轨道</strong>绑定到“某个节点的某个属性”（例如 <code>Sprite2D:position</code>）。<strong>关键帧</strong>记录该属性在某一时刻的值；两个关键帧之间，引擎会自动插值，让属性平滑变化。</p>
<p><code>AnimationPlayer</code> 远不止能做位移。它可以驱动<strong>检查器里几乎任何可插值的属性</strong>：颜色、透明度、碰撞形状的启用状态、着色器参数等等。</p>
<h4 id="不止是属性轨道类型全览">不止是属性：轨道类型全览</h4>
<p>除了最常用的属性轨道，<code>AnimationPlayer</code> 还支持多种专用轨道，这是它成为“剪辑台”的关键：</p>
<table>
	<thead>
			<tr>
					<th style="text-align: left">轨道类型</th>
					<th style="text-align: left">作用</th>
					<th style="text-align: left">典型用途</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td style="text-align: left"><strong>属性轨道</strong> (Property)</td>
					<td style="text-align: left">插值节点属性</td>
					<td style="text-align: left">位置、旋转、缩放、颜色</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>方法轨道</strong> (Call Method)</td>
					<td style="text-align: left">在精确时间点调用函数</td>
					<td style="text-align: left">在攻击动画第 0.3 秒生成伤害判定、播放音效、触发状态切换</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>音频轨道</strong> (Audio Playback)</td>
					<td style="text-align: left">将音频锁定在时间轴上播放</td>
					<td style="text-align: left">让脚步声与脚落地精确同步</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>贝塞尔曲线轨道</strong> (Bezier)</td>
					<td style="text-align: left">用曲线精细控制数值变化节奏</td>
					<td style="text-align: left">非线性的 UI 动效、特殊的缓动需求</td>
			</tr>
			<tr>
					<td style="text-align: left"><strong>动画轨道</strong> (Animation)</td>
					<td style="text-align: left">播放其他动画</td>
					<td style="text-align: left">在一条时间轴上串联多个片段</td>
			</tr>
	</tbody>
</table>
<p><strong>方法轨道的一个重要细节</strong>：它默认的调用模式是 <code>CONTINUOUS</code>，在关键帧前后拖拽播放头时可能会反复触发。对于“伤害判定只该发生一次”的逻辑，应当在代码中将调用模式设为 <code>CALL_MODE_DISCRETE</code>，确保函数在越过关键帧时只执行一次。</p>
<h4 id="-一个必须避开的坑">⚠️ 一个必须避开的坑</h4>
<p>不要将带有 2D/3D 变换的节点设为 <code>AnimationPlayer</code> 的<strong>直接子节点</strong>。因为 <code>AnimationPlayer</code> 继承自裸 <code>Node</code>，不传递变换，这会导致子节点的视觉表现异常。正确的结构是让 <code>AnimationPlayer</code> 与 <code>Sprite2D</code> 等节点<strong>平级</strong>，而不是成为它的父节点。</p>
<hr>
<h3 id="-第三层animationtree--状态机与混合的大脑">🧠 第三层：<code>AnimationTree</code> —— 状态机与混合的大脑</h3>
<p>当你的动画需求从“播放一条片段”升级为“在多个片段之间智能切换和混合”时，<code>AnimationTree</code> 就该登场了。</p>
<p>它的基本结构是：<code>AnimationTree</code> 通过 <code>anim_player</code> 属性指向一个 <code>AnimationPlayer</code>，自身在运行时以<strong>参数</strong>的形式对外暴露控制接口。</p>
<h4 id="两种核心组织方式状态机-vs-混合空间">两种核心组织方式：状态机 vs 混合空间</h4>
<p><strong>① 状态机 (<code>AnimationNodeStateMachine</code>)</strong> —— 管理“离散状态”的切换</p>
<p>适合 <code>idle</code>、<code>walk</code>、<code>jump</code>、<code>attack</code> 这类<strong>互斥状态</strong>。你在编辑器中画出状态节点和过渡连线，通过代码驱动状态迁移。</p>
<p>最常用的两种驱动方式：</p>
<ul>
<li>
<p><strong><code>travel()</code></strong>：命令式切换。在 <code>_physics_process</code> 中根据游戏逻辑判断目标状态并调用。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript" data-lang="gdscript"><span class="line"><span class="cl"><span class="kd">var</span> <span class="n">playback</span> <span class="o">=</span> <span class="n">anim_tree</span><span class="o">.</span><span class="nf">get</span><span class="p">(</span><span class="s2">&#34;parameters/StateMachine/playback&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">playback</span><span class="o">.</span><span class="nf">travel</span><span class="p">(</span><span class="s2">&#34;Run&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p><strong>Advance Condition（推进条件）</strong>：声明式切换。在过渡线上设置一个布尔条件名，代码中设置该参数，条件满足时自动过渡。适合<strong>受击、死亡</strong>等事件驱动的切换。</p>
</li>
</ul>
<p>此外，<strong>Auto Advance</strong> 可以用于<strong>连招链</strong>：<code>Attack1 → Attack2</code> 无需条件，前一段播完自动进入下一段。</p>
<p><strong>② 混合空间 (<code>BlendSpace1D</code> / <code>BlendSpace2D</code>)</strong> —— 管理“连续变化”</p>
<p>适合<strong>方向</strong>和<strong>速度</strong>这类连续量。</p>
<ul>
<li>
<p><strong><code>BlendSpace1D</code></strong>：单一参数驱动。例如用速度值在 <code>walk</code> 和 <code>run</code> 之间连续混合。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript" data-lang="gdscript"><span class="line"><span class="cl"><span class="n">anim_tree</span><span class="p">[</span><span class="s2">&#34;parameters/BlendSpace1D/blend_position&#34;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">inverse_lerp</span><span class="p">(</span><span class="n">walk_speed</span><span class="p">,</span> <span class="n">run_speed</span><span class="p">,</span> <span class="n">velocity</span><span class="o">.</span><span class="nf">length</span><span class="p">())</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p><strong><code>BlendSpace2D</code></strong>：二维向量驱动。将 8 个方向的动画放置在平面上的对应坐标，用输入方向向量直接驱动，实现<strong>8 方向移动</strong>的自然混合。</p>
</li>
</ul>
<p><strong>实际项目中，两者是配合使用的</strong>：状态机负责“当前该处于什么大状态”（比如 <code>Locomotion</code> 状态），而该状态内部的 <code>walk/run</code> 切换或方向混合则交给混合空间处理。</p>
<hr>
<h3 id="-专项骨骼动画2d-与-3d">🦴 专项：骨骼动画（2D 与 3D）</h3>
<p><strong>2D 骨骼</strong>通过 <code>Skeleton2D</code> + <code>Bone2D</code> 层级实现。<code>AnimationPlayer</code> 对 <code>Bone2D</code> 的旋转属性打关键帧，即可驱动骨骼摆动。</p>
<p>如果需要<strong>程序化</strong>的肢体定位（比如让脚精确踩在斜坡上），可以使用 <code>SkeletonModification2DTwoBoneIK</code>。将 IK 目标点交给 <code>Marker2D</code> 或射线检测结果，骨骼链会自动解算姿态。</p>
<p><strong>3D 动画</strong>的导入非常直接：从 Blender 等 DCC 工具导出 FBX/glTF 时勾选动画，导入 Godot 后，动画会自动收纳在生成场景的 <code>AnimationPlayer</code> 节点中。之后 <code>AnimationTree</code> 指向这个 <code>AnimationPlayer</code> 即可照常使用。</p>
<hr>
<h3 id="-总结你的学习节奏">💎 总结：你的学习节奏</h3>
<ol>
<li><strong>先只用 <code>Tween</code></strong>：所有“代码里顺手做一下”的动效，都用它完成，熟悉插值、缓动和链式调用。</li>
<li><strong>再掌握 <code>AnimationPlayer</code></strong>：学会在动画面板里创建片段、添加属性轨道，并尝试<strong>方法轨道</strong>来把游戏逻辑事件绑定到时间线上。</li>
<li><strong>最后引入 <code>AnimationTree</code></strong>：从一个简单的 <code>idle/walk</code> 状态机开始，逐步加入 <code>BlendSpace2D</code> 处理方向移动。记住那条法则——<strong>能用 <code>AnimationPlayer</code> 直接 <code>play()</code> 解决的，就不要用状态机</strong>。</li>
</ol>
<p>Godot 动画系统的设计哲学是<strong>用可视化编辑器承载“编排”，用代码控制“决策”</strong>。当你把 <code>AnimationPlayer</code> 当作素材库、<code>AnimationTree</code> 当作决策层时，两者的分工就会变得非常清晰。</p>
]]></content:encoded></item></channel></rss>