創作世界のいろいろ〜AdobeとかC#とか

絵を描く人がC#とか3Dとか動画編集とかやる為の備忘録

【NCMB】Unityで会員管理内の独自フィールドを取得する

ユーザーがメモしたときにメモを一覧にして記憶できる機能を実装したくて調べてみました。

会員管理の独自フィールドとは

ユーザーだけが取得できるデータをNCMBで管理したいときに作成します。会員管理に独自フィールド(phonenumberとか)を設定できます。

指定可能な型は文字列、int、配列、オブジェクト、緯度経度。

※ランキングに反映させるスコアなどは、一般的にデータストアで管理します。

 

結果

できました(条件付き)

課題

Json型で送受信したいがうまくいかない

 

手順

まず、NCMBのダッシュボード上で独自フィールドを新規追加しておきます。

テスト用に予めカンマで区切っておいた文字列を登録しました。
※ここで本当はJsonにしたかった。でもNCMB上でオブジェクト型にはならず、配列型になってしまいます。
そして配列型ならば、と色々Unity側で変換させようと思いましたが私の経験値では無理でした…

 


Unityで、下記のようなscriptを追加します。


if (currentUser.ContainsKey("userMemo")) { string toString = currentUser["userMemo"] as string; toLst = toString.Split(','); toList(toLst); } else { UnityEngine.Debug.Log("userMemo not found."); } public void toList(string[] toLst) { this.toLst = toLst; var userMemoList = new List<userMemoModel>(); userMemoList.Add(new userMemoModel { Title = toLst[0], Date = toLst[1], Memo = toLst[2], }); Debug.Log(userMemoList[0].Title + "タイトルを入力"); Debug.Log(userMemoList[0].Date + "メモした日"); Debug.Log(userMemoList[0].Memo + "メモ"); } public class userMemoModel { public string Title { get; set; } public string Date { get; set; } public string Memo { get; set; } }

以下の部分です

User.ContainsKey("userMemo")

Keyの名前で検索して、フィールドがある場合はtrueを返します。

そして、以下の部分で実際に値を取得(string変換も)しています。

currentUser["userMemo"] as string;

複数の値ではなく単一の値であれば、これでUnity内で操作ができるはずです。

 

今回はリスト化したいので、NCMBUser から文字列を取得したら、カンマ区切りでリスト<string>化しています。

toLst = toString.Split(',');

その後、そのリストをリスト<カスタムクラス>に割り当てます。

userMemoList[0].~~ 部分がきちんとNCMBで登録した文字列になってますね。

これでどんどんAddしていけば、タイトル、日付、メモの内容を一覧で管理できるようになります。機種変更されても問題無しです。

でも別記事と同じ方法になってしまいました。機能はしてるので今はこれで良しとします。。

メモ技術は社会人にとっては超重要だと思います*

【連載 Unity初心者向け】歴史学習アプリを作る(5 string配列→List<カスタムクラス>変換)

本記事ではLinqの使い方配列→カスタムクラス使用のListへ変換する解説を行います。初心者の方にわかりづらいLinqと配列→複数型を使用したListへの変換ですが、とても使える構文だと思います。私も勉強中なので一緒に学習いただけると良いかもです。

下記の続き

matsrikagraphic.hatenablog.com

前回の記事で、NCMBのファイルストアからDLしたcsvをstring配列に格納するところまで終わりました。ただ、前回のままでは、最後の解説文と最初の問題IDが一つの値になってしまっています。なので、最後の解説文の最後に『' , '』を入れて再度アップロードします。

 

String配列の問題集をカスタムクラスを使用したListへ入れる

完了したら、次に前回記事のContentsDownloader.csを下記のように変更します。

public class ContentsDownloader : MonoBehaviour
{
    [SerializeField] string sourceFileName;//~~~.csvのファイル名をインスペクターから指定する
    [SerializeField] int sourceFileValues;//インスペクターから配列数を指定する

    private string[] _allQuestions;

    void Start()
    {
        QuizContentManager();
    }

