【Unity初心者】Unityでネットゲームを作りたい【4】やっぱりログイン時に、新規か判断してプレーヤーデータを読み書きしたい

https://qiita.com/ysyss5500/items/4aeb23639a8cf3d67376

### やっぱりログイン時に、新規か判断してプレーヤーデータを読み書きしたい
___
やっぱ、読み込むだけじゃゲームにならない
空のプレーヤーデータを読もうとするとエラーになるし
何をしても理解してないのでエラーばかり...
ちとログインの方法をわかりやすいのに変更
試行錯誤して行きつきました
[kan](https://kan-kikuchi.hatenablog.com/entry/PlayFabLogin)さんのPlayFabログイン時のスクリプトをあれこれいじって何とか形になりました
ちなみにこちらのPlayFabの導入方法（SDKを後入れ）すればマイクロソフトアカウントでのログインが可能になります

PlayFabLogin.cs
```rd
using System;
using PlayFab;
using PlayFab.ClientModels;
using UnityEngine;

/// <summary>
/// PlayFabのログイン処理を行うクラス
/// </summary>
public class PlayFabLogin : MonoBehaviour
{
    private bool _shouldCreateAccount;//アカウントを作成するか    
    private string _customID;//ログイン時に使うID
    
    ///ここでaを数字として
    public int a;

    //=================================================================================
    //ログイン処理
    //=================================================================================
    public void Start()
    {
        Login();

        if (a == 0)
        {
            ////ここに通常ログイン時の処理（プレーヤデータ取得）
            Debug.Log("通常ログイン");
            Debug.Log(a);
        }
        else if (a == 1)
        {
            ///ここに新規ログイン時の処理（プレーヤデータ初期データ書込み）
            Debug.Log("新規ログイン");
            Debug.Log(a);
        }
        else
        {
            Debug.Log("エラー");
            Debug.Log(a);
        }

        ////ここにタイトルデータ取得処理（もしくは他で）
    }


    //ログイン実行
    private void Login()
    {
        _customID = LoadCustomID();
        var request = new LoginWithCustomIDRequest { CustomId = _customID, CreateAccount = _shouldCreateAccount };//補足　既にアカウントが作成されており、CreateAccountがtrueになっていてもエラーにはならない
        PlayFabClientAPI.LoginWithCustomID(request, OnLoginSuccess, OnLoginFailure);
    }

    //ログイン成功
    private void OnLoginSuccess(LoginResult result)
    {
        //アカウントを作成しようとしたのに、IDが既に使われていて、出来なかった場合
        if (_shouldCreateAccount == true && result.NewlyCreated == false)
        {
            Debug.LogWarning("CustomId :" + _customID + "は既に使われています。");
            Login();//ログインしなおし
            return;
        }
        //アカウント新規作成できたらIDを保存
        if (result.NewlyCreated == true)
        {
            SaveCustomID();
        }
        Debug.Log("ログイン成功!!");        
    }

    //ログイン失敗
    private void OnLoginFailure(PlayFabError error)
    {
        Debug.LogError("PlayFabのログインに失敗\n" + error.GenerateErrorReport());
    }

    //=================================================================================
    //カスタムIDの取得
    //=================================================================================

    //IDを保存する時のKEY
    private static readonly string CUSTOM_ID_SAVE_KEY = "CUSTOM_ID_SAVE_KEY";

    //IDを取得
    private string LoadCustomID()
    {
        //IDをセーブデータから取得
        string id = PlayerPrefs.GetString(CUSTOM_ID_SAVE_KEY);

        //idの中身がnullもしくは空の文字列("")の場合は_shouldCreateAccountはtrueになる。
        _shouldCreateAccount = string.IsNullOrEmpty(id);　//新規にするには、= true; にする

        //idの中身がない場合、文字列を新規作成
        if (_shouldCreateAccount == true)
        {
            //////////////////////ここでaを1にして判定
            a++;
            //////////////////////
            return GenerateCustomID();//文字列を新規作成
        }
        else
        {
            return id;//セーブされた文字列を返す
        }
    }

    //IDの保存
    private void SaveCustomID()
    {
        PlayerPrefs.SetString(CUSTOM_ID_SAVE_KEY, _customID);
    }

    //=================================================================================
    //カスタムIDの生成
    //=================================================================================

    //IDを生成する
    //ユニークな文字列をGuidを使用し生成
    //https://docs.microsoft.com/ja-jp/dotnet/api/system.guid.tostring?redirectedfrom=MSDN&view=netframework-4.8#System_Guid_ToString_System_String_
    private string GenerateCustomID()
    {
        //Guidの構造体生成
        Guid guid = Guid.NewGuid();
        return guid.ToString("N");//書式指定子はNを指定　詳細は「Guid.ToString メソッド」のドキュメント参照
    }
}
```

どこに新規の判定があって、どこに書き込んでどこで条件分岐するのか、何で条件分岐するのか
ホント悩んで色々やってみました

結果、aという変数作って０なら通常ログイン、1なら新規ログインと判断でき、処理できるようになった
trueとfalseが一般的なんだろーがこっちのがわかりやすい（私）

んで毎回新規扱いにして、チェックしたかったので
```rd
//idの中身がnullもしくは空の文字列("")の場合は_shouldCreateAccountはtrueになる。
_shouldCreateAccount = string.IsNullOrEmpty(id);　//新規にするには、= true; にする
```
これを=true;に変更してやってました
PlayFabのプレーヤーがいっぱいになった(-_-;)
___
###### プレイヤーデータの読み書き

ここで[【Unity初心者】Unityでネットゲームを作りたい【2】Json取入](https://qiita.com/ysyss5500/items/7078965fc5ea6e203d55)で作ったJsonデータの形がちょいと違うのに気が付く

PlayFabではキーに配列名で値に[....]で指定みたい

色々試した結果、後でＪｓｏｎとして使えればいいし、初期登録の時だけだからとりえずそのまま書き込んじゃえ！となった
そして　”...”　の中に「”」これが使えない
＼"（バックスラッシュ）ってやると使えるらしいが、全角でもおｋなんか？
キーボードの右下にひらがなの「め」の所にあるが、押してみると￥がでるー
調べてみると半角の＼の代わりに￥の半角でおｋみたい
Excelのやつを改造して￥が出るようにした
試すと成功ﾌｳ

試行錯誤した結果、上のスクリプトのstart()の中の条件分岐に何書いてもエラーの連続でしたお勧めしません
行きついたのがこれです

PlayFabLogin.cs
```rd
using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework.Interfaces;
using PlayFab;
using PlayFab.ClientModels;
using UnityEditor.PackageManager;
using UnityEngine;
using static PlayFabLogin;


/// <summary>
/// PlayFabのログイン処理を行うクラス
/// </summary>
public class PlayFabLogin : MonoBehaviour
{
    private bool _shouldCreateAccount;//アカウントを作成するか    
    private string _customID;//ログイン時に使うID

    //=================================================================================
    //ログイン処理
    //=================================================================================
    public void Start()
    {
        Login();
    }

    /// 新規登録時の初期データ書込み処理
    public static void SetUserData()

        {

        PlayFabClientAPI.UpdateUserData(new UpdateUserDataRequest()
        {
            Data = new Dictionary<string, string>() {
            {"PlayerData","[{\"name\":\"あああ\",\"HP\":\"0\",\"ST\":\"0\",\"DE\":\"0\",\"SP\":\"0\",\"Rank\":\"N\"},{\"name\":\"アイテム1\",\"HP\":\"0\",\"ST\":\"0\",\"DE\":\"0\",\"SP\":\"0\",\"Rank\":\"N\"},{\"name\":\"アイテム2\",\"HP\":\"0\",\"ST\":\"0\",\"DE\":\"0\",\"SP\":\"0\",\"Rank\":\"N\"},{\"name\":\"アイテム3\",\"HP\":\"0\",\"ST\":\"0\",\"DE\":\"0\",\"SP\":\"0\",\"Rank\":\"N\"}]"},
            {"PlayerMons", "[{\"name\":\"スライム1\",\"HP\":\"1\",\"ST\":\"1\",\"DE\":\"1\",\"SP\":\"1\",\"Rank\":\"N\"},{\"name\":\"スライム2\",\"HP\":\"1\",\"ST\":\"1\",\"DE\":\"1\",\"SP\":\"1\",\"Rank\":\"N\"},{\"name\":\"スライム3\",\"HP\":\"1\",\"ST\":\"1\",\"DE\":\"1\",\"SP\":\"1\",\"Rank\":\"N\"},{\"name\":\"スライム4\",\"HP\":\"1\",\"ST\":\"1\",\"DE\":\"1\",\"SP\":\"1\",\"Rank\":\"N\"},{\"name\":\"スライム5\",\"HP\":\"1\",\"ST\":\"1\",\"DE\":\"1\",\"SP\":\"1\",\"Rank\":\"N\"}]"}
        }
        },
        result => Debug.Log("新規データ書き込み成功"),
        error => {
            Debug.Log("エラーです");
            Debug.Log(error.GenerateErrorReport());
        });
    }
    /// 新規ではない場合のデータ読み込み処理
        public static void GetUserData()
    {
        var request = new GetUserDataRequest();
        PlayFabClientAPI.GetUserData(request, OnSuccess, OnError);

        void OnSuccess(GetUserDataResult result)
        {
            Debug.Log("GetUserData: Success!");
            Debug.Log(result.Data["PlayerData"].Value);
            Debug.Log(result.Data["PlayerMons"].Value);
        }

        void OnError(PlayFabError error)
        {
            Debug.Log("GetUserData: Fail...");
            Debug.Log(error.GenerateErrorReport());
        }
    }

        //ログイン実行
    private void Login()
    {
        _customID = LoadCustomID();
        var request = new LoginWithCustomIDRequest { CustomId = _customID, CreateAccount = _shouldCreateAccount };//補足　既にアカウントが作成されており、CreateAccountがtrueになっていてもエラーにはならない
        PlayFabClientAPI.LoginWithCustomID(request, OnLoginSuccess, OnLoginFailure);
    }

    //ログイン成功
    private void OnLoginSuccess(LoginResult result)
    {
        //アカウントを作成しようとしたのに、IDが既に使われていて、出来なかった場合
        if (_shouldCreateAccount == true && result.NewlyCreated == false)
        {
            Debug.LogWarning("CustomId :" + _customID + "は既に使われています。");
            Login();//ログインしなおし
            return;
        }
        //アカウント新規作成できたらIDを保存
        if (result.NewlyCreated == true)
        {
            SaveCustomID();
            ///ここで新規データ書き込み処理を行う
            SetUserData();
        }
        else
        {
            ///ここで通常ログインでのプレイヤーデータ読み込み処理を行う
            GetUserData();
        }
            Debug.Log("ログイン成功!!");
    }

    //ログイン失敗
    private void OnLoginFailure(PlayFabError error)
    {
        Debug.LogError("PlayFabのログインに失敗\n" + error.GenerateErrorReport());
    }

    //=================================================================================
    //カスタムIDの取得
    //=================================================================================

    //IDを保存する時のKEY
    private static readonly string CUSTOM_ID_SAVE_KEY = "CUSTOM_ID_SAVE_KEY";

    //IDを取得
    private string LoadCustomID()
    {
        //IDをセーブデータから取得
        string id = PlayerPrefs.GetString(CUSTOM_ID_SAVE_KEY);

        //idの中身がnullもしくは空の文字列("")の場合は_shouldCreateAccountはtrueになる。
        _shouldCreateAccount = string.IsNullOrEmpty(id);　//新規にするには、= true; にする

        //idの中身がない場合、文字列を新規作成
        if (_shouldCreateAccount == true)
        {
            return GenerateCustomID();//文字列を新規作成
        }
        else
        {
            return id;//セーブされた文字列を返す
        }
    }

    //IDの保存
    private void SaveCustomID()
    {
        PlayerPrefs.SetString(CUSTOM_ID_SAVE_KEY, _customID);
    }

    //=================================================================================
    //カスタムIDの生成
    //=================================================================================

    //IDを生成する
    //ユニークな文字列をGuidを使用し生成
    //https://docs.microsoft.com/ja-jp/dotnet/api/system.guid.tostring?redirectedfrom=MSDN&view=netframework-4.8#System_Guid_ToString_System_String_
    private string GenerateCustomID()
    {
        //Guidの構造体生成
        Guid guid = Guid.NewGuid();
        return guid.ToString("N");//書式指定子はNを指定　詳細は「Guid.ToString メソッド」のドキュメント参照
    }
}
```
ここでは/表示になってるけどMVSでは￥表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/c9737e5d-edb6-b6c2-3364-c4dca8983b79.png)
こんな感じで成功
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/ab37f014-7985-db7a-c86c-296d43c87cbc.png)

