「授業用」カテゴリーアーカイブ

グラフ用スクリプト

バックアップ用

長すぎ.ライブラリ化しろよ.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using NCMB;
using System;
using MiniJSON;//use miniJSON
using UnityEngine.UI;//use unity gui
using userManager;//入所日数など
using System.Globalization;//hex color用

//radar graph show script

public class suGraph : MonoBehaviour {

	public GameObject myGraphPrefab;

	public WMG_Radar_Graph graph;
	public WMG_Series series1;
	WMG_Series[] seriesArr;//seriesの複数作成用 
	WMG_Series series0;//合格ライン用
	WMG_Series[] seriesPairs;//Pairの複数作成用 

	//詳細グラフ用
	public WMG_Axis_Graph syousaiGraphGO;
	WMG_Series series100;
	WMG_Series series200;
	List<Vector2> syousaiVec;//折れ線グラフ入れる用
	List<Vector2> goukakuVec;//折れ線グラフ入れる用
	List<string> soyousaiDateList;//横X軸データ用


	WMG_Node gragui;
	Dictionary<string, object> _skillPo;//ディクショナリです
	string myUsrName;//検索用のユーザーネーム入れ
	string pairUsrName;//ペアのユーザネーム入れ


	//凡例表示用
	public  RectTransform bonreiParent;
	public RectTransform bonreiPrefab;

	List<string> texColors ;
	List<string>texColors2 ;

	int checkedCount; //実際にチェック済みのカウント数
	int userChecked = 0;

	//Pair表示用
	public  RectTransform pairParent;
	public RectTransform pairPrefab;
	public GameObject noPairObj;

	//ドロップダウン用
	public Dropdown hyoujiDrop;

	//ポイント色用
	WMG_List<Color> myc ;
	WMG_List<Color> myLinec;
	WMG_List<Color> myLinecLocal;
	NCMBUser user;
	WMG_List<Color> mycLocal;

	//グラフの表示件数を増やす
	int graphDispCount;
	public GameObject hyoujiKensuDropGO;

	public GameObject syousaiGraph;//ジャンル別詳細のグラフアサイン用
	public int dlDataCount;//ダウンロードするデータ数

	List<Transform> bonreiGOs = new List<Transform>();

	//ドロップダウンをリセットする用
	public GameObject dropGO;

	//GameObject[] bonreiObjs;//prefabをまとめて消す用(凡例の表示とか)
	int genreID = 0;

	//詳細グラフのタイトル
	string syousaiTitle;
	WMG_List<string> genreList = new WMG_List<string> (){ "食事", "身だしなみ", "衛生管理", "健康管理", "金銭管理", "社会性", "危機管理" };

	List<string> dateListLocal;


	//グラフデータ作成用
	List<List<float>> graData = new List<List<float>>();//多次元リスト?
	List<List<float>> graDatarRev = new List<List<float>>();//詳細グラフ横軸表示用に逆順のを用意する

	//ペアグラフ作成データ
	List<List<float>> graDataPair = new List<List<float>>();//多次元リスト?

	//件数表示用
	public Text kensu;


	// Use this for initialization
	void Start () {
	//my
	graph = myGraphPrefab.GetComponent<WMG_Radar_Graph>();//指定のゲームオブジェクトからgraphを取得
		syousaiGraph.SetActive(false);
		user = NCMBUser.CurrentUser;
		myUsrName = user.UserName;
		soyousaiDateList = new List<string>();

		//グラフクリックテスト用
		graph.WMG_Click += MyCustomFunction;

		colorGenerate ();//色生成
		//レーダーグラフ用最初に30個Series作っておく

		//ペア選択用
		noPairObj.SetActive(true);

		//初期設定
		dlDataCount = 30;//30はグラフマックス値

		seriesArr = new WMG_Series[dlDataCount];//
		for (int i = 0; i < dlDataCount; i++) {
			seriesArr [i] = graph.addSeries ();//グラフにつながり(series)を追加?
		}
		series0 = graph.addSeries ();

		//詳細グラフ用ここでseriesを追加しておくとグラフが二重にならない
		series100 = syousaiGraphGO.addSeries();
		series200 = syousaiGraphGO.addSeries();

		//表示件数ドロップダウン用
		hyoujiKensuDropGO.GetComponent<Dropdown>().value = 0;
		graphDispCount = 5;//グラフ最大表示件数


		//データを取得する関数へ
		//getSkillData ();//SUではここはオフにする
	}


	//グラフクリックテストで飛ばされる先のファンクション
	void MyCustomFunction(WMG_Series series, WMG_Node node) {
		Debug.Log("Node: " + node.name + " on series: " + series.name + " was clicked!");
	}


	// Update is called once per frame
	void Update () {
	
	}

	//冒頭特定色に固定そのうしろはランダムカラー
	void colorGenerate(){
		//
		texColors = new List<string> (){ "blue", "red", "green", "cyan", "magenta", "yellow", "grey" };
		texColors2 = new List<string> (){ "blue", "red", "green", "cyan", "magenta", "yellow", "grey" };
		myc  = new WMG_List<Color>(){Color.blue, Color.red, Color.green, Color.cyan, Color.magenta, Color.yellow, Color.gray};
		myLinec  = new WMG_List<Color>(){new Color(0F, 0F, 1F, 0.7f),new Color (1F, 0F, 0F, 0.7f), new Color (0F, 1F, 0F, 0.7f),new Color (0F, 1F, 1F, 0.7f),new Color (1F, 0F, 1F, 0.7f),new Color (1F, 1F, 0F, 0.7f),new Color (0.7F, 0.7F, 0.7F, 0.7f)};

		//表示件数増に伴うグラフ色数生成
		for (int i = 0; i < 23; i++) {//7+23で30生成
			Color randomColor = new Color(UnityEngine.Random.value, UnityEngine.Random.value, UnityEngine.Random.value);
			myc.Add(randomColor);
			myLinec.Add(randomColor);
			//texcolor用16進数に変換する
			float rcolorf = randomColor.r * 255;
			float gcolorf = randomColor.g * 255;
			float bcolorf = randomColor.b * 255;
			int rcolor = (int)rcolorf;
			int gcolor = (int)gcolorf;
			int bcolor = (int)bcolorf;
			string hex = "#" + rcolor.ToString("X2") + gcolor.ToString("X2") + bcolor.ToString("X2") + "ff";
			texColors.Add (hex);
			texColors2.Add (hex);

		}

	}


