2019の終わりが近づいてまいりました。
令和元年に何かを残したくて日々勉強中です。
年内中に簡単なアプリをアウトプットできるように
頑張ってるのですが、思うように行かないのがプログラムと人生。
無事にできるといいのですが(´`;)
さてさて、勉強中に仕入れた情報を少し書いてみたいと思います。
以前、CSVの扱いを書いたのですが、
ファイルの内容をエクセルで編集する必要があったので、
オープンなフォルダに保存できるようにしていました。
ゲームのフィールドデータやゲーム内容を保存する場合、
オープンなファイルに保存するとユーザーからもアクセスできるので、
内容の編集ができてしまうのは問題があります。
なので、大事なデータはResourcesフォルダー内に保存して
読み書きできるようにするのが、一般的だと思います。
ハックできる人なら簡単に見る事ができるそうですが、
そのへんはスルーします。(;^o^) \(ToT )あんたほんとにそれでいいの
今回は、csvデータからオブジェクトをクローン配置してみます。
内容としては、脱出ルートの表示にしてみようかと思います。
用意したのは、

矢印だらけで分かりにくい… (..*) オハズカシイ・・
フィールドに隠された爆弾があり、条件を満たすと脱出ルートと爆弾が表示される
みたいな感じです。
まず、クローンを生成する為にオブジェクトをプレハブにします。

それぞれの4方向のプレハブと爆弾のプレハブを準備します。
クローンオブジェクトは、クリアするまで非アクティブにしたいので、
RootParentの親オブジェクトを作成して、その中にクローンを用意します。
クローンができた所で、親オブジェクトを非アクティブにすれば、
一括でクローンを隠す事ができます。
続いて、エクセルでマップデータを作成します。
クローンは配列で管理するので、配列番号とクローンを合わせます。
今回は、
0=Bomb
1=UP
2=RIGHT
3=DOWN
4=LEFT
空きマス=B
としておきます。

エクセルで6×6のフィールドデータを作成して、

csvで保存する際、UTF-8を選択しておくとandroidにも対応できます。
ちなみに空きマスをBとしましたが何でもいいです。
空白を作ると読み込めないので、何かわかるようにしておきます。
今回は、ブランクのBにしました。
読込み時に判別できれば問題なしでっす。
Unityに戻って、CSVファイルをインポートします。

まず、Resource内にTextDataのフォルダを作ります。

TextDataのフォルダを開けて、先ほどのCSVファイルをインポートします。
続いて、スクリプトを作成します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System;
public class GameManager : MonoBehaviour
{
public GameObject RootParet; //クローンの親オブジェクト
public GameObject[] RootPanelPrefab; //各オブジェクトのプレハブ
//縦横のポジション座標
private float[] AxisX = { -250, -150, -50, 50, 150, 250 };
private float[] AxisY = { 250, 150, 50, -50, -150, -250 };
private string FilePath = "TextData/RootData"; //CSVファイルのパス
// Start is called before the first frame update
void Start()
{
StartCoroutine(LoadCSV());
}
IEnumerator LoadCSV()
{
TextAsset csvFile = Resources.Load<TextAsset>(FilePath);
StringReader reader = new StringReader(csvFile.text);
List<string[]> csv = new List<string[]>();
//CSVファイルの読み出し
while (reader.Peek() != -1)
{
string line = reader.ReadLine();
csv.Add(line.Split(','));
}
reader.Close();
//データからオブジェクトの選定
for(int y = 0; y < 6; y++)
{
for (int x = 0; x < 6; x++)
{
if (csv[y][x] == "B")
{
continue;
}
else
{
int num = Convert.ToInt32(csv[y][x]);
CreateObject(x, y, num);
}
}
}
RootParet.SetActive(false);
if (RootParet.activeSelf == false)
{
yield return null;
}
}
//オブジェクトの生成
void CreateObject(int x,int y, int num)
{
GameObject root = (GameObject)Instantiate(RootPanelPrefab[num]);
root.transform.SetParent(RootParet.transform, false);
root.transform.localPosition = new Vector3(AxisX[x], AxisY[y], 0);
}
}
StreamReaderを使うので、System.IOを宣言します。
途中でstring型からint型に変換するので、Systemも宣言します。
ファイルのパスは、Resources.LoadでResourcesフォルダまで開いてくれるので、
続きのTextData/RootDataを指定すれば読み込めます。
CSVファイルの拡張子はいりません。
おそらくTextassetとして取り込むので、必要なくなるのでは?
と思っています。ちなみに拡張子を付けると読み込めません。
ファイルから、読み出し座標xyとオブジェクトナンバーを取得して、
ナンバーのみクローンを生成するようにしてみました。
コルーチンでセットしたのは、オブジェクトの生成後に親オブジェクトを
非アクティブにするまで、他の処理を停止する為です。
例えば、クローンに当たり判定を付けていた場合、
フィールド配置のオブジェクトにプレイヤーオブジェクトを重ねて
配置した場合、同時に配置すると当たり判定が出てしまいます。
Destroyなどを呼び出していると、生成と同時に削除されてしまうので、
フィールドオブジェクトを配置して、非アクティブにしてから、
メインオブジェクトを配置すると事故が起こらないかと思います。
少し難点は、StreamReaderでファイルリードをループした所で
再度、リストからオブジェクト生成のループを回している所ですかね。
読込みながら生成を組んでみたのですが、
なぜかCSVの一行目を繰り返し読み込んでしまいました。
仕方がないので生成を分離しました。
この辺りは、今後の課題ですかね~ (~ヘ~;)ウーン
最後にPLAYしてみます。

ちょっと分かりにくいですが、ヒエラルキーを見るとクローンが生成されています。
親オブジェクトをアクティブにすると…

無事、生成されております。
後は、クリア判定を用意して親オブジェクトをアクティブ化すればOKかと。
煮るなり焼くなり好きにできます。
同じようなフィールドで複数面あるようなゲームでは、
Sceneを作成するだけで大変になります。
Sceneの切り替えをナンバー化すれば、データの読込みだけになるので、
Textデータからのオブジェクト配置は重要になりそうです。
エクセルでマップデータを作るのも大変なので、
Unityでフィールドデータを編集できるアプリを作っておくと
より楽に複数面の準備ができるようになるかと思います。
プレイSceneの作成に役立ててもらえると嬉しいです。
今回は、この辺で(o・・o)/~マタネェ
この記事へのコメント