新規の時は書き込んで、新規じゃないときはデータをPlayFabからもってこいって事

これ大事
```
private void OnLoginSuccess(LoginResult result)
    {
    //ここにGetUserData();とか書くみたい
    ｝
```    
[UnityからPlayFabのユーザーデータをCRUDする](https://qiita.com/_y_minami/items/5914b2ef89a8c83444b7)こちらを参考にしました
[クイックスタート: プレイヤー データを設定して取得する](https://learn.microsoft.com/ja-jp/gaming/playfab/features/playerdata/quickstart)こちらも参考にしました

PlayFabに書いた直後に読み込むとエラーでます
多分反映されるまでちょいと時間かかるみたい（何秒か

usingの所は使ってないのも書いてあるので、気になる方は消してください（いろいろやった形跡がｗ
プログラムが順番でないから、昔やってた私は頭使います。。。
この処理してここ飛んでさらにここ飛んでｗ
変なところに書くとすぐエラー
むずい

タイトルデータも同じようにやれば読み込めるみたいなので次回挑戦して、そのデータをどこのシーンでも使えるようにして
表示等出来るようにしなければ！

あとプレーヤー名を「Player0001」みたいにして、新規の時に0002と増えて名前が被らないようにもしたい
タイトルデータ使えば出来るかな？

←前  [【Unity初心者】Unityでネットゲームを作りたい【3】PlayFabログインと同時にやりたい](https://qiita.com/ysyss5500/items/1338d95f2774e247478a)

[【Unity初心者】Unityでネットゲームを作りたい【5】PlayFabからプレイヤーデータ(Json)・タイトルデータ(Json)をログイン（新規も）時に取得して配列に設置後、どこでも使えるようにしたい](https://qiita.com/ysyss5500/items/9d76c18c054f8a6881f3)　次→

https://qiita.com/ysyss5500/items/4aeb23639a8cf3d67376