	void getSkillData(){
		graData.Clear ();//ダウンロードしたデータを消す
		graDatarRev.Clear ();//ダウンロードしたデータを消す
		colorGenerate();//色リセット

		//グラフを取得するためにデータを取得
		NCMBQuery<NCMBObject> query = new NCMBQuery<NCMBObject> ("testobj");
		//query.Limit = graphDispCount;
		query.Limit = dlDataCount;//とりあえず上限30件取得する

		query.OrderByDescending ("createDate");//createDateを降順(最新が先)でソート_ここを入れ替えると全体が変わるかな
		//query.WhereEqualTo ("skillPO", "");
		query.WhereEqualTo ("player", myUsrName);//Playerがusernameの結果を検索
		query.FindAsync ((List<NCMBObject> objList ,NCMBException e) => {
			if (e != null) {
				//検索失敗時の処理
				Debug.Log(e.Message);
			} else {

				if ( objList == null || objList.Count == 0 ){
					//Debug.Log(e.Message);
					Debug.Log("Error");//検索結果がない
					return;
				}
				//S
				int po = 0;//
				int po2 = 0;

				//実際のデータ数をセット
				checkedCount = objList.Count;

				texColors2.Reverse();//ペア表示用に逆にする(色かぶり防止)

				///////////////----------ここからforeach-----------////////////
				//直近○件表示を出す
				foreach (NCMBObject objdata in objList) {//new
					int listCallNum = objList.Count - 1;//
					List<float> statusData = new List<float>();//グラフ用
					List<float> statusDataPair = new List<float>();//グラフ用



					Dictionary<string, string> pairDic = new Dictionary<string, string> ();
				//	if(objdata["pair"].ToString() == "0"){
					if(!objdata.ContainsKey("pair") || objdata["pair"].ToString() == "0"){
						//通常の処理


						//凡例作成ペア無し
						string nyusyokikan;
						var item = GameObject.Instantiate(bonreiPrefab) as Transform;//プレファブを生成
						item.SetParent(bonreiParent); //レイアウトグループのある親にセッ
						bonreiGOs.Add(item);
						//DateTime dt = objdata.UpdateDate.Value;//データ更新日をDateに
						DateTime dt = objdata.CreateDate.Value;//データ更新日をDateに

						//UTCをJSTに
						TimeZone zone = TimeZone.CurrentTimeZone;
						TimeSpan offset = zone.GetUtcOffset(DateTime.Now);//オフセット取得して差分を出す
						DateTime jst = dt + offset;//差分を計算してJSTにする

						string thisDay = jst.ToLongDatePattern();//更新日の表記を整形
						string thisTime  = jst.ToShortTimeString();
						nyusyokikan = usrManager.nyusyoSabun(dt);
						item.name = objdata.ObjectId.ToString();//プレファブ名をObjIDにする.このIDで詳細グラフを表示する
						item.GetComponent<Text>(). text = thisDay +  thisTime + ":<size=30><color=" + texColors[po] + ">●</color></size>入所" + nyusyokikan + "日";//できればよみやすい形式に整形
						string dateFull = thisDay +  thisTime + "<size=30><color=" + texColors2[po2] + ">■</color></size>";//pairグラフ表示用texColors2を使用
						//詳細データグラフの日付用
						string mon_day = jst.ToString("MM"+"月" + "dd" + "日");
						soyousaiDateList.Add(mon_day);//詳細グラフに日付表示用


							//return;
						//ペア無しデータ作成
						string json = Json.Serialize(objdata["skillPo"]);//SkillPoのデータだけを取り出すDictionaryでくるのでJsonにする
						_skillPo  = Json.Deserialize (json) as Dictionary<string, object>;//それをDictionaryにする

						//実際にデータを取り出して加工する
						int ponagasa  = _skillPo.Count;
						for( int i=0; i < ponagasa; i++){
							int indexNum = i + 1;//0がないから
							string callNum = "m0" + indexNum.ToString();
							float skillfloat = float.Parse( _skillPo[callNum].ToString());
							//パーセントに計算
							//m01 =3,m02=4, m03=6, m04=4,m05=2,m06=8, m07=4

							string sex = user ["sex"].ToString();
							if (sex == "0") {

								//男子のポイントをパーセントにする
								if(callNum == "m01"){
									skillfloat = 100f*(skillfloat / 15f);
								}else if(callNum == "m02"){
									skillfloat = 100f*(skillfloat / 20f);
								}else if(callNum == "m03"){
									skillfloat = 100f*(skillfloat / 30f);
								}else if(callNum == "m04"){
									skillfloat = 100f*(skillfloat / 20f);
								}else if(callNum == "m05"){
									skillfloat = 100f*(skillfloat / 10f);
								}else if(callNum == "m06"){
									skillfloat = 100f*(skillfloat / 40f);
								}else if(callNum == "m07"){
									skillfloat = 100f*(skillfloat / 20f);
								}

							} else {//女子の場合
								//女子のポイントをパーセントにする
								if(callNum == "m01"){
									skillfloat = 100f*(skillfloat / 15f);
								}else if(callNum == "m02"){
									skillfloat = 100f*(skillfloat / 30f);
								}else if(callNum == "m03"){
									skillfloat = 100f*(skillfloat / 35f);
								}else if(callNum == "m04"){
									skillfloat = 100f*(skillfloat / 20f);
								}else if(callNum == "m05"){
									skillfloat = 100f*(skillfloat / 10f);
								}else if(callNum == "m06"){
									skillfloat = 100f*(skillfloat / 40f);
								}else if(callNum == "m07"){
									skillfloat = 100f*(skillfloat / 25f);
								}
							}

							//LISTに登録
							statusData.Add(skillfloat);
							listCallNum++;//呼び出すオブジェクトを増分
							skillfloat = 0f;
						}//forここまで

						graData.Add(statusData);//多次元LISTにリストを追加
						po++;//for eachの回数
						userChecked++;
						//ペア無しデータ作成ここまで
					}else{
						noPairObj.SetActive(false);//ペア情報が1件でもあったら表示を消す
						//日付生成
						DateTime dt = objdata.CreateDate.Value;//データ更新日をDate
						//UTCをJSTに
						TimeZone zone = TimeZone.CurrentTimeZone;
						TimeSpan offset = zone.GetUtcOffset(DateTime.Now);//オフセット取得して差分を出す
						DateTime jst = dt + offset;//差分を計算してJSTにする

						string thisDay = jst.ToLongDatePattern();//更新日の表記を整形
						string thisTime  = jst.ToShortTimeString();
						string dateFull = thisDay +  thisTime + "<size=30><color=" + texColors2[po2] + ">■</color></size>";//pairグラフ表示用texColors2を使用


						//pair用のグラフへ
						pairDic.Add("pairID", objdata["pair"].ToString());
						pairDic.Add("createDate", dateFull);
						string pairJson = Json.Serialize(objdata["skillPo"]);
						pairDic.Add("skillPoJson", pairJson);
						//RawデータいれるならJson化してここに
						//トグルのON/OFFえおするためにプレファブ名をGO名に変更しておく?


						//プレファブを作成し採点者とユーザ名と日付とトグルを生成して
						var item3 = GameObject.Instantiate(pairPrefab) as Transform;//プレファブを生成
						item3.SetParent(pairParent); 
						item3.transform.FindChild("Label").GetComponent<Text>().text = pairDic["pairID"] + ":" +pairDic["createDate"] ;
						item3.name = "pair" + po2.ToString();
					//	item3.GetComponent<Text>(). text = "ペア["+pairDic["pairID"] + "]" +pairDic["createDate"] ;

						//Debug.Log(pairDic["pairID"] + ":" + pairDic["createDate"] + ":" +pairDic["skillPoJson"]);
						Dictionary<string, object> _skillPo2 = Json.Deserialize(pairDic["skillPoJson"]) as Dictionary<string, object>;//json化したSkillPoをディクショナリに戻す
						//パーセントを計算してベクトルにしてSiries生成してオブジェクトリストに入れて番号でON/OFFする

						//実際にデータを取り出して加工する
						int ponagasa2  = _skillPo2.Count;
						for( int i=0; i < ponagasa2; i++){
							int indexNum2 = i + 1;//0がないから
							string callNum2 = "m0" + indexNum2.ToString();
							float skillfloat2 = float.Parse( _skillPo2[callNum2].ToString());
							//パーセントに計算
							//m01 =3,m02=4, m03=6, m04=4,m05=2,m06=8, m07=4

							string sex = user ["sex"].ToString();
							if (sex == "0") {

								//男子のポイントをパーセントにする
								if(callNum2 == "m01"){
									skillfloat2 = 100f*(skillfloat2 / 15f);
								}else if(callNum2 == "m02"){
									skillfloat2 = 100f*(skillfloat2 / 20f);
								}else if(callNum2 == "m03"){
									skillfloat2 = 100f*(skillfloat2 / 30f);
								}else if(callNum2 == "m04"){
									skillfloat2 = 100f*(skillfloat2 / 20f);
								}else if(callNum2 == "m05"){
									skillfloat2 = 100f*(skillfloat2 / 10f);
								}else if(callNum2 == "m06"){
									skillfloat2 = 100f*(skillfloat2 / 40f);
								}else if(callNum2 == "m07"){
									skillfloat2 = 100f*(skillfloat2 / 20f);
								}

							} else {//女子の場合
								//女子のポイントをパーセントにする
								if(callNum2 == "m01"){
									skillfloat2 = 100f*(skillfloat2 / 15f);
								}else if(callNum2 == "m02"){
									skillfloat2 = 100f*(skillfloat2 / 30f);
								}else if(callNum2 == "m03"){
									skillfloat2 = 100f*(skillfloat2 / 35f);
								}else if(callNum2 == "m04"){
									skillfloat2 = 100f*(skillfloat2 / 20f);
								}else if(callNum2 == "m05"){
									skillfloat2 = 100f*(skillfloat2 / 10f);
								}else if(callNum2 == "m06"){
									skillfloat2 = 100f*(skillfloat2 / 40f);
								}else if(callNum2 == "m07"){
									skillfloat2 = 100f*(skillfloat2 / 25f);
								}
							}

//							Debug.Log(skillfloat2);
							//LISTに登録
							statusDataPair.Add(skillfloat2);
							//listCallNum++;//呼び出すオブジェクトを増分
							skillfloat2 = 0f;
						}//forここまで
							
						//graDataPair.Add(statusDataPair);//多次元LISTにリストを追加
						po2++;//pairのループ回数
						//Debug.Log("count_" + graDataPair.Count);
						graDataPair.Add(statusDataPair);//多次元LISTにリストを追加
					}//ifがペアのときのデータ作成終わり

			}//for eachここまで
			///////////////----------ここまでforeach-----------////////////


				//30件に満たない部分をゼロで埋める
				int zeroDataCount = dlDataCount - po;//POはペア無しのカウント数で残数を
				for(int p =0; p < zeroDataCount; p++){
					List<float> statusData = new List<float>(){0f, 0f, 0f, 0f, 0f, 0f, 0f};
					graData.Add(statusData);
				}
					

				//凡例の最後に合格ラインを追加
				var item2 = GameObject.Instantiate(bonreiPrefab) as Transform;//プレファブを生成
				item2.SetParent(bonreiParent); //レイアウトグループのある親にセット
				item2.GetComponent<Text>(). text = "合格ライン:<size=30><color=white>■</color></size>" ;//できればよみやすい形式に整形

				//詳細グラフ用に逆のデータを作成
				graDatarRev = new List<List<float>>(graData);
				graDatarRev.Reverse();
				soyousaiDateList.Reverse();//日付を逆順に

				//登録件数が1〜4件のときに出るエラー対策
				//if(graData.Count < 5){
				if(po < 5){
					//graphDispCount = graData.Count;
					graphDispCount = po;
				}else{
					graphDispCount = 5;
				}
//				Debug.Log("grac" + graphDispCount);
				//グラフを描画

				//検索結果件数表示
				if(userChecked < 30 ){
				kensu.text =  "全部で" + userChecked.ToString() + "件の記録があります";
				}else{
					kensu.text =  "最新の30件を表示しています";
				}


				drawGraph ();
			}
		});

	//	getdata ();

	}

