【GS2.Experience】戦闘に参加したパーティメンバーに経験値を加算するスクリプト

# 詰まっていたこと
GS2-Questのコンソールで、戦闘に参加したパーティメンバー全体に経験値を付与しようとしたところ、
プロパティIDを可変的に設定する方法がわからず、いろいろ模索しました。

クエストクリア報酬のアクションでFormationを使うとできるような記載がドキュメントにありましたが、
入手アクションを設定する項目でアクションの選択ができず、別途Script処理を呼び出す方法を考えました。

【補足】
ユーザー自身やキャラクター別の経験値は、経験値加算時に設定するプロパティIDによって
専用の枠が作成されるというのに気づくのに時間がかかりました。
（キャラ経験値は別途DB管理でランク閾値だけGS2のものを参照しようとか考えてました）

# スクリプト

GS2-Scriptで作成したコードは以下の通りです。

```Lua
userId = args.userId
experience = args.config[2].value
experience_client = gs2('experience')
resultItems={}

if not userId then
   userId = args.account.userId 
end

if not args.config then
    print("args.config is nil")
end
    
unitIds = {
    args.config[3].value, 
    args.config[4].value,
    args.config[5].value,
    args.config[6].value,
    args.config[7].value
}
print("userId " .. userId)

for i, id in ipairs(unitIds) do
    print("unitId[" .. i .. "]: " .. id)
        
    res = experience_client.add_experience_by_user_id({
      namespaceName="experience-0001",
      experienceName="characterLevel",
      userId = userId,
      experienceValue = tonumber(experience),
      propertyId = id .. ":characterLevel"
    })
    if(res.isError) then
        -- When error occurs
        fail(res['statusCode'], res['message'])
    end
        
    api_result = res.result
    item = api_result.item;
    table.insert(resultItems, item)
end

result = {
  permit=true,
  items = resultItems
}
```

引数（Scriptテスト時に引数のところにコピペすると、userIdとconfidのダブルクォーテーションが外れてエラーになるので注意）
``` json
{
"userId": "データオーナーのID",
"config" : [
{"key":"userId", "value": "データオーナーのID"},
{"key":"experience", "value":"500"},
{"key":"unitIds0", "value":"unit-001"}, 
{"key":"unitIds1", "value":"unit-002"},
{"key":"unitIds2", "value":"unit-003"},
{"key":"unitIds3", "value":"unit-004"},
{"key":"unitIds4", "value":"unit-005"}
]
}
```

# スクリプトについて

経験値加算のメソッド「add_experience_by_user_id」を使って対象のプロパティIDの累積経験値を加算していきます。
プロパティIDが未登録状態でも、新規で登録されます。

キャラごとの経験値プロパティIDは最終的に「unit-XXX:characterLevel」という名称で登録しています。
（add_experience_by_user_idの引数：propertyId）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2796558/6c58dbfa-e9c0-9139-eb53-7eb4207fb073.png)

スクリプトを実行した後の結果が以下のイメージ（加算経験値を500で渡した場合）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2796558/13c77aa4-1b9b-2cf4-5409-ec7cbea61d55.png)


# その他
クエスト報酬で参加キャラクターに経験値付与する正攻法はまだ探していきます。
UnityからJobQueueの呼び出しと、遅延処理ということでジョブ処理待機を制御することが課題です。
（クエスト報酬付与も結局JobQueueなので大差なし？）

# 参考
https://docs.gs2.io/ja/api_reference/experience/sdk/

https://app.gs2.io/docs/index.html#d08151a818

(TIPS: パーティに編成されたキャラクターへの経験値付与 がやりたかった)

# 追記　2023/6/11
技術サポートのフォーラムで質問し、実現するための正しい設定方法を教えていただきました。

contentsのcompleteAcquireActionsで、request内にacquireActionの項目を追加し、経験値加算のアクション名とそのアクション（スタンプシート）に渡すパラメータを追記することで実現できました。

acquireActionで渡すpripatyIdには#{propatyId}を設定することで、
指定したFormationのindexに紐づくプロパティIDリストを取得してくれるそうです。
コンソール上でクエストクリア処理を試すと、経験値加算のアクションは一度JobQueueにとどまり
手動実行が必要ですが、無事Formationのindex0に設定しているプロパティIDに一致する経験値への加算ができました。

``` JSON
{
    "action": "Gs2Formation:AcquireActionsToFormProperties",
    "request": {
        "namespaceName": "formation-0001",
        "userId": "#{userId}",
        "moldName": "partyModel",
        "index": 0,
        "acquireAction": {
            "action": "Gs2Experience:AddExperienceByUserId",
            "request": {
                "namespaceName":"experience-0001",
                "userId": "#{userId}",
                "experienceName": "characterLevel",
                "propertyId": "#{propertyId}",
                "experienceValue": 1000
              }
        },
        "config": []
    }
}
```


サポートご担当の方、ありがとうございました。