RandamNumberゲームの作成
簡単なゲーム作成を通して、uGUI,Http通信、Jsonパースを学習する。今回は後編。(前編はこちら)WebAPIにアクセスしてランキングを表示する。
WebAPIの確認
1.JSP&Servletの20で作成したローカルなWebAPIに以下のようなURLでリクエストを投げると
http://localhost:8080/ScoreAPI/GetRanking?name=mjpurin&score=32000&sex=0&count=100
下のようなJSONが返却される。

これはリクエストの際にname,score,sex,countをパラメーターとして渡すとそのデータをデータベースに挿入し、その挿入データのidと何位だったのかを表すRank,ランキングに入ったのかというbool,それと合わせて実際のランクングデータを配列で返却するものだ。このAPIを利用してランキングをつくる。
2.Sendボタンを押した時にWebAPIにアクセスすれば良さそうだ。CanvasController.csを以下のように作成しCanvasにアタッチする。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Linq;
using System;
using UnityEngine.Networking;
public class CanvasController : MonoBehaviour {
private const int COUNT=100;//ベスト100の取得
private const float CELLHEIGHT = 65.0f;//セル一つ分の高さ
public Text name;//ユーザーが入力した名前が入るTextオブジェクト
public Text score;//ユーザーが入力した点数が入るTextオブジェクト
public ToggleGroup tg;
public GameObject startButton;
public GameObject formPanel;
public GameObject rankingPanel;
public GameObject cells;
public GameObject prefab;
public Sprite[] sprites;
float scaleFactor = 1.0f;//CanvasのscaleFactorを変更している場合はここの値を変える;
//Sendボタンが押された時の処理
public void OnSendClick(){
StartCoroutine (PostConnect ());
}
//コルーチンでWebに接続する。
IEnumerator PostConnect(){
//選択されているラジオボタンを取得(usingにSysatem.Linqが必須)
Toggle tgl = tg.ActiveToggles ().FirstOrDefault();
//パラメーターを詰める
WWWForm form = new WWWForm();
form.AddField("name", name.text);
form.AddField("score", score.text);
form.AddField("sex", tgl.name=="Man"? 0:1);
form.AddField ("count", COUNT);
string url="http://localhost:8080/ScoreAPI/GetRanking";
//Postで通信
UnityWebRequest uwr = UnityWebRequest.Post (url,form);
yield return uwr.SendWebRequest ();
if(uwr.isNetworkError){
Debug.Log (uwr.error);
}else{
//Unity標準のJSONパーサーをつかう。JSON文字列を元にクラスを作成する。
var ranking = JsonUtility.FromJson<RankingData>(uwr.downloadHandler.text);
//ランキングい入った時の処理
if (ranking.isRankingIn) {
//ランキングの数だけ回す
for(int i=0;i<ranking.list.Count;i++){
//cellをInstantiate
GameObject cell = Instantiate (prefab);
//自分のデータだったら背景を青にする
if (ranking.lastId == ranking.list[i].id) {
Image panel = cell.GetComponent<Image> ();
panel.color = Color.cyan;
}
//cellをCellsの子要素にする。
cell.transform.SetParent (cells.transform, false);
//cellの子要素Rankを取得
Text rank = cell.transform.Find("Rank").GetComponent<Text> ();
//順位を表示
rank.text = (i+1).ToString ();
//性別に応じてアイコンを表示
Image image = cell.transform.Find("Thumb").GetComponent<Image> ();
image.sprite = ranking.list[i].sex == 0 ? sprites [0] : sprites [1];
//名前を表示
Text name = cell.transform.Find("Name").GetComponent<Text> ();
name.text = ranking.list[i].name;
//点数を表示
Text scoreText = cell.transform.Find("Score").GetComponent<Text> ();
scoreText.text = ranking.list[i].score .ToString();
}
rankingPanel.SetActive (true);
//表示位置にスクロールさせる
if (ranking.rank > Screen.height/scaleFactor/CELLHEIGHT) {
Vector3 vec = cells.transform.localPosition;
float distination =
ranking.rank * CELLHEIGHT - Mathf.Max(Screen.height/scaleFactor / 2,Screen.height/scaleFactor - (ranking.list.Count - ranking.rank) * CELLHEIGHT);
float diff = distination-vec.y;
while(diff> 0.1f){
vec = cells.transform.localPosition;
vec.y = Mathf.Lerp (vec.y, distination, 0.1f);
cells.transform.localPosition = vec;
diff = distination - vec.y;
yield return new WaitForSeconds (0.01f);
}
}
}
formPanel.SetActive (false);
startButton.SetActive (true);
}
}
}
//Jsonパースの為にクラスを作成する
[Serializable]
class RankingData{
public int lastId;
public int rank;
public List<Score> list;
public bool isRankingIn;
}
[Serializable]
class Score{
public int id;
public string name;
public int score;
public int sex;
}
3.インスペクターからpublicフィールドを以下のように登録する。

4.ヒエラルキーからSubmitButtonを選択してインスペクターから以下のようにOnClickを登録する。

5.最初はFormPanelもRankingPanelも非表示にしておこう。それぞれを選択し、Activeのチェックを外しておこう。

6.Gameの進行に合わせてPanelのActiveを切り替えたい。CubeController.csに以下のように追記しよう。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CubeController : MonoBehaviour {
public Text Score;
public GameObject startButton;
private Coroutine game;
private bool isPlay;
/******追加*****/
public GameObject formPanel;
public GameObject RankingPanel;
/***************/
void Update () {
if(isPlay && Input.GetMouseButtonDown(0)){
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if(Physics.Raycast(ray,out hit,100.0f)){
if(hit.collider.name=="Cube"){
StopCoroutine (game);
isPlay = false;
/******追加*****/
formPanel.SetActive (true);
/***************/
}
}
}
}
IEnumerator RandomNum(){
while (true) {
transform.Rotate (0, 10.0f, 0);
yield return new WaitForSeconds (0.3f);
Score.text = Random.Range (0, 100000).ToString();
}
}
public void StartClick(){
game=StartCoroutine (RandomNum ());
startButton.SetActive (false);
isPlay = true;
/******追加*****/
//古いランキングデータは削除
Transform cells = RankingPanel.transform.FindChild ("Cells");
for( int i=0; i < cells.childCount; i++ ){
GameObject.Destroy( cells.GetChild( i ).gameObject );
}
//スクロールを先頭に戻す
Vector3 vec = cells.localPosition;
vec.y = 0f;
cells.localPosition = vec;
//非表示
RankingPanel.SetActive (false);
/***************/
}
}
7.Cubeのインスペクターからpublicフィールドを以下のように登録する。

確認
8.実行してみよう。ランクインした時にランキングが表示されれば成功だ。

コメント