	//これ使っていない?ペア表示に使う?
	void getdata(){

		NCMBObject obj2 = new NCMBObject ("Book");//BOOkってなに?
		obj2.ObjectId = "OEHVJXwOLUweq7Af";//ここ動的にいれかえる
		obj2.FetchAsync ((NCMBException e) => {        
			if (e != null) {
				Debug.Log("e");
				//エラー処理
			} else {
				//成功時の処理
				Debug.Log("ok");
				Debug.Log(obj2["player"]);
			}               
		});
	}



	void drawGraph(){
		graph.Refresh ();

		//グラフ全般の設定?
		graph.randomData = false;   // ランダムでデータ作成はしないのでfalse
		int koumokusu = graData [0].Count; //最初のグラフの項目数を取得して変数に
		graph.numPoints = koumokusu;        // 項目数を設定
		graph.hideLabels = false;
		graph.radarMinVal = 0;      // 最低
		graph.radarMaxVal = 100;    // 最大
		graph.numGrids = 5;         // グリッドの数

		graph.offset = new Vector2 (10, 0);//ずらせる
		graph.paddingLeftRight = new Vector2 (120, 120);
		graph.paddingTopBottom = new Vector2 (120, 120);

		graph.labelStrings = new WMG_List<string> (){ "食事", "身だしなみ", "衛生管理", "健康管理", "金銭管理", "社会性", "危機管理" };//男性時の項目
		graph.labelsOffset = 24;
		graph.labelsColor = Color.white;
		graph.gridColor = Color.black;

		int graDataSu = graData.Count;//Listの削除数を検出

		//グラフ色関係
		int rmvCount = myLinec.Count -graData.Count;//削除する色の範囲を数える


		int rmvStart = dlDataCount - graphDispCount;

		WMG_List<Color> mycPair = new WMG_List<Color> ();
		mycPair.SetList (myc);//mycをmycLocalにコピー
		mycPair.Reverse ();


		//ペアグラフ表示seriesPairs[i]
		graDataPair.Reverse();
		for (int pairs = 0; pairs < graDataPair.Count; pairs++) {
			WMG_Series mypairs;


			mypairs  = graph.addSeries ();//グラフにつながり(series)を追加?
			List<Vector2> pointVectorPair =  graph.GenRadar (graDataPair[pairs] , graph.offset.x, graph.offset.y, graph.degreeOffset);//
			//Debug.Log("count" + pairs);
			mypairs.pointValues.SetList(pointVectorPair);
			mypairs.hidePoints = false; 
			mypairs.hideLines = false;// 線表示
			mypairs.pointWidthHeight = 15f;
			mypairs.pointColor = mycPair[pairs];//カラーリストから色をつける
			mypairs.connectFirstToLast = true;      // 最後と最初の点をつなぐ
			mypairs.lineColor = mycPair[pairs];//ライン用のカラーリスト(半透明)をつける
			mypairs.lineScale = 1.5f;//1.5
			mypairs.pointPrefab = 1;//ポイントの形を変えるラインの形も変えよう
			mypairs.linkPrefab = 0;//線を点線に
			mypairs.name = "mypair" + pairs.ToString();

		}





		//最初にseries全部作っておく

		//データが30件以下の処理をしておく
		int maxdatasu;
		if (graDatarRev.Count < dlDataCount) {
			maxdatasu = graDatarRev.Count;
		} else {
			maxdatasu = dlDataCount;
		}

		maxdatasu = 30;


//		Debug.Log ("max" + maxdatasu);
		int nullKaisu = dlDataCount - graDatarRev.Count;

//		if (i < nullKaisu) {
			//LISTに足
//		}

		for (int i = 0; i <maxdatasu; i++) {
			//seriesArr [i] = graph.addSeries ();//グラフにつながり(series)を追加?
		List<Vector2> pointVector2 = graph.GenRadar (graDatarRev [i], graph.offset.x, graph.offset.y, graph.degreeOffset);//graDatarRev  graData

			seriesArr [i].pointValues.SetList (pointVector2); 
			seriesArr [i].hidePoints = false;              // 点を表示
			seriesArr [i].pointWidthHeight = 18f;
			seriesArr [i].pointColor = myLinec[i];//カラーリストから色をつける
			seriesArr [i].connectFirstToLast = true;      // 最後と最初の点をつなぐ
			seriesArr [i].lineColor = myLinec[i];//ライン用のカラーリスト(半透明)をつける
			seriesArr [i].lineScale = 1.5f;
			//seriesArr [i].da
			seriesArr [i].dataLabelsEnabled = false;
		}
			
		//合格ラインを描画
		//WMG_Series series0 = graph.addSeries ();//グラフにつながり(series)を追加?
		List<float> statusData0 = new List<float> (){ 74, 74, 74, 74, 74, 74, 74 };//合格点ライン表示用
		List<Vector2> pointVector0 = graph.GenRadar (statusData0, graph.offset.x, graph.offset.y, graph.degreeOffset);
		series0.pointValues.SetList (pointVector0); 
		series0.hidePoints = true;              // 点を表示
		series0.pointWidthHeight = 20f;
		series0.connectFirstToLast = true;      // 最後と最初の点をつなぐ
		series0.lineColor = Color.white; // 線の色白
		series0.lineScale = 3f;

	//graph.Refresh ();

		//表示件数ドロップダウンを変化させる
		dropdownItem ();
		//不要な凡例や線を消す

		//初回は5がマックス値
		if (userChecked < 5) {
			//graphDispCount = graData.Count;//5件以下の数をここに
			graphDispCount = userChecked;
		} else {
			graphDispCount = 5;
		}

		hideSeries (graphDispCount);//不要な線と点と凡例を消す

	}