    public void QuizContentManager()
    {
        var file = new NCMBFile(sourceFileName);// NCMBFileを初期化
        _allQuestions = new string[sourceFileValues];// 指定した値の数で配列を作成

        // データを取得する (FetchAsync は NCMBAPI)
        file.FetchAsync((byte[] fileData, NCMBException error) =>
        {
            if (error != null) //失敗
            {
                Debug.Log(error);
            }
            else //成功
            {
                QuizContentsDL(fileData);
            }
        });
    }

    public void QuizContentsDL(byte[] fd)
    {
        // 受け取った byte[] を string 化する
        var sourceText = System.Text.Encoding.UTF8.GetString(fd);
        // 指定した値の数で配列を作成
        //var allQuestoins = new string[sourceFileValues];

        _allQuestions = sourceText.Split(',');

        for (int i = 0; i < _allQuestions.Length; i++)
        {
            //Debug.Log(_allQuestions[i]);
        }
        var QuizContents = new List<QuizContent>();
        //カスタムクラスにそれぞれの値をaddする
        for (int n = 0; n < 3; n++)
        {
            QuizContents.Add(new QuizContent
            {
                ID = int.Parse(_allQuestions[0 + n * 11]),
                QuizSentence = _allQuestions[1 + n * 11],
                Image_filename = _allQuestions[2 + n * 11],
                Selection_a = _allQuestions[3 + n * 11],
                Selection_b = _allQuestions[4 + n * 11],
                Selection_c = _allQuestions[5 + n * 11],
                Answer = _allQuestions[6 + n * 11],
                Genre_Era = _allQuestions[7 + n * 11],
                Genre_About = _allQuestions[8 + n * 11],
                Stage = int.Parse(_allQuestions[9 + n * 11]),
                Infomation = _allQuestions[10 + n * 11],
            });
        }
    }

    public class QuizContent
    {
        public int ID { get; set; }
        public string QuizSentence { get; set; }
        public string Image_filename { get; set; }
        public string Selection_a { get; set; }
        public string Selection_b { get; set; }
        public string Selection_c { get; set; }
        public string Answer { get; set; }
        public string Genre_Era { get; set; }
        public string Genre_About { get; set; }
        public int Stage { get; set; }
        public string Infomation { get; set; }
    }
}

主に追加したことは、csvのカラムに合わせたpublic class QuizContentを作成したこと、 NCMB APIのFetchasyncのelseの中にあった命令を外部の関数(メソッド)へ移したことです。

そして、作成したカスタムクラスへstring配列をそれぞれ格納しています。

上記コードで、問題集のデータが、カスタムクラスのID毎に管理できるようになります。

 

問題毎に各値を抜き出せるかLinqを使って確認する。

更に、ContentsDownloader.csを下記のように修正します。全文を載せます。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using NCMB;
using UnityEngine;

public class ContentsDownloader : MonoBehaviour
{
    [SerializeField] string sourceFileName;//~~~.csvのファイル名をインスペクターから指定する
    [SerializeField] int sourceFileValues;//インスペクターから配列数を指定する

    private string[] _allQuestions;

    void Start()
    {
        QuizContentManager();
    }

    public void QuizContentManager()
    {
        var file = new NCMBFile(sourceFileName);// NCMBFileを初期化
        _allQuestions = new string[sourceFileValues];// 指定した値の数で配列を作成

        // データを取得する (FetchAsync は NCMBAPI)
        file.FetchAsync((byte[] fileData, NCMBException error) =>
        {
            if (error != null) //失敗
            {
                Debug.Log(error);
            }
            else //成功
            {
                QuizContentsDL(fileData);
            }
        });
    }

