# 运行时皮肤

皮肤用于控制skeleton在运行时中使用哪些附件. [皮肤](/spine-api-reference#Skin)是一个map, 其中键(key)是槽位和名称, 而值(value)是一个附件. 名称指的是Spine编辑器中定义的皮肤占位符名称, 并不一定是附件的名称. 这使得代码和动画可以用皮肤占位符名称来设置附件, 而不必引用具体的附件.

例如, 某个皮肤可能有一个key `slot=head,name=head`且key的值为 `attachment=fish-head`. 另一个皮肤也能有相同的key`slot=head,name=head`以及值`attachment=donkey-head`. 皮肤据此将代码和动画同实际使用的附件解耦. 代码和动画可使用名称`head`来更换附件, 但具体显示哪个附件取决于skeleton的当前皮肤.

Skeleton数据中定义的所有附件都存放在皮肤中. 不在Spine编辑器皮肤中的附件, 在运行时中会出现在名为`default`的皮肤里, 这里的皮肤名称与附件名称相同. 当Skeleton 的 `getAttachment`需要按名称查找附件时, 会先在skeleton的当前皮肤中查找, 找不到才会去SkeletonData的默认皮肤中查找.

# 自定义

Skeleton不受Spine编辑器中定义的皮肤所限制. 可在运行时创建一个空皮肤再填充附件. 例如, 某个Skeleton可以有一个狗头或蛇头, 也可以有羽翼或火翼. 为每个头部或翅膀部件单独创建皮肤是十分繁琐的, 尤其是要组合很多的时候. 替代方案是通过编程创建包含头部、翅膀或其他附件的皮肤.

# 附件分组

虽然皮肤的主要作用是解耦, 但是也可以用于附件分组. 皮肤通常用于切换Skeleton的整体外观.

皮肤也可以用来为附件子集分组. 例如游戏角色装备的某个"部件(item)"由多个附件组成的情况. 一件衬衫可能是由一个躯干附件加上两个袖子附件组成. 在这种情况下, 就可以创建包含3个衬衫附件的一套皮肤.

在运行时, Skeleton只能有一套皮肤(加上SkeletonData中的"default"皮肤作为后备). 也可以程序化地创建皮肤, 然后填充来自其他皮肤的附件. 如此便可将多个"部件"的皮肤组合适配skeleton. 

```
Skin newSkin = new Skin("new-skin"); // 1. Create a new empty skin
newSkin.addSkin(skeletonData.findSkin("shirt/pink"); // 2. Add items
newSkin.addSkin(skeletonData.findSkin("pants/green");
newSkin.addSkin(skeletonData.findSkin("shoes/sneakers");
```

在 Spine 编辑器中, 你可以使用[皮肤视图](/spine-skins-view)一次预览多套皮肤.

# 更换皮肤

在设置了一个新皮肤且Skeleton尚无皮肤时, 可在setup pose中见到附加的皮肤附件.

在设置了一个新皮肤但Skeleton已有一套皮肤时, 仅当槽位中已存在旧皮肤附件时才会附加新皮肤的附件. 否则运行时不会更换任何附件.

为确保当前皮肤正确配置了各个附件, 需要告知全部与附件有关的组件来重新设置槽位.
```
skeleton.setSkin(newSkin); // 1. Set the active skin
skeleton.setSlotsToSetupPose(); // 2. Use setup pose to set base attachments.
animationState.apply(skeleton); // 3. Use AnimationState to set attachments active in the current movement.
// 4. Set attachments that were manually changed.
```

如果该帧在调用animationState.apply前设置了皮肤, 则可忽略对`animationState.apply`的调用.

要实现任何其他行为, 均需要在更换皮肤后再设置附件.

# 创建附件

与运行时皮肤创建相似, 你也可以程序化地创建附件. 当需要创建大量附件时可有效地避免Spine中的繁琐操作.

Spine中附件的位置其实是附件相对于其父骨骼的位置. 当通过编程方式创建附件时, 需要一些约定来知道将附件放置在哪里。这里的主要问题是当图片尺寸不一时, 需要以不同方式定位图片.

为了解决这个问题, 可用留白足够多的模板图片来组装skeleton, 以便容纳各种附件. 这样便可从模板图片创建任意数量的附件, 且无需添加到Spine skeleton中. 在运行时替换掉模板图片附件, 纹理区域(texture region)便会随之改变。因为每张图片与对应模板图片尺寸一致, 它们会自动附加到骨骼的相同位置上.

创建美术资产时使用模板图像来标记骨骼位置十分有效, 此外, 附件图片中的留白部分可用纹理打包器或起来类似程序剥离.

[下一节: API参考](/spine-api-reference)
[上一节: 运行时skeleton](/spine-runtime-skeletons)
[Spine运行时指南: 目录]