前回 Firebase とのやりとり部分を Rest Client for Unity というAssetStoreでDLできるライブラリを利用して記述しましたが、今回はその部分を Unity が提供している UnityEngine.Networking クラスの関数(UnityWebRequest,DownloadHandlerBuffer) を使って書き換えてみました!
環境
PC: MacBook Air
前回記事
Unityでデータベースと連携させたい!(Firebase編)
参照記事
UnityWebRequestの使い方【Unity】
UnityWebRequest
DownloadHandlerBuffer
UnityWebRequest HTTP POST to Cloud Functions for Firebase
UnityWebRequestでJSONをPOSTする方法
【C#】クラス名って何?ジェネリッククラスについて。
C#のラムダ式【=>】って何?
C# の delegate : メソッドの引数にメソッドを渡して使用する方法と、JavaScript の function(){} と同じ使用方法( 匿名 )
Unityで覚えるC#
UnityのJsonUtilityの細かい10の疑問をいまさら検証した
以下作業内容
-
PlayerScores.cs
を書き換える
- 削除した部分
+ 追記した部分
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
- using Proyecto26;
+ using UnityEngine.Networking;
public class PlayerScores : MonoBehaviour
{
public Text scoreText;
public InputField nameText;
private System.Random random = new System.Random();
User user = new User();
public static int playerScore;
public static string playerName;
public GameObject targetObject;
// Start is called before the first frame update
void Start()
{
playerScore = random.Next(0, 101);
scoreText.text = "Score: " + playerScore;
}
public void OnSubmit(){
playerName = nameText.text;
PostToDatabase();
}
public void OnGetScore(){
RetrieveFromDatabase();
}
private void UpdateScore(){
scoreText.text = "Score: " + user.userScore;
ChangeColorName(user.userScore);
}
private void PostToDatabase(){
User user = new User();
- RestClient.Put("https://forunity-e2ac2.firebaseio.com/"+ playerName +".json",user);
+ string jsonStr = JsonUtility.ToJson(user);
+ StartCoroutine(Put("https://forunity-e2ac2.firebaseio.com/"+ playerName +".json", jsonStr));
ChangeColorName(user.userScore);
}
private void RetrieveFromDatabase(){
- RestClient.Get<User>("https://forunity-e2ac2.firebaseio.com/"+ nameText.text +".json").Then(response =>
- {
- user = response;
- UpdateScore();
- });
+ StartCoroutine(GetUserDat("https://forunity-e2ac2.firebaseio.com/"+ nameText.text +".json"));
}
private void ChangeColorName(int score){
//Debug.Log(score);
if(score < 25){
// red
targetObject.GetComponent<Renderer>().material.color = Color.red;
} else if (score < 50){
// yellow
targetObject.GetComponent<Renderer>().material.color = Color.yellow;
} else if (score < 75){
// green
targetObject.GetComponent<Renderer>().material.color = Color.green;
} else {
// blue
targetObject.GetComponent<Renderer>().material.color = Color.blue;
}
}
+
+ //SendWebRequest
+ private IEnumerator Put(string url, string jsonStr){
+ //UnityWebRequestを生成する
+ UnityWebRequest request = UnityWebRequest.Put(url, jsonStr);
+
+ //SendWebRequestを実行して送受信開始
+ yield return request.SendWebRequest();
+
+ //エラー判定
+ if(request.isHttpError || request.isNetworkError){
+ //エラーログ
+ Debug.Log(request.error);
+ } else {
+ //結果確認
+ Debug.Log(request.downloadHandler.text);
+ }
+ }
+ private IEnumerator GetUserDat(string url){
+ //UnityWebRequestを生成する
+ UnityWebRequest request = UnityWebRequest.Get(url);
+ request.downloadHandler = new DownloadHandlerBuffer();
+
+ //SendWebRequestを実行して送受信開始
+ yield return request.SendWebRequest();
+
+ //エラー判定
+ if(request.isHttpError || request.isNetworkError){
+ //エラーログ
+ Debug.Log(request.error);
+ } else {
+ // json -> c# で使える形式に直さないとならない...
+ user = JsonUtility.FromJson<User>(request.downloadHandler.text);
+ UpdateScore();
+
+ //結果確認ログ
+ Debug.Log(request.downloadHandler.text);
+ }
+ }
}
その1
必要なusingを宣言
using Proyecto26;
はRest Client for Unityライブラリ用の記述なので削除し、using UnityEngine.Networking;
を代わりに追記します
using UnityEngine.Networking;
その2
登録・更新するファンクションを準備する
登録・更新は UnityWebRequest.Put を使います
private IEnumerator Put(string url, string jsonStr){
//UnityWebRequestを生成する
UnityWebRequest request = UnityWebRequest.Put(url, jsonStr);
//SendWebRequestを実行して送受信開始
yield return request.SendWebRequest();
//エラー判定
if(request.isHttpError || request.isNetworkError){
//エラーログ
Debug.Log(request.error);
} else {
//結果確認
Debug.Log(request.downloadHandler.text);
}
}
その3
取得するファンクションを準備する
取得は UnityWebRequest.Get と DownloadHandlerBuffer を使います
(Get結果を使用するために SendWebRequest() する前に DownloadHandlerBuffer のインスタンスを生成しておかないとならないのと、jsonで取得してきたリクエスト結果をC#で使える形に変換しなければならないところで詰まって結構時間かかりました。。poz)
private IEnumerator GetUserDat(string url){
//UnityWebRequestを生成する
UnityWebRequest request = UnityWebRequest.Get(url);
request.downloadHandler = new DownloadHandlerBuffer();
//SendWebRequestを実行して送受信開始
yield return request.SendWebRequest();
//エラー判定
if(request.isHttpError || request.isNetworkError){
//エラーログ
Debug.Log(request.error);
} else {
// json -> c# で使える形式に直さないとならない...
user = JsonUtility.FromJson<User>(request.downloadHandler.text);
UpdateScore();
//結果確認ログ
Debug.Log(request.downloadHandler.text);
}
}
その4
準備したファンクションを呼び出すように書き換える
Rest Client for Unity の関数を使っていた部分をそれぞれ準備したファンクションに書き換えます
その際、コルーチンとして扱って呼び出します(Unityはフレームごとにスレッドがすぎていってしまうので、フレームを跨いで処理を中断・再開させることが出来る仕組みであるコルーチンを利用)
Putするデータはjson型で渡したいので、JsonUtility.ToJsonをかましました
private void PostToDatabase(){
User user = new User();
string jsonStr = JsonUtility.ToJson(user);
StartCoroutine(Put("https://forunity-e2ac2.firebaseio.com/"+ playerName +".json", jsonStr));
ChangeColorName(user.userScore);
}
private void RetrieveFromDatabase(){
StartCoroutine(GetUserDat("https://forunity-e2ac2.firebaseio.com/"+ nameText.text +".json"));
}
修正はこれだけです
(※最終的なPlayerScores.cs
)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
public class PlayerScores : MonoBehaviour
{
public Text scoreText;
public InputField nameText;
private System.Random random = new System.Random();
User user = new User();
public static int playerScore;
public static string playerName;
public GameObject targetObject;
// Start is called before the first frame update
void Start()
{
playerScore = random.Next(0, 101);
scoreText.text = "Score: " + playerScore;
}
public void OnSubmit(){
playerName = nameText.text;
PostToDatabase();
}
public void OnGetScore(){
RetrieveFromDatabase();
}
private void UpdateScore(){
scoreText.text = "Score: " + user.userScore;
ChangeColorName(user.userScore);
}
private void PostToDatabase(){
User user = new User();
string jsonStr = JsonUtility.ToJson(user);
StartCoroutine(Put("https://forunity-e2ac2.firebaseio.com/"+ playerName +".json", jsonStr));
ChangeColorName(user.userScore);
}
private void RetrieveFromDatabase(){
StartCoroutine(GetUserDat("https://forunity-e2ac2.firebaseio.com/"+ nameText.text +".json"));
}
private void ChangeColorName(int score){
//Debug.Log(score);
if(score < 25){
// red
targetObject.GetComponent<Renderer>().material.color = Color.red;
} else if (score < 50){
// yellow
targetObject.GetComponent<Renderer>().material.color = Color.yellow;
} else if (score < 75){
// green
targetObject.GetComponent<Renderer>().material.color = Color.green;
} else {
// blue
targetObject.GetComponent<Renderer>().material.color = Color.blue;
}
}
//SendWebRequest
private IEnumerator Put(string url, string jsonStr){
//UnityWebRequestを生成する
UnityWebRequest request = UnityWebRequest.Put(url, jsonStr);
//SendWebRequestを実行して送受信開始
yield return request.SendWebRequest();
//エラー判定
if(request.isHttpError || request.isNetworkError){
//エラーログ
Debug.Log(request.error);
} else {
//結果確認
Debug.Log(request.downloadHandler.text);
}
}
private IEnumerator GetUserDat(string url){
//UnityWebRequestを生成する
UnityWebRequest request = UnityWebRequest.Get(url);
request.downloadHandler = new DownloadHandlerBuffer();
//SendWebRequestを実行して送受信開始
yield return request.SendWebRequest();
//エラー判定
if(request.isHttpError || request.isNetworkError){
//エラーログ
Debug.Log(request.error);
} else {
// json -> c# で使える形式に直さないとならない...
user = JsonUtility.FromJson<User>(request.downloadHandler.text);
UpdateScore();
//結果確認ログ
Debug.Log(request.downloadHandler.text);
}
}
}
→ 問題なく登録・更新・取得できました!!
振り返り
前回 Rest Client for Unity というライブラリを使った Firebase とのやりとり部分を Unity提供の関数を使ったらどんな記述になるのかな、と思い立って書き換えてみましたが、
そもそもC#に不慣れなので、コルーチンやらラムダ式やらも調べつつで丸一日費やし、Unityの先生に助言もいただき、なんとか書き換えることができました。。。prz
感想としては、便利なライブラリはとってもありがたいものなんだな、です!
これからは便利ライブラリをバンバン使って実装時間を短縮して作りたいものを早く作る方に重点を置いて行きたいなと思いました!
以上!