	//グラフの表示
	void hideSeries(int hyoujisu){//引数は表示件数
		WMG_List<Color> myLinecLocal = new WMG_List<Color>();
		myLinecLocal.SetList (myLinec);

		int rmvStart = dlDataCount - graphDispCount;
		//myLinec.Reverse ();//リストを逆順にする
		//myLinec.RemoveRange (0, rmvStart);//最新版を残す設定で日付を削除して色数合わせる
		myLinecLocal.RemoveRange(graphDispCount, rmvStart);
		//myLinecLocal.Reverse ();//リストを逆順にする

		//Debug.Log (rmvStart);
		//Debug.Log (myLinecLocal.Count);

		int po = 0;

		//Debug.Log("hikisu" + hyoujisu);
		//レーダーグラフ線と点を非表示にする
		//int rmvStart = dlDataCount - graphDispCount;
		for(int i=0; i < dlDataCount; i++){
			seriesArr[i].hideLines = true;
			seriesArr[i].hidePoints = true;
		}

		//レーダーグラフ線と点を表示する
		int showStart = dlDataCount - 1;
		int showEnd = showStart - hyoujisu;
//	Debug.Log (showStart +":" + showEnd);
	for(int t = showStart; t > showEnd; t--){
	//	for(int t = 0; t < hyoujisu; t++){
			//Debug.Log (t);
			seriesArr [t].pointColor = myLinecLocal[po];
			seriesArr [t].lineColor = myLinecLocal[po];
			seriesArr[t].hideLines = false;
			seriesArr[t].hidePoints = false;
			po++;
		}



		//凡例を表示する
		for (int p = 0; p < graData.Count; p++) {
			if (p < bonreiGOs.Count) {
				GameObject delGO = bonreiGOs [p].gameObject;
				delGO.SetActive (true);
			}
		}

		//凡例を非表示にする
	if(hyoujisu < 6){
			for(int q = hyoujisu; q < graData.Count; q++){
				if (q < bonreiGOs.Count) {
					GameObject delGO = bonreiGOs [q].gameObject;
					delGO.SetActive (false);
				}
			}
			//return;
		}else{
			for(int q = hyoujisu; q < graData.Count; q++){
				if (q < bonreiGOs.Count) {
					GameObject delGO = bonreiGOs [q].gameObject;
					delGO.SetActive (false);
				}
		}
		}

	}
		
		