    public void QuizContentsDL(byte[] fd)
    {
        // 受け取った byte[] を string 化する
        var sourceText = System.Text.Encoding.UTF8.GetString(fd);
        // 指定した値の数で配列を作成
        //var allQuestoins = new string[sourceFileValues];

        _allQuestions = sourceText.Split(',');

        for (int i = 0; i < _allQuestions.Length; i++)
        {
            //Debug.Log(_allQuestions[i]);
        }
        var QuizContents = new List<QuizContent>();
        //カスタムクラスにそれぞれの値をaddする
        for (int n = 0; n < 3; n++)
        {
            QuizContents.Add(new QuizContent
            {
                ID = int.Parse(_allQuestions[0 + n * 11]),
                QuizSentence = _allQuestions[1 + n * 11],
                Image_filename = _allQuestions[2 + n * 11],
                Selection_a = _allQuestions[3 + n * 11],
                Selection_b = _allQuestions[4 + n * 11],
                Selection_c = _allQuestions[5 + n * 11],
                Answer = _allQuestions[6 + n * 11],
                Genre_Era = _allQuestions[7 + n * 11],
                Genre_About = _allQuestions[8 + n * 11],
                Stage = int.Parse(_allQuestions[9 + n * 11]),
                Infomation = _allQuestions[10 + n * 11],
            });
        }
        SortQuizContents(QuizContents);

    }

public void SortQuizContents(IEnumerable<QuizContent> qc)
    {
        IEnumerable<QuizContent> sortquizContents = from QuizContent in qc where QuizContent.ID == 9990 select QuizContent;

        foreach (QuizContent quizContent in sortquizContents)
        {
            Debug.Log(quizContent.ID);
            Debug.Log(quizContent.QuizSentence);

        }
    }


    public class QuizContent
    {
        public int ID { get; set; }
        public string QuizSentence { get; set; }
        public string Image_filename { get; set; }
        public string Selection_a { get; set; }
        public string Selection_b { get; set; }
        public string Selection_c { get; set; }
        public string Answer { get; set; }
        public string Genre_Era { get; set; }
        public string Genre_About { get; set; }
        public int Stage { get; set; }
        public string Infomation { get; set; }
    }
}

追加したのは下記の部分です

public void SortQuizContents(IEnumerable<QuizContent> qc)
    {
        IEnumerable<QuizContent> sortquizContents = from QuizContent in qc where QuizContent.ID == 9990 select QuizContent;

        foreach (QuizContent quizContent in sortquizContents)
        {
            Debug.Log(quizContent.ID);
            Debug.Log(quizContent.QuizSentence);

        }
    }

Linqを使用してフィルターをかけています。

 IEnumerable<QuizContent> sortquizContents = from QuizContent in qc where QuizContent.ID == 9990 select QuizContent;

この一行で最初の問題だけを抜き出しています。

IEnumerable は、列挙可能にするListというイメージで、Listに似た使い方ができます。

Enumという列挙型変数がありますよね。

matsrikagraphic.hatenablog.com

ableというのは「〜可能」という意味になるので、そのままEnumerable<T>は列挙可能リストという感じで覚えてもらうと良いと思います。それ以上詳しいことは初心者なので現時点では私は分かりません。。

 

=の後の右辺がLinq構文です。

from QuizContent in qc where QuizContent.ID == 9990 select QuizContent;

色分けすると分かりやすいと思います。

こうすると何が確認できるかというと、このForeach文を見るように、


        foreach (QuizContent quizContent in sortquizContents)
        {
            Debug.Log(quizContent.ID);
            Debug.Log(quizContent.QuizSentence);

        }

QuizSentenceが、ID9990に紐づいたQuizSentenceだけ呼ばれるようになります。

つまり起動すると、ID9990である一問目だけを抜き出して書き出してくれるのです。

後に何も続いていないですよね?

一行でデータにフィルタリングをかけられるのです。

今現在、foreachでくくってる意味はありません。

foreachでくくるのは、フィルタリングに対して複数の項目が該当する場合に繰り返すためです。なので、仮に二問目のID9991の問題もIDを9990に変更してみると、一問目と二問目のID番号と問題文が表示されます。

これがLinqのメリットです。

 

Q. 引数ってなんで使うの?
A. 使う理由がずっと私も分かりませんでした。引数を使ってるのは、関数を分けるためです。間接的にこうやってローカル変数からローカル変数へ渡してあげると、関数(メソッド)を分けて同じ値の変数を操作することができます。

次回はUI作成にすすもうと思います。

**Linqの解説とC#基礎学習にはコレが絶対おすすめ!!**

**私も↑を読んで勉強しています**

とくにピーコックアンダーソンさんの本は分かりやすいです。

【連載 Unity初心者向け】歴史学習アプリを作る(4 csvデータをunityへDLする)

この記事の続き

matsrikagraphic.hatenablog.com

