Skip to content

Commit 6306de2

Browse files
committed
[增加] 增加动画的增加或替换接口
1 parent 3a9b3ad commit 6306de2

File tree

2 files changed

+122
-0
lines changed

2 files changed

+122
-0
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// ==========================================================================================
2+
// GameFrameX 组织及其衍生项目的版权、商标、专利及其他相关权利
3+
// GameFrameX organization and its derivative projects' copyrights, trademarks, patents, and related rights
4+
// 均受中华人民共和国及相关国际法律法规保护。
5+
// are protected by the laws of the People's Republic of China and relevant international regulations.
6+
//
7+
// 使用本项目须严格遵守相应法律法规及开源许可证之规定。
8+
// Usage of this project must strictly comply with applicable laws, regulations, and open-source licenses.
9+
//
10+
// 本项目采用 MIT 许可证与 Apache License 2.0 双许可证分发,
11+
// This project is dual-licensed under the MIT License and Apache License 2.0,
12+
// 完整许可证文本请参见源代码根目录下的 LICENSE 文件。
13+
// please refer to the LICENSE file in the root directory of the source code for the full license text.
14+
//
15+
// 禁止利用本项目实施任何危害国家安全、破坏社会秩序、
16+
// It is prohibited to use this project to engage in any activities that endanger national security, disrupt social order,
17+
// 侵犯他人合法权益等法律法规所禁止的行为!
18+
// or infringe upon the legitimate rights and interests of others, as prohibited by laws and regulations!
19+
// 因基于本项目二次开发所产生的一切法律纠纷与责任,
20+
// Any legal disputes and liabilities arising from secondary development based on this project
21+
// 本项目组织与贡献者概不承担。
22+
// shall be borne solely by the developer; the project organization and contributors assume no responsibility.
23+
//
24+
// GitHub 仓库:https://github.com/GameFrameX
25+
// GitHub Repository: https://github.com/GameFrameX
26+
// Gitee 仓库:https://gitee.com/GameFrameX
27+
// Gitee Repository: https://gitee.com/GameFrameX
28+
// 官方文档:https://gameframex.doc.alianblank.com/
29+
// Official Documentation: https://gameframex.doc.alianblank.com/
30+
// ==========================================================================================
31+
32+
using UnityEngine;
33+
34+
namespace Spine.Unity
35+
{
36+
public static class SkeletonDataAssetExtension
37+
{
38+
/// <summary>
39+
/// 为 GameObject 添加或替换 SkeletonAnimation 组件,并设置骨骼数据与动画
40+
/// </summary>
41+
/// <param name="gameObject">需要挂载或更新 SkeletonAnimation 的 GameObject</param>
42+
/// <param name="skeletonDataAsset">骨骼数据资源</param>
43+
/// <param name="animationName">初始动画名称,为空则不播放动画</param>
44+
/// <param name="isLoop">是否循环播放</param>
45+
/// <param name="quiet">是否静默添加(不输出日志)</param>
46+
/// <returns>添加或更新后的 SkeletonAnimation 组件</returns>
47+
public static SkeletonAnimation AddOrReplace(this GameObject gameObject, SkeletonDataAsset skeletonDataAsset, string animationName = null, bool isLoop = false, bool quiet = false)
48+
{
49+
if (skeletonDataAsset == null)
50+
{
51+
Debug.LogError("skeletonDataAsset is null");
52+
return default;
53+
}
54+
55+
// 将 GameObject 名称同步为资源名称,方便调试
56+
gameObject.name = skeletonDataAsset.name;
57+
var component = gameObject.GetComponent<SkeletonAnimation>();
58+
if (component == null)
59+
{
60+
// 不存在则自动添加新组件
61+
return SkeletonRenderer.AddSpineComponent<SkeletonAnimation>(gameObject, skeletonDataAsset, quiet);
62+
}
63+
64+
// 已存在则直接替换骨骼数据并刷新
65+
component.skeletonDataAsset = skeletonDataAsset;
66+
skeletonDataAsset.GetSkeletonData(false); // 强制同步数据
67+
OnChangeSpine(component, animationName, isLoop);
68+
return component;
69+
}
70+
71+
/// <summary>
72+
/// 切换 SkeletonAnimation 的动画与皮肤,并同步到初始姿态
73+
/// </summary>
74+
/// <param name="skeletonAnimation">目标 SkeletonAnimation</param>
75+
/// <param name="animationName">需要切换的动画名称,为空则清空轨道</param>
76+
/// <param name="isLoop">是否循环</param>
77+
public static void OnChangeSpine(this SkeletonAnimation skeletonAnimation, string animationName, bool isLoop)
78+
{
79+
var skeletonData = skeletonAnimation.Skeleton.Data;
80+
81+
var state = skeletonAnimation.AnimationState;
82+
var animationToUse = !string.IsNullOrEmpty(animationName) ? skeletonData.FindAnimation(animationName) : null;
83+
if (animationToUse != null)
84+
{
85+
var trackEntry = state.GetCurrent(0);
86+
// 若当前无动画、动画名不同或已播放完毕且非循环,则重新设置
87+
if (trackEntry == null || trackEntry.Animation.Name != animationName || trackEntry.IsComplete && !trackEntry.Loop)
88+
{
89+
trackEntry = state.SetAnimation(0, animationToUse, isLoop);
90+
}
91+
else
92+
{
93+
// 仅更新循环状态
94+
trackEntry.Loop = isLoop;
95+
}
96+
97+
trackEntry.TimeScale = 1; // 重置播放速度
98+
}
99+
else
100+
{
101+
// 无动画时清空轨道
102+
state.ClearTrack(0);
103+
}
104+
105+
// 同步皮肤:优先使用默认皮肤,否则取首个可用皮肤
106+
var skin = skeletonData.DefaultSkin;
107+
if (skin == null && skeletonData.Skins.Count > 0)
108+
{
109+
skin = skeletonData.Skins.Items[0];
110+
}
111+
112+
if (skeletonAnimation.skeleton.Skin != skin)
113+
{
114+
skeletonAnimation.skeleton.SetSkin(skin);
115+
skeletonAnimation.skeleton.SetSlotsToSetupPose(); // 强制刷新到初始姿态
116+
}
117+
}
118+
}
119+
}

Runtime/Extension/SkeletonDataAssetExtension.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)