	public void gradeletetest(){
		series1.hideLines = true;//series1の線を消す
		series1.hidePoints = true;//series1のポイントを消す

	}

	//個別のグラフを表示する.凡例をタップするとここを実行する?

	//objIdを受ける
	//データbaseをグラフ化する


	//詳細グラフのドロップダウンをここで受ける
	public void droplistChanged(int result){
		genreID = result;
		//毎回グラフの中身を入れ替える
		syousaiVec = new List<Vector2>();
		goukakuVec = new List<Vector2>();
		dateListLocal = new List<string> (soyousaiDateList);//加工用のリストを新規に作成する

		List<List<float>> oresenLocal = new List<List<float>>(graData);
		oresenLocal.Reverse ();
		int rmvPos = dlDataCount - graphDispCount;
//		Debug.Log ("userChecked_" + );
//		Debug.Log ("rmvPos_" + rmvPos);
		if (rmvPos > 0) {
			oresenLocal.RemoveRange (0, rmvPos);
		}

//		Debug.Log(oresenLocal.Count);

		if (result > 0) {//最初のドロップダウン選択時のエラー排除用
			result--;
			int po = 1;
			//折れ線グラフ用データ作成
			for  (int i= 0; i < oresenLocal.Count ; i++){//横グラフにするgraData これが正解
				//ここでデータ作成
				syousaiVec.Add(new Vector2(po, oresenLocal [i] [result]));//List syousaidtaに選択したジャンルのデータを追加graData
				goukakuVec.Add(new Vector2(po, 74));
				po++;
	//			Debug.Log (i);
			}
			syousaiTitle = genreList[result];

			syousaiGraph.SetActive (true);
			//Debug.Log(oresenLocal.Count);
			//Debug.Log(checkedCount);
			//件数に応じて増減させる
		
			int rmvStart = userChecked - graphDispCount;
//			Debug.Log (rmvStart);
			if (rmvStart < 0) {
				rmvStart = 0;
				//下の計算は659行あたりも同じにすること

				//dateListLocal.RemoveRange (0, rmvStart);//最新版を残す設定で日付を削除するとグラフが削れる
			} else {
				dateListLocal.RemoveRange (0, rmvStart);//最新版を残す設定で日付を削除するとグラフが削れる
			}
			drawSyousaiGra ();//データセット完了後にグラフを描画する
		}else{
			result = 0;
		}
		//end IF
	}


