playfabクラウドスクリプト用tipsメモ

PlayFabのクラウドスクリプト用。ゲーム作りに使いそうな処理をメモ書きストックしていこうかと思います。

###乱数生成
例)0～80までの整数を返すjavascript

```javascript
var seed = Math.floor( Math.random() * 80 )
```
Math.random()は0～1の小数を返すので、終端の値を掛けMath.floorで小数切り捨て。

###時間を格納＆現在の時間との秒数比較

playfabのサーバー側のみで時間を扱うとき。
時間を格納して、前回格納された時間と現在の時間を秒数で表示。
playfabに時間はぶちこめるが文字列になってしまうので再度時間に変換する。

※このスクリプト実行時にはあらかじめプレイヤーの「内部データ」にsavedtimeを作っておく必要があります。

```javascript

    //InternalData（内部データ）に保存した時間を取得
    var request = {
        "PlayFabId": currentPlayerId,
        "Keys": ["savedtime"]
    }
    var saveTimeObject= server.GetUserInternalData(request);
    var savedTimeString= saveTimeObject.Data["savedtime"].Value;
    
    //playfabから取得した「savedTimeString」は文字列。
    //文字列を渡せば時間変換してくれるDate.parseを使用して時間の比較ができるようになる
    var savedTime= Date.parse(savedTimeString);
    
    //現在の時間取得
    var nowTime = new Date();
 
    //比較
    var timeAnser = (nowTime - savedTime) / 1000;    //ミリ秒なので1000を掛けて秒数に
    log.info(timeAnser);        //これが結果。ログ出力テスト
    

    //最後に現在の時間をInternalData（内部データ）に再格納
    var request = {
        "PlayFabId": currentPlayerId,
        "Data": {"savedtime": nowTime }
    };
    server.UpdateUserInternalData(request);
```

###自分のインベントリにあるアイテムID、インスタンスIDの取得

『アイテム付与の際に、すでに同じアイテムを持っていた場合は限界突破』的な事をやりたい時、
既に〇〇って持っていたっけ？　という時に使いそう。

最初は「自分が所有しているアイテムIDのインスタンスを返すAPI」を探していたのだけども、そういうのは無くてフォーラムでこんな感じの投稿があったのでお借りいたしました。

[こちらのフォーラム投稿より]
(https://community.playfab.com/questions/6681/how-to-only-get-all-itemids-for-all-items-in-playe.html)

```javascript

    //格納する配列を作ってみる
    var ItemIDs = [];           //所有しているアイテムIDの配列
    var ItemInstanceIds = [];   //所有しているアイテム「インスタンスID」の配列
    var ItemDisplayNames = [];  //所有しているアイテム名の配列

    // インスタンスIDとは
    // スタックされていない場合、同じアイテムIDでも別なものの場合がある
    // ドラクエでやくそうを２つ所有している場合
    // 1番目にあるやくそうと、2番目にあるやくそうは違うインスタンスID

    var request = {
        "PlayFabId": currentPlayerId
    };


    var playerInventory = server.GetUserInventory(request);
    
    
    //返ってきた結果の.Inventory配列に情報が詰まっているので全て取得する
    for (var i in playerInventory.Inventory)
    {
        // アイテムID、インスタンスID、ディスプレイネームを取得
        var ItemId = playerInventory.Inventory[i].ItemId;
        var ItemInstanceId = playerInventory.Inventory[i].ItemInstanceId;
        var ItemDisplayName = playerInventory.Inventory[i].DisplayName;
        
        // 配列に格納していく
        ItemIDs.push(ItemId);
        ItemInstanceIds.push(ItemInstanceId);
        ItemDisplayNames.push(ItemDisplayName);
    }    

    // ログ出力
    log.info(ItemIDs);
    log.info(ItemInstanceIds);
    log.info(ItemDisplayNames);
```


###所有しているアイテムのカスタムデータ操作
自分の持っているアイテムのスキルレベルを3にしてみる、みたいな処理。
ItemInstanceIdは上記のアイテムインスタンスIDを取得したものを使えばよいかもと。

```javascript
    var request = {
        "PlayFabId": currentPlayerId,
        "ItemInstanceId": 該当のアイテムインスタンスIDを記載,
        "Data": {"SkillLv": 3}
    };

    var playerStatResult = server.UpdateUserInventoryItemCustomData(request);    
```

###（クライアント）クラウドスクリプトからのJSON受取

JSON扱うのに慣れてないのもあり、ドはまりした。
@_y_minamiさんが記事にされているUtf8Jsonも入れました。

[UnityでPlayFabのタイトルデータを取得して表示する](https://qiita.com/_y_minami/items/3396f832d868d52bbbaf#21-%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%A9%E3%82%A4%E3%82%B6%E3%81%AE%E7%94%A8%E6%84%8F)
[Unity：超高速なJsonパーサ Utf8Json＋WebGLの使い方、JsonUtilityの問題点](https://www.fast-system.jp/unity-utf8json-howto/)



```javascript:クラウドスクリプト側
//クラウドスクリプトのreturnがこうなっていると想定
    return {    messageValue: 128,
                messageValue2: 512       
            };
```


```c#:unity側
    public class ReceiveObject
    {
        //クラウドスクリプトと名前合わせないとだめなやーつ
        public int messageValue { get; set; }
        public int messageValue2 { get; set; }
    }

//・・・
//略
//・・・


//クラウドスクリプトが成功した時に呼ばれるコールバック
    private static void OnSucceceTestStone(ExecuteCloudScriptResult result)
    {

        //ExecuteCloudScriptResult 型のオブジェクトをJsonObject にキャストして入れる
        JsonObject jsonResult = (JsonObject)result.FunctionResult;

        //デシリアイズを掛ける。その時に先ほどのオブジェクトをToString
        ReceiveObject receiveObject = JsonSerializer.Deserialize<ReceiveObject>(jsonResult.ToString());

        //取得できる！
        Debug.Log(receiveObject.messageValue2);
        Debug.Log(receiveObject.messageValue2);
    }
```

###jsでの配列とオブジェクトが混在したものを生成する場合
playfabでこういうのを動的に作りたい場合意外にこんがらがる。
オブジェクトはプロパティで代入、配列はpushで入れる。

```javascript#:これを作るために
request={

        "CatalogVersion": "nissen_spring",  //カタログバージョンを指定
        "ItemGrants": [
            {
                "PlayFabId": currentPlayerId,
                "ItemId": "maguro"
            },

             {
                "PlayFabId": currentPlayerId,
                "ItemId": "sanma"
            }           
        ]
}
```

```javascript#:こうする
    var request = {};
    
    var ItemGrantArr = [];    
    var ItemGrant = {};    
    
    ItemGrant.PlayFabId = currentPlayerId;
    ItemGrant.ItemId = "maguro";
    
    ItemGrantArr.push(ItemGrant)
    
    ItemGrant.PlayFabId = currentPlayerId;
    ItemGrant.ItemId = "sanma";

    ItemGrantArr.push(ItemGrant);
    
    request.ItemGrants = ItemGrantArr;
    request.CatalogVersion = "nissen_spring";
    

    log.info(request);   
  ```  
###unityからplayFabにJsonを送る場合

一回パースする

```javascript#:クラウドスクリプト

handlers.hogehoge= function (args, context) {

    //argsにjsonが入ってるとする
    log.info(args);     //これは使えない（args.hogehogeでエラー）    
    json = JSON.parse( args );
    log.info(json);     //これを使う （json.hogehogeで使える） 

```