Clothing

## 什么是服装？

s&box 香肠人的预制服装，开发者和玩家都可以用它们来装扮自己的香肠人（Pawn）。你可以在主菜单中查看一些可用的服装。在某些游戏模式中，开发者可能希望手动设置玩家的服装，例如在团队之间创建视觉区分。您可以使用服装的资源 ID 通过资源库系统加载服装。

## 什么是资源 ID？

资源 ID 是 s&box 内部保存服装和其他资产参考的方式。您可以在游戏中添加以下控制台命令，查看可用服装名称和资源 ID 的列表。

```
/// <summary>
/// 调试控制台命令列出所有可用的玩家服装。
/// </summary>
[ConCmd.Admin]
public static void ListAllClothing()
{
 foreach ( var item in ResourceLibrary.GetAll<Clothing>() )
 {
 Log.Info( $"{item.Title} - {item.ResourceId}" );
 }
}

```

## 设置玩家服装

游戏模式必须实现一个穿衣系统，以防止赤身裸体的野蛮香肠人出现。s&box 自带的 **ClothingContainer** 类可抽象出衣服的加载，并防止添加衣服时可能发生的碰撞（如两件衬衫、两双鞋等）。

## 自动加载玩家默认服装

以下代码将为玩家穿上他们从主菜单中选择的任何服装。请注意，**Clothing.DressEntity** 可以为任何 Pawn 实例（如 NPC）穿上衣服。

### **MyPlayer.Clothing.cs**

```
public partial class MyPlayer
{
 public ClothingContainer Clothing { get; protected set; }

 /// <summary>
 /// 将衣服设置为玩家所穿的衣服
 /// </summary>
 public void UpdateClothes( Client cl )
 {
 Clothing ??= new();
 Clothing.LoadFromClient( cl );
 }
}

```

### **MyPlayer.cs**

```
public partial class MyPlayer : Player
{
 public override void Respawn()
 {
 UpdateClothes( Client );
 Clothing.DressEntity( this );
 }
}

```

## 手动设置玩家所穿服装

您还可以手动设置玩家的服装，忽略他们之前在主菜单中的配置。这对于团队游戏模式来说通常很重要。

### **MyPlayer.Clothes.cs**

```
public partial class MyPlayer
{
 public ClothingContainer Clothing { get; protected set; }

 private static readonly int[] TeamAClothing =
 {
 1846461341, // Police Cap.
 -923065548, // Suit Jacket.
 1761917151, // Tactical Vest.
 1194605997, // Smart Trousers.
 -1377292782 // Black Boots.
 };

 private static readonly int[] TeamBClothing =
 {
 -394380878, // Prison Jumpsuit.
 591027714 // Sneakers.
 };

 /// <summary>
 /// 根据玩家的队伍设置衣服
 /// </summary>
 public void UpdateClothes( Client cl )
 {
 Clothing ??= new ClothingContainer();

 var player = cl.Pawn as MyPlayer;

 // 清除任何先前装备的衣服。
 Clothing.Clothing.Clear();

 // 注意：您可以将此代码重构为一个 'GetTeamClothing' 方法。
 if ( player.Team == Team.A )
 {
 foreach ( var itemId in TeamAClothing )
 {
 Clothing.Toggle( ResourceLibrary.Get<Clothing>( itemId ) );
 }
 }
 else
 {
 foreach ( var itemId in TeamBClothing )
 {
 Clothing.Toggle( ResourceLibrary.Get<Clothing>( itemId ) );
 }
 }
 }
}

```

## 白名单服装类别

为了实现某种程度的自定义，您可能希望允许玩家配置自己的头发、皮肤等，同时强迫他们穿上特定的衬衫和鞋子。为此，您可以将某些服装类别列入白名单，并手动反序列化玩家的装备。

### **MyPlayer.Clothes.cs**

```
public partial class MyPlayer
{
 public ClothingContainer Clothing { get; protected set; }

 private static readonly Clothing.ClothingCategory[] WhitelistedAccessories =
 {
 Sandbox.Clothing.ClothingCategory.Skin, Sandbox.Clothing.ClothingCategory.Facial,
 Sandbox.Clothing.ClothingCategory.Hair
 };

 public void UpdateClothes( Client cl )
 {
 Clothing ??= new ClothingContainer();

 // Clear out any previously equipped clothing.
 Clothing.Clothing.Clear();

 // Only loads certain client configured clothing items.
 // E.g. Hair, Skin, etc.
 DeserializeAccessories( cl.GetClientData( "avatar" ) );

 // ... Set the rest of the player's clothing manually ...
 // (See above)
 }

 /// <summary>
 /// 反序列化客户端配件并为其提供装备。
 /// "Accessories" may include Hair, Skin, Etc.
 /// </summary>
 /// <param name="json"></param>
 private void DeserializeAccessories( string json )
 {
 if ( string.IsNullOrWhiteSpace( json ) )
 {
 return;
 }

 try
 {
 var entries = JsonSerializer.Deserialize<ClothingContainer.Entry[]>( json );
 foreach ( var entry in entries! )
 {
 var item = ResourceLibrary.Get<Clothing>( entry.Id );
 if ( item == null ) continue;
 if ( !WhitelistedAccessories.Contains( item.Category ) ) continue;

 Clothing.Toggle( item );
 }
 }
 catch ( System.Exception e )
 {
 Log.Warning( e, "Error deserializing accessories" );
 }
 }
}

```