	//詳細グラフ件数表示変更用
	void syousaiChange(){
		goukakuVec = new List<Vector2>();

		Debug.Log ("genreID" + genreID);
		syousaiVec = new List<Vector2>();
		List<List<float>> oresenLocal = new List<List<float>>(graData);
	//	int rmvPos = graData.Count - graphDispCount;
		int rmvPos = userChecked - graphDispCount;
		Debug.Log (rmvPos);
		Debug.Log ("V" + oresenLocal.Count);
		//oresenLocal.Reverse ();
		oresenLocal.RemoveRange (0, rmvPos);

		int poz = 1;
		if (genreID > 0) {
			genreID--;
			for (int i = 0; i < oresenLocal.Count; i++) {//横グラフにするgraData これが正解
//				Debug.Log ("int" + i);
				syousaiVec.Add (new Vector2 (poz, oresenLocal [i] [genreID]));//List syousaidtaに選択したジャンルのデータを追加graData
				goukakuVec.Add (new Vector2 (poz, 74));
				poz++;
			}
		}

		if (syousaiGraph.GetActive ()){
			
		dateListLocal = new List<string> (soyousaiDateList);//加工用のリストを新規に作成する

			//件数に応じて増減させる
		//	int rmvStart = checkedCount - graphDispCount;
			int rmvStart = userChecked - graphDispCount;
				if (rmvStart < 0) {
					rmvStart = 0;
					//下の計算は659行あたりも同じにすること
					dateListLocal.RemoveRange (0, rmvStart);//最新版を残す設定で日付を削除するとグラフが削れる
				} else {
			dateListLocal.RemoveRange (0, rmvStart);//最新版を残す設定で日付を削除するとグラフが削れる
			}
			drawSyousaiGra ();//データセット完了後にグラフを再描画する
		}
		//end IF
	}




	public void dropdownItem(){
		hyoujiDrop.ClearOptions ();//一旦リセット
		//int grakensu = checkedCount;
		int grakensu = userChecked ;
		if (grakensu < 6) {
			hyoujiDrop.options.Add (new Dropdown.OptionData { text = "〜5件" });
		}
		if (grakensu > 5 && grakensu < 11) {
			hyoujiDrop.options.Add (new Dropdown.OptionData { text = "〜5件" });
			hyoujiDrop.options.Add (new Dropdown.OptionData { text = "10件" });
		}
		if(grakensu > 10 && grakensu <21){
			hyoujiDrop.options.Add (new Dropdown.OptionData { text = "〜5件" });
			hyoujiDrop.options.Add (new Dropdown.OptionData { text = "10件" });
		hyoujiDrop.options.Add(new Dropdown.OptionData { text = "20件" });
		}
		if(grakensu > 20 && grakensu <31){
			hyoujiDrop.options.Add (new Dropdown.OptionData { text = "〜5件" });
			hyoujiDrop.options.Add (new Dropdown.OptionData { text = "10件" });
			hyoujiDrop.options.Add(new Dropdown.OptionData { text = "20件" });
		hyoujiDrop.options.Add(new Dropdown.OptionData { text = "30件" });
		}

		hyoujiDrop.RefreshShownValue();

	}



	//レーダーグラフ表示件数変更ドロップダウン用
	public void hyoujikensuDropChanged(Dropdown dropdown){

		if (dropdown.value == 0) {
			if (userChecked > 0 && userChecked < 5) {
				graphDispCount = userChecked;
			}else {
				graphDispCount = 5;
			}
		} else if (dropdown.value == 1) {
			if (userChecked >5 && userChecked < 10) {
				graphDispCount = userChecked;
			} else {
				graphDispCount = 10;
			}
		} else if (dropdown.value == 2) {
			if (userChecked < 20) {
				graphDispCount = userChecked;
			} else {
				graphDispCount = 20;
			}
		}else if (dropdown.value == 3) {
			if (userChecked < 30) {
				graphDispCount = userChecked;
			} else {
				graphDispCount = 30;
			}
		}
			
		syousaiChange();//詳細グラフを更新
		hideSeries (graphDispCount);
	}


	//詳細グラフの描画
	void drawSyousaiGra(){

		mycLocal = new WMG_List<Color> ();
		mycLocal.SetList (myc);//mycをmycLocalにコピー
		mycLocal.Reverse ();

		int rmvStart = 0;
		//int rmvStart = dlDataCount - graphDispCount;
		if (userChecked > 4) { //5件以上ならプルダウンの件数利用
			rmvStart = dlDataCount - graphDispCount;
		} else {
			rmvStart = dlDataCount - userChecked;//5件以下なら実際のデータ数で
		}

			mycLocal.RemoveRange (0, rmvStart);//最新版を残す設定で日付を削除して色数合わせる


		int LastDate = dateListLocal.Count - 1;
		// x軸の文字を表示する設定
		syousaiGraphGO.graphTitleOffset = new Vector2 (0, 60);
		syousaiGraphGO.graphTitleString = "[" + syousaiTitle+ "]" + dateListLocal[0] + "〜" + dateListLocal[LastDate];//グラフの上部に表示されるタイトル
		syousaiGraphGO.groups.SetList(dateListLocal);
		syousaiGraphGO.useGroups = true;
		syousaiGraphGO.xAxis.LabelType = WMG_Axis.labelTypes.groups;
		syousaiGraphGO.xAxis.AxisLabelSize = 20;
		syousaiGraphGO.xAxis.AxisLabelRotation = 70f;
		syousaiGraphGO.legend.hideLegend = true;//グラフの下の小さい凡例を消す
	


		int _xaxismemori = dateListLocal.Count;
		syousaiGraphGO.xAxis.AxisMaxValue = _xaxismemori;//x軸最大値
		syousaiGraphGO.xAxis.AxisNumTicks = _xaxismemori;
		syousaiGraphGO.xAxis.AxisMinValue = 0;//x軸最小値
		syousaiGraphGO.xAxis.AxisLabelSize = 18;//y 軸ラベルフォントサイズ
		syousaiGraphGO.yAxis.AxisMaxValue = 100;//y軸最大値
		syousaiGraphGO.yAxis.AxisMinValue = 0;//y軸最小サイズ
		syousaiGraphGO.yAxis.AxisNumTicks = 11;//y 軸分割
		syousaiGraphGO.yAxis.AxisLabelSize = 18;//y 軸ラベルフォントサイズ
		syousaiGraphGO.autoFitLabels = false;
		//syousaiGraphGO.legend.legendEntryFontSize = 24;


		series100.pointValues.SetList(syousaiVec);
		//series100.seriesName = "詳細";
		series100.usePointColors = true;
		//series100.usePointColors = false;
		series100.pointColors = mycLocal;//複数色

		series100.pointWidthHeight = 30;
		series100.lineColor = Color.gray;
		series100.lineScale = 2f;
		series100.dataLabelsEnabled = true;
		series100.dataLabelsFontSize = 24;
		series100.dataLabelsOffset = new Vector2 (18, -5);
		series100.dataLabelsColor = Color.white;

		//合格ライン描画用
		series200.pointValues.SetList(goukakuVec);
		series200.hidePoints = true;              // 点を表示
		series200.pointWidthHeight = 20f;
		series200.connectFirstToLast = true;      // 最後と最初の点をつなぐ
		series200.lineColor = Color.white; // 線の色白
		series200.lineScale = 2f;

	}