MCNBのファイルストアへアップロードしたcsvデータをDLしてstring配列に直し、Unityのコンソールに出せるまでをやります。下記のように↓

最小限の実装scriptはこちら↓

using System;
using System.Collections;
using System.Collections.Generic;
using NCMB;
using UnityEngine;

public class ContentsDownloader : MonoBehaviour
{
    [SerializeField] string sourceFileName;//~~~.csvのファイル名をインスペクターから指定する

    private void Start()
    {
        var file = new NCMBFile(sourceFileName);// NCMBFileを初期化

        // データを取得する (FetchAsync は NCMBAPI)
        file.FetchAsync((byte[] fileData, NCMBException error) =>
        {
            if (error != null) //失敗
            {
                Debug.Log(error);
            }
            else //成功
            {
                // 受け取った byte[] を string 化する
                var sourceText = System.Text.Encoding.UTF8.GetString(fileData);

                //11colums * 3rows = 0始まりで33個の値なので32
                var allQuestoins = new string[32];

                allQuestoins = sourceText.Split(',');
                for (int i = 0 ; i <allQuestoins.Length ; i++)
                {
                    
                    Debug.Log(allQuestoins[i]);
                }

            }
        });

    }

まずはNCMBへクイズデータをアップロード

NCMBへアップロードするのはcsvデータです。

下記記事参考にさせていただきました。

negi-lab.blog.jp

上記記事に書かれているように、csvデータをMCNBのファイルストアでアップロードすれば、いちいちUnity上で何かを修正することなく、クイズのデータを更新することが可能になります。

きちんとした形にするのであれば上記記事参考にしていただいたほうが良いです。(確実にDLが完了した状態で次の手順にすすんだりとか、多分)

本記事ではもっと簡易的に実装します。

 

はじめに、下記のようなcsvを作成しました。

エクセルでも良いと思うのですが、エクセルで作成したcsvだとUnicodeの変換がうまくいかないです。私は下記のアプリを使用しています。

Easy CSV Editor

Easy CSV Editor

  • VDT LABS S.R.L.
  • 開発ツール
  • ¥1,500

apps.apple.com

このエディターは有料ですが、JSON変換、EXCEL変換などにも対応しており、SQLへデータをJSON形式等でアップロードする際にも日本語をきちんと変換してくれるのでストレスが無くて良いと思っています。Windowsで販売されてるかは分かりません。

 

これをMCNBのファイルストアへアップロードします。

アップロードすると下記のように追加できたことが確認できます。

このファイル名を.csvの拡張子まで含めて、Unityのインスペクター上で入力します。

 

GameObjectとアタッチするScriptを作成する

新たに「ContentsDownloader.cs」というScriptと「ContentsManager」というGameObjectを作成しました。(名前は自由でいいです)

Script内には、冒頭にあるコードを記述します。

using System;
using System.Collections;
using System.Collections.Generic;
using NCMB;
using UnityEngine;

public class ContentsDownloader : MonoBehaviour
{
    [SerializeField] string sourceFileName;//~~~.csvのファイル名をインスペクターから指定する

    private void Start()
    {
        var file = new NCMBFile(sourceFileName);// NCMBFileを初期化

        // データを取得する (FetchAsync は NCMBAPI)
        file.FetchAsync((byte[] fileData, NCMBException error) =>
        {
            if (error != null) //失敗
            {
                Debug.Log(error);
            }
            else //成功
            {
                // 受け取った byte[] を string 化する
                var sourceText = System.Text.Encoding.UTF8.GetString(fileData);

                //11colums * 3rows = 0始まりで33個の値なので32
                var allQuestoins = new string[32];

                allQuestoins = sourceText.Split(',');
                for (int i = 0 ; i <allQuestoins.Length ; i++)
                {
                    
                    Debug.Log(allQuestoins[i]);
                }

            }
        });

    }

Inspecor上で先ほどアップロードしたcsvのファイルネームをコピペしてください。

このファイル名ですね

これだけでOKです。

 

シーンマネージャーでシーン遷移

今回、タイトル画面とは別のシーンで作成したので、過去記事で作成した「TitleManager.cs」の下記部分を修正します。

using UnityEngine.SceneManagement;

    //~~~~~以下省略

