# 玩家余额

> Use the SDK to manage player currency balances.

`PlayerBalances` 命名空间包含用于获取和更新玩家货币余额的所有方法。

这些方法将从 Authentication SDK 返回当前登录玩家的余额。

> **Note:**
>
> 此命名空间中的所有方法都可以抛出 [EconomyException](./exceptions.md#economyexception)。

## GetBalancesAsync##getbalances

检索当前用户的货币余额。可采用 `GetBalancesOptions`。

获取余额时，可以使用 `GetBalancesOptions` 设置获取余额的数量上限（1 到 100）。设置上限有助于分页。默认上限为 20。

以下示例代码检索当前用户的前五个余额，然后检索后五个余额，包括已从配置中删除的货币的余额。

```cs title="C#"
// Optional, defaults to 20
GetBalancesOptions options = new GetBalancesOptions
{
    ItemsPerFetch = 5
};

GetBalancesResult getBalancesResult = await EconomyService.Instance.PlayerBalances.GetBalancesAsync(options);
List<PlayerBalance> firstFiveBalances = getBalancesResult.Balances;
// do something with your balances

if (getBalancesResult.HasNext) {
    getBalancesResult = await getBalancesResult.GetNextAsync(options.ItemsPerFetch);
    List<PlayerBalance> nextFiveBalances = getBalancesResult.Balances;
    // do something with your balances
}
```

这些方法将返回 `GetBalancesResult`。请参阅 [GetBalancesResult](#getbalancesresults)。

### GetBalancesOptions##getbalancesoptions

`GetBalancesAsync` 调用的选项对象。它有以下字段：

* `ItemsPerFetch`：整数。默认为 20。使用此设置可将每次调用获取的最大余额数量设置为 1 到 100（包含 1 和 100）之间的数。

### GetBalancesResult##getbalancesresults

通过 `GetBalancesResult`，可分页查看检索到的余额列表。它包含以下字段：

* `Balances`：包含当前获取余额的 `List<PlayerBalance>`。

它具有以下方法：

* `GetNextAsync(int itemsToFetch = 20)`：此方法可异步获取更多结果。可以通过一个可选参数来限制获取的结果数量（1 到 100，默认为 20）。这将返回新结果，`Balances` 列表中同时包含原有物品和新获取的物品。

## SetBalanceAsync##setbalance

将指定货币的余额设置为指定值。

此方法可采用一项用于设置写锁的 `SetBalancesOptions` 对象。若提供了该对象，除非 `writeLock` 与先前读取时接收到的 `writeLock` 匹配，否则将抛出异常，以实现乐观并发。如果未提供，则无论数据中是否存在任何 `writeLock`，交易都会继续进行。

如果操作成功，此方法将在更新被应用后返回当前余额。

```cs title="C#"
string currencyID = "GOLD_BARS";
int newAmount = 1000;
string writeLock = "someLockValueFromPreviousRequest";
SetBalanceOptions options = new SetBalanceOptions
{
    WriteLock = writeLock
};

PlayerBalance newBalance = await EconomyService.Instance.PlayerBalances.SetBalanceAsync(currencyID, newAmount);
// OR
PlayerBalance otherNewBalance = await EconomyService.Instance.PlayerBalances.SetBalanceAsync(currencyID, newAmount, options);
```

### SetBalanceOptions##setbalanceoptions

`SetBalanceAsync` 调用的选项对象。它有以下字段：

* `WriteLock`：字符串。默认为 `null`。使用它来设置写锁，以实现乐观并发。请参阅[写锁](./common-objects.md#using-the-writelock)。

## IncrementBalanceAsync##incrementbalance

将指定货币的余额增加指定值。

此方法可采用一项用于设置写锁的 `IncrementBalancesOptions` 对象。若提供了该对象，除非 `writeLock` 与先前读取时接收到的 `writeLock` 匹配，否则将抛出异常，以实现乐观并发。如果未提供，则无论数据中是否存在任何 `writeLock`，交易都会继续进行。

如果操作成功，此方法将在更新被应用后返回当前余额。

```cs title="C#"
string currencyID = "GOLD_BARS";
int incrementAmount = 1000;
string writeLock = "someLockValueFromPreviousRequest";
IncrementBalanceOptions options = new IncrementBalanceOptions
{
    WriteLock = writeLock
};

PlayerBalance newBalance = await EconomyService.Instance.PlayerBalances.IncrementBalanceAsync(currencyID, newAmount);
// OR
PlayerBalance otherNewBalance = await EconomyService.Instance.PlayerBalances.IncrementBalanceAsync(currencyID, newAmount, options);
```

### IncrementBalanceOptions##incrementbalanceoptions

`IncrementBalanceAsync` 调用的选项对象。它有以下字段：

* `WriteLock`：字符串。默认为 `null`。使用它来设置写锁，以实现乐观并发。请参阅[写锁](./common-objects.md#using-the-writelock)。

## DecrementBalanceAsync##decrementbalance

将指定货币的余额减少指定值。

此方法可采用一项用于设置写锁的 `DecrementBalanceOptions` 对象。若提供了该对象，除非 `writeLock` 与先前读取时接收到的 `writeLock` 匹配，否则将抛出异常，以实现乐观并发。如果未提供，则无论数据中是否存在任何 `writeLock`，交易都会继续进行。

如果操作成功，此方法将在更新被应用后返回当前余额。

```cs title="C#"
string currencyID = "GOLD_BARS";
int decrementAmount = 1000;
string writeLock = "someLockValueFromPreviousRequest";
DecrementBalanceOptions options = new DecrementBalanceOptions
{
    WriteLock = writeLock
};

PlayerBalance newBalance = await EconomyService.Instance.PlayerBalances.DecrementBalanceAsync(currencyID, newAmount);
// OR
PlayerBalance otherNewBalance = await EconomyService.Instance.PlayerBalances.DecrementBalanceAsync(currencyID, newAmount, options);
```

### DecrementBalanceOptions##decrementbalanceoptions

`DecrementBalanceAsync` 调用的选项对象。它包含以下字段：

* `WriteLock`：字符串。默认为 `null`。使用它来设置写锁，以实现乐观并发。请参阅[写锁](./common-objects.md#using-the-writelock)。

## PlayerBalance##playerbalance

玩家余额代表玩家的一项货币余额。它包含以下字段：

* `CurrencyId`：该余额所代表的货币的 ID。
* `Balance`：玩家拥有的该货币的整数数量。
* `WriteLock`：当前的 `writeLock` 字符串。
* `Created`：此余额的创建日期。它是一个 [EconomyDate](./common-objects.md#economydate) 对象。
* `Modified`：此余额的修改日期。它是一个 [EconomyDate](./common-objects.md#economydate) 对象。

它还有以下辅助器方法：

### GetCurrencyDefinitionAsync##getcurrencydefinitionasync

这是获取此余额相关货币的货币定义的便捷方法。它返回 [CurrencyDefinition](./configuration.md#currencydefinition)。

```cs title="C#"
PlayerBalance myPlayerBalance = ... // Get a player balance from one of the above methods
CurrencyDefinition currencyDefForMyPlayerBalance = myPlayerBalance.GetCurrencyDefinitionAsync();
```

## BalanceUpdated##balanceupdated

可以订阅此事件，以便在 SDK 更新特定货币余额时收到通知。订阅者将收到已更新余额的货币 ID。

> **Note:**
>
> SDK 发起的操作（例如，更新玩家余额、进行购买）将调用此事件。因其他设备/服务端的更改而进行任何更新时不调用此事件。

```cs title="C#"
EconomyService.Instance.PlayerBalances.BalanceUpdated += currencyID => {
    Debug.Log($"The currency that was updated was {currencyID}");
};
```