	// 詳細グラフを閉じる用

	public void closeSyousaiGra(){
		syousaiGraph.SetActive (false);

		//ドロップダウンをリセットする
		dropGO.GetComponent<Dropdown>().value = 0;
	}

}

 

AIキャラに追いつかれるとゲームオーバー

いくつかの設定項目あります

  • AIキャラ(AiThirdPersonController)のCupsuleColliderIsTriggerONにする
  • AiThirdPersonControllerにTagを設定する(Tagの付け方ははここを参照)このTag名で当たったのがAiかどうか判定します
  • 下記のスクリプトを作成し,ThirdPersonController(自分のキャラ)にアサインする

スクリプト(AiHit.cs という名前で保存)

using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;//シーン遷移をするのに必要

public class AiHit : MonoBehaviour {

	[SerializeField, HeaderAttribute ("AIキャラのタグ名")]
	public string myAiTag;

	[SerializeField, HeaderAttribute ("AIキャラに捕まったときのシーン名")]
	public string AiHitScene;

	void OnTriggerEnter(Collider hitCollider) {
		if (hitCollider.gameObject.tag == myAiTag) {
			this.gameObject.SetActive (false);//Playerを見えなくする
			Invoke("AiHitEnd", 2f);
		}
	}


	void AiHitEnd(){
		SceneManager.LoadScene (AiHitScene);//AIあたったシーン名へ
		//Destroy(this.gameObject);//Playerを消去する(使っていない)
	}
}

アサインしたら,ThirdPersonControllerのInspectorを確認し,AIキャラクタのタグ名を指定し,AIキャラに捕まったときのシーン名も指定する

ゲームを実行して確認してください.AIに追いつかれたら2秒後に指定したシーン名に遷移します

NCMBデータ作成日をJSTに戻す

NCMBのcreate DataはUTCなのでJSTに戻す

 

C#でもUnityだと動かない例(.NET 2.0だから?)

						DateTime dt = objdata.CreateDate.Value;//データ更新日をdtに
						TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
            DateTime jst2 = TimeZoneInfo.ConvertTimeFromUtc(dt, tzi);

 

Unityでも動く例

						DateTime dt = objdata.CreateDate.Value;//データ更新日をdtに入れる

						//UTCをJSTに
						TimeZone zone = TimeZone.CurrentTimeZone;
						TimeSpan offset = zone.GetUtcOffset(DateTime.Now);//オフセット取得して差分を出す
						DateTime jst = dt + offset;//差分を計算してJSTにする

ちょっとめんどい

メモ JSONが空問題

デバッグ環境ではどこかにPlayerPrefesが残っててエラーがおきないのだけど,初めてのユーザはそれが起こる問題

とりあえずの回避策

			//SUリストの取得?
			string mytest  = PlayerPrefs.GetString ("sulist");//PlayerPrefsに保存してるのはいかがなものかと,,
			//上のsulist(mytest)がnullならエラー出る
			if (mytest.Length > 0) {
				sudic = Json.Deserialize (mytest) as Dictionary<string, object>;

				foreach (KeyValuePair<string , object> pair in sudic) {
					Debug.Log (pair.Key + ":" + pair.Value);
					acl.SetReadAccess(pair.Value.ToString(), true);//加算用のテンポラリ変数
				}
			}

ログイン時にこのsulistを取らせることで根治できるはず

AIから追従対象までの距離を出す

2点間の距離を取得する場合,通常では

Vector3
.Distance(
Vector3

obja

,
Vector3

objb

);
などで取得するが,AIを使う場合はベクトルの計算ではなくAI(NavMesh)から距離が取れる(距離を出力してくれる)

 

//変数系

public     NavMeshAgent mynav2;//インスペクタに現れるのでNavMeshがついているゲームオブジェクトをアサインする

float enemyDistance;

//以下をUpdate(){  } の中に入れる

enemyDistance = mynav2.remainingDistance;

で取得可能.

 

スクリプトサンプル例

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class aiDistance : MonoBehaviour {
	public     NavMeshAgent mynav2;//インスペクタに現れるのでNavMeshがついているゲームオブジェクトをアサインする
	float enemyDistance;
	public Text disTex;
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
		enemyDistance = mynav2.remainingDistance;
		disTex.text = enemyDistance.ToString ();
	}
}

実行画面例

unity AIのターゲットを途中で変更