    //Scene移動(最後のHelloButton)
    public void ChangeScene()
    {
        SceneManager.LoadScene("MainMenuScene");
    }
}

最後に表示されるHelloButtonにこのメソッドを適用させます。

 

これで起動すれば、コンソールにcsvデータが値ごとに順番に出てくるはずです。

 

次回はちょっとしたバグとカスタムクラスへ落とし込む作業

このままでは、ちょっと問題があります。

最後のクイズの解説文と、次の問題のIDが一つの値にくっついてしまっています。

これは最後の文章の次が改行('\n')になっていて、カンマ( ' , ' )で区切られてる訳ではないからです。

Scriptの中に、以下の行があると思います。

allQuestoins = sourceText.Split(',');

Splitとは「割る」という意味です。テキストを一文字目から読み込んで、「 , 」が出てきたら、そこで一つの値として区切るということになっています。

 

なので、最後の文に「 , 」をつけてあげれば良いです。逆にcsvの値の中の数字で「10,000」などとカンマを打ってしまうと、10と000に値が分かれてしまいます。

 

次回記事で修正後、この羅列されてるだけの配列を、問題番号、問題文、選択肢、正解、、、というように種別化するためカスタムクラスを作成し、そのカスタムクラスを使用したList変数へ代入していきます。

 

小話

日本で初めて民の思想統一を図ろうとしたのはおそらく蘇我氏・聖徳太子でしょう。このあたりの学習をしていくと、後々の日本史学習も面白くなります。

まんが日本史を観るのもおすすめ。超分かりやすいです

 

【Unity chatGPT】豚と話せるアプリ作ってみました。

以下の記事を参考にさせていただきました。

 

note.com

 

qiita.com

 

実装方法については上記記事が大変参考になりますので是非読んでみてください。

あとはUnity向けに色々と調整するだけです。

感想はtwitterに書いた通りです。

アルパチーノ素敵ですよね。

【Blender 初心者向】モデリング不要 メッシュひとつで円筒形レンガを作る

普段Blender触らない方でもきっと簡単につくれる

 

やり方

使用するのは、平面のメッシュ。

レンガの境界に沿って二分割されています。

※最初から円筒型のメッシュがあるんだしソレ使えばいいんじゃない?と思った方も是非読んでください。こちらのやり方のほうがUVが崩れず管理が楽ですし、他の形にも応用できます。

 

レンガの画像は取り急ぎ自分で描いたものを適用させました。

個人使用するだけでしたら、ご自由に活用ください。

平面に適用するくらいのUV展開方法なら、検索したらすぐ出てくると思うので割愛します。

 

平面を押し出して、厚みをつけます。

予想通り高さが0のままマテリアルが引き伸ばされてます。

これを修正します。

 

まずサイズの違う二面の辺を選択してシームをマークを適用して分離させます。

その後、側面選択をしてUV展開します。

UV展開されました。なんかx軸がおかしいです。

※押し出し時にz軸固定されてなかったみたいだった…

頂点選択 → スケール → 0 で平らにします。

ここ選択して Sキー、X軸を0に

 

直りました。

向きを90度回転して、レンガ一個分の大きさに合わせていきます。

このくらいで良いかと思います。

 

メッシュをカーブに沿って変形させる

まず、オブジェクトモードでカーブ→円を配置

再びレンガを選択して、今度はモディファイアから配列を選択

伸ばしたい方向に1されてるか確認してください。

個数はあとで決めますので、そのまま次に、

モディファイア → カーブ を追加します

カーブモディファイアで、オブジェクトを選択できるところがあります。

スポイトのアイコンをクリックして、先ほどの円を選択します。

そうすると円に沿ってレンガが曲がります

辺をレンガの境界に合わせたので綺麗に曲がってます。

これが、メッシュの辺がレンガの真ん中にきてたりすると、レンガがベキっと曲がって接合部分が真っ直ぐになってしまいます。

あとは最初に作った配列の個数を増やせば良いです。

 

サイズ調整

そのまんまだと、ピッタリとおしりが合ってくれませんので、

円のスケールを変更するか、

レンガのX軸のスケールを変更すれば良いです。

 

レンガのX軸を変更するときは、マウスでなく、小数点以下の数字を少しずついじって調整したほうが良いと思います。

0.992にしたらピッタリ合いました。

最後にスケールの適用を忘れずに!

オブジェクトモードでCommand + A を押すとスケールや回転を現在値で初期化できます。初期化しないと、基準値が乱れているので、モディファイアを追加したり回転移動などさせたい時に思ったように動いてくれなくなります。

こんな感じ

 

あとはさらに縦に伸ばしたりとか

一個置き間隔で押し出したり、いろいろいじってみてください。

 

この方法を覚えれば、円ではなくカーブパスを利用したり、水平のメッシュではなく角度のあるメッシュを並べて屋根っぽくしたり、あとは時計のメモリを作ったりとか…様々なことに応用ができるようになります。

 

なんでBlenderって無料なんだろう…

 

 

【連載 Unity初心者向け】歴史学習アプリを作る(3 ユーザー登録の実装)

試験的連載モノ[初心者がUnityで学習アプリを作る] 3

初心者だけど少しでもそれっぽいデザインも加えてゲームを作りたい・至極単純なサンプルではなく実際に使えそうな実装をしてみたい方向けに、初心者の私が学習アプリを作る過程を記事にします。

↓本記事ではこの登録機能の実装部分(NCMB使用)を作っていきます。

↓実際にクラウド上で登録が成功していることを確認するところまでやります。

 

 NCMB機能を呼び出すコードサンプル

※NCMB公式サンプルがGithubで公開されています。私はDLしてないので詳細の中身がわからないのですが、公式のもののほうが絶対に良いので、NCMBの学習はしたくないから実装だけしたいの…という方はそちらをDLして使用してください。

今回は、自分でコードの構成を考えてみるトレーニングのために自分で作ったものなので、

初心者が作ったけど動いたよっ!というコードを赤裸々公開していますので実際になにか不都合が起きても責任取れません。。

また、本記事時点では、既存のユーザーネームとパスワードを入力してもログインができない、新規登録のみの実装になっています。ブログという形を取った備忘録なのでご了承くださいませ。

前記事で作ったTitleManager.csを以下のように修正します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using NCMB;
using TMPro;
using UnityEditor.UIElements;

public class TitleManager : MonoBehaviour
{
    [SerializeField]
    public GameObject SignupPanel;
    [SerializeField]
    public GameObject LoginedPanel;
    [SerializeField]
    public TMP_InputField UserNameField;
    [SerializeField]
    public TMP_InputField PassWordField;
    [SerializeField]
    public TextMeshProUGUI HelloText;
    [SerializeField]
    public TextMeshProUGUI SevedDeviceText;
    [SerializeField]
    public GameObject TitleManagerObject;

    public static string Username;
    public static string Password;

    void Start()
    {
        SignupPanel.SetActive(false);
        LoginedPanel.SetActive(false);

        PlayerPrefs.GetString("savedeviceName");
        if (PlayerPrefs.GetString("savedeviceName") != "")
        {//端末にすでにデータ保存されていれば、オートログインする
            Username = PlayerPrefs.GetString("savedeviceName");
            Password = PlayerPrefs.GetString("savedevicePass");
            Autologin();
        }
    }

    //最初のSTARTButtonを押したあとの処理
    //パネル表示だけする
    public void OnStartClick()
    {
        SignupPanel.SetActive(true);
    }

    //SignUpのOKButtonを押したあとの処理
    //インプットフィールドに文字列が入力されたかの確認をする
    public void OnSignUpOKClick()
    {
        //インプットフィールドの値を各stringへ代入
        Username = UserNameField.text.ToString();
        Password = PassWordField.text.ToString();

        if (Username != "" && Password != "")
        {//どちらも入力したら登録可能かチェック
            OnSignUpCheck();
        }
        else
        {//どちらかNullのままだと次へ進まない
            return;
        }
    }

    //ユーザー登録できるかチェック
    //ここからNCMB機能を使う
    public void OnSignUpCheck()
    {
        //インスタンス
        NCMBUser user = new NCMBUser();

        //NCMBUserクラスのnew userが持っているUserNameとPasswordへ入力した値を代入
        user.UserName = Username;
        user.Password = Password;

        //サインアップ
        user.SignUpAsync((NCMBException e) =>
        {
            if (e != null)
            {
                Debug.Log("登録できませんでした");
                Debug.Log(e.ErrorMessage);
                return;
            }
            else
            {  Debug.Log("新規登録に成功しました");
                HelloText.text = "Hello : " + Username;
                LoginedPanel.SetActive(true);
                SignupPanel.SetActive(false);

                NCMBUser.LogInAsync(Username, Password,
                (NCMBException e) =>
                {
                    if (e != null)
                    {
                        UnityEngine.Debug.Log(e.ErrorMessage);
                    }
                    else
                    {
                        PlayerPrefs.SetString("savedeviceName", Username);
                        PlayerPrefs.SetString("savedevicePass", Password);
                        SevedDeviceText.text = "端末にデータを保存しました : " + Username;
                        //Scene移動(TitleManagerは破棄しない)
                        DontDestroyOnLoad(TitleManagerObject);
                    }

                });
            }
        });
    }

    //端末にすでにデータ保存されていれば、オートログインする
    public void Autologin()
    {
        //コンストラクタ
        NCMBUser user = new NCMBUser();
        NCMBUser.LogInAsync(Username, Password,
                (NCMBException e) =>
                {
                    if (e != null)
                    {
                        UnityEngine.Debug.Log(e.ErrorMessage);
                    }
                    else
                    {
                        SevedDeviceText.text = "AutoLoginSuccess : " + Username;
HelloText.text = "Hello : " + Username;                         SignupPanel.SetActive(false); LoginedPanel.SetActive(true); //Scene移動(TitleManagerは破棄しない) DontDestroyOnLoad(TitleManagerObject); } }); } //Scene移動(最後のHelloButton) public void ChangeScene() { } }

 

前記事から新たに作ったのはこちらです。サインアップパネルを流用してるだけ。

usernameとpasswordを入力してユーザー登録が成功すると、上記のパネルが現れます。すでに端末にデータがあれば、起動直後にこのパネルが現れます。端末にデータが無い場合は、前の記事で作った新規登録のパネルが表示されます。

 

新規登録画面に移る起動Ver(初回起動)

 

起動と同時にログインされる起動Ver(登録完了以降の起動)

さりげなく左下の文字が、登録後だと"UserDataSeved"になっていて、

オートログイン後だと"AutoLoginSuccess"になっています。(なんかそれっぽいかなと思って)

 

記事のサンプルを使用してみる超初学者の方はコードで[SerializeField]されてるGameObjectをアタッチするのを忘れずに。

 

動作確認で何度もユーザー登録したのであっという間にユーザー6人に増えました。

 

次回はタイトル画面に飽きてしまったので、既存のユーザー名とパスワードでログインする機能を実装する部分よりも先に進みます。

日本史の学習アプリなので、ざっくり日本史で押さえておきたいポイントを表にしました。(書き殴り段階なので多少の前後あり)この表を基に学習コンテンツを作っていきます。

 

雑談 日本史の勉強の仕方

個人的に日本史で大事なキーワードだと思ってるのが

蘇我氏と聖徳太子・仏教・律令制度〜荘園制度・承久の乱・朝廷衰退・廃藩置県・日清日露戦争・世界大戦・東京裁判です。

上記のキーワードがだとしたら、これを理解していくと日本史が線として繋がっていくと思います。

 

超ざっくり日本史を10行でまとめる

自然神崇拝だった邪馬台国

仏教伝来とそれを促進し統率を図った蘇我氏と聖徳太子

権力を握ったはいいけれど維持の仕方がわからず廃れた院政と荘園制度

我慢できなくなった人々が源氏を担ぎ上げて武力で下剋上した承久の乱

朝廷がお飾りになって武力にものいわす戦国時代

幕府が倒れて政府が領地を全部とりあげ勝手に再分配した廃藩置県

重工業の発展と海外留学をした人たちの知識を持って領土を広げようとした日清戦争からの日露戦争

諸外国との外交に悩み、戦地に出た軍隊も言うことを聞かないので、もつれにもつれて二度の世界大戦

そして東京裁判

戦後復興しながらも、いまだに敗戦国日本

という感じだと思います。多分。卒業式風に声に出すと覚えるかも