動的に変更できる

時間がないのでスクリプト全文

using UnityEngine;
using System.Collections;
//using UnityStandardAssets.Characters.ThirdPerson;

public class targetchange : MonoBehaviour {
	public NavMeshAgent myObj;
	public Transform goalpos1;
	public Transform goalpos2;
	public Transform dummy;//AIThirdPersonを入れる
	Transform setPos;

	void Start(){
		setPos =  dummy;
	}

	void Update(){
		
		myObj.SetDestination (setPos.position);
	}

	//スピードを0.5に変える
	public void chngSpeed(){
		myObj.speed = 0.5f;
	}


	//ターゲットをgoalpos1にする
	public void target1(){
		setPos = goalpos1;

	}

	//ターゲットをgoalpos2にする
	public void target2(){
		setPos = goalpos2;
	}
}

参考動画(ボタンで切り替えています)

AI機能を用いたゲームの制作(1)

今回はAI(人工知能)を利用したゲームを制作する
この場合のAIとは流行のDeep Learning(深層学習)ではなく,最短距離を検索する経路探索アルゴリズムである
UnityではNavigation SystemでA*というアルゴリズムを利用してこれを実現している
https://docs.unity3d.com/jp/current/Manual/nav-InnerWorkings.html

1)Navigationの使い方

  1. File>New Scene で新規シーンを作成
  2. GameObject>3D Object>Plane で平面を作成
  3. InspectorでScaleを全て10倍にする
  4. Project内の StandardAssets>Characters>Prefabs から,(A)ThirdPersonControllerと(B)AIThirdPersonControllerをPlane上に配置する
  5. (B)AIThirdPersonCharacotrを選択し,InspectorにあるAI Character Control内Targetに,ヒエラルキーの(A)ThirdPersonCharacotrをアサインする
  6. メニューバー>Window>Navigationを選択
  7. 設置したPlaneを選択し(下図1),Navigationの設定からObjectを選択(下図2)し,Navigation Staticにチェックをれ(下図3),Navigation AreaからWalkableを選択(下図4)
  8. 右下のBakeをクリック(上図の5)し,歩行可能エリアを焼き付ける
  9. ゲームを再生してみる
  10. やたら速く追いかけられる
  11. そこで(B)AIThirdPersonControllerのInspectorにあるNav Mesh AgentSpeed(初期値は1)を変える.これで追いかけられるスピードを変更することができる

NPC(Non Player Character)を動かす一つの方法として,こうしたアルゴリズムが利用されている

 

2)歩行不可エリアの設定

  1. 次に,障害物を設置し,歩行不可エリアを設定する
  2. StandardAssets内ProtoType内のPrefabを適当に配置する(Projectに無い場合は,Assets>ImportPackages>Prototypingで読み込む)
  3. Prefabs内のモデルをPlane上に配置する.自由な位置に置いてかまわない
  4. 置いたPrefabを選択し,Navigation Staticにチェックを入れ,Navigation AreaからNot Walkableを選択
  5. 右下のBakeをクリックし,歩行不可能エリアを焼き付ける
  6. ゲームを再生する

追いかけるスピードを変化させることで,例えばゾンビが,撃たれたきっかけでスピードを落としたり,距離で判定しギリギリで追いつかないといった設定もできる

これらを利用して可能なのが

・鬼ごっこ

・障害物競走

・だるまさんがころんだVR(需要あるのか?)

などではないか.

3)ゲームを企画する

これまでのテクニックを用いて,AIを用いたゲームを企画し,実際に制作せよ.地形(Terrain)またはPlane上でプレイし,制限時間を設けること.

なんらかの勝ち,負けを判定し,結果を変えること

スクリプトはEdukit内の物を使ってかまわない(改造してもかまわない)

機能ではなく世界観やその世界が持つ独自のルールに注力すること

NCMB パスワードリセット

UnityでのNCMBパスワードリセットの方法(全文)

時間ないので全文転載

using UnityEngine;
using System.Collections;
using NCMB;
using UnityEngine.UI;//use unity gui
using UnityEngine.SceneManagement;

public class PassReset : MonoBehaviour {

	public Text emailfield;
	public Text statustxt;
	string meado;
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}



	public void doResetvoid(){
		meado = emailfield.text;
		//NCMBUser user = new NCMBUser();
		NCMBUser.RequestPasswordResetAsync(meado,(NCMBException e) => {    
			if (e != null) {
				UnityEngine.Debug.Log ("ログインに失敗: " + e.ErrorMessage);
				statustxt.text = "リセットに失敗しました\nメールアドレスを確認してください";
			} else {
				statustxt.text = "パスワードリセットに成功しました\nメールを受信しパスワードを再設定してください";

				Invoke("toTop", 3f);
			}
		});

	}


	//scne change
	public void toTop(){
		SceneManager.LoadScene ("top");
	}

}

メールに仮パスワードとリセットページへのリンクが届くのでWEBでリセットするらしい

NCMBのユーザIDをplayerPrefsに入れて呼び出す

NCMBのuser.objectIdを取得して,他のところで使います

//JSON読み込み
				foreach (NCMBUser users in userList) {
					suDicAll.Add(users.UserName.ToString(), users.ObjectId.ToString());//Dictionaryに入れる

				//ここでJSON化し,PlayerPrefesに入れる
					myjson = Json.Serialize(suDicAll);

				}//foreachここまで
PlayerPrefs.SetString("sulist", myjson);


//JSON読み出し
using MiniJSON;//use miniJSONが必要です

			string mytest  = PlayerPrefs.GetString ("sulist");
			var sudic = Json.Deserialize(mytest) as Dictionary<string, object>;


			foreach (KeyValuePair<string , object> pair in sudic) {
				Debug.Log (pair.Key + ":" + pair.Value);
				acl.SetReadAccess(pair.Value.ToString(), true);//加算用のテンポラリ変数
			}