ファイブボックスではUntiyの初心者から上級者まで、会員様の習得度に応じたカリキュラムをご用意しています。
今回から数回にわたり、ファイブボックスのカリキュラムをご紹介していきます。
1つ目はステップ6で学習する「フィッシングゲーム」です。
UnityRoom(ユニティルーム)で公開していますので、ご興味があればこちらもご参考にしてください。
カリキュラムの全貌
この作品は次の15のステップから構成されており、各ステップ2時間から4時間程度、合計30時間から50時間程度でこの作品を完成させていきます。
かなり長いカリキュラムですが、各フェーズ基礎からの振り返りもできて充実した内容になっています。
- フェーズ1 環境構築とデータの取り込み
- フェーズ2 魚の生成
- フェーズ3 プレイヤーの動き
- フェーズ4 エサの管理
- フェーズ5 ヒットのフロー
- フェーズ6 獲得情報表示
- フェーズ7 メニュー作成と効果音
- フェーズ8 ショップシーン作成
- フェーズ9 データのセーブとロード
- フェーズ10 ランキング機能
- フェーズ11 コレクション機能
- フェーズ12 詳細データ表示
- フェーズ13 ステージ管理
- フェーズ14 各種演出
- フェーズ15 釣り竿とリールの購入システム
今回はフェーズ1のカリキュラムをご紹介します。
フェーズ1のご紹介
環境構築とデータの取り込み
環境構築
Unityで新たに2Dのプロジェクトを作成します。
❶ 2D のプロジェクトを指定
❷ プロジェクト名に 「Lets Go Fishing」などの適当な名前を指定
❸ 保存場所に任意の場所を指定
❹「プロジェクトを作成」ボタンを選択
Webブラウザでゲームをプレイできるように、環境を変更します。
上部のメニューから、File => Build Settings をクリック。
「WebGL」 を選択して 「Swich Platform」 をクリック。
さらに 「Player Settings」 のメニューを展開。
「Player」 => 「WebGL」タグ を選択 => 「Resolution」 の項目から以下のように指定
[Default Canvas Width] = 960
[Default Canvas Height] = 540
※解像度は任意で指定していただいても結構ですが、このカリキュラムでは上記で指定した値をベースに各種オブジェクトの大きさ等を指定していきます。
解像度の設定が完了したら、ゲーム時の解像度も指定します。
Gameビュー を表示し、上部メニューから解像度を指定します。
Gameビュー の上部で表示上の解像度、アスペクト比などを指定することができます。今回は上で指定したアスペクト比に合わせ「16:9 Aspect」に指定しておきます。
作成されたプロジェクトに、初期状態で用意されている「Sceneフォルダ」の名前を変更、他に2つのフォルダを作成します。
❶ 「01_Scenes」 ⇒ 既存の「Scene」フォルダの名前を変更、Scene を管理
❷ 「02_Scripts」 ⇒ スクリプトファイルを格納するフォルダ
❸ 「03_Prefabs」 ⇒ プレハブを格納するフォルダ
さらに「01_Scene」フォルダの配下に2つのシーンを作成します。
❶ 「StartScene」 スタートシーンとなります(既存の SampleScene の名前変更でも構いません)
❷ 「GameScene」 ⇒ 釣りゲームのシーンとなります。
作成した2つの Scene を利用する Scene としてに登録します。
Unityメニューの [File] => [Build Settings] と遷移して「StartScene」と「GameScene」を上部の 「Scenes in Build」のエリアにドラッグ&ドロップして登録します。
さらに画像ファイルや魚、えさなどの情報を記載したテキストファイルや、画像ファイルなどをまとめた素材を取り込みます。
Unityメニューの「Assets」から「Import Package」⇒「CousomPackage」と辿り、指定したパッケージを取得します。
素材取り込み後のAssets内は、以下のような構成となります。
フォルダ名 | 内容 |
---|---|
01_Scenes | 各種シーンを格納 |
02_Scripts | スクリプトファイルを格納 |
03_Prefabs | プレハブを格納 |
04_Sprits | 画像素材を格納 |
05_Others | その他の素材(音源、フォント等)を格納 |
Resources | プログラムから取り込むための素材を格納 |
魚のデータ取込み
素材の用意
この作品では多くの魚のデータを使用しますので、上の課題で取得済みのテキストファイルからデータを取り込みます。
取得するデータ「FishData」は以下のようなものです。
※「FishData」を原本をご希望の場合は教室までお問い合わせください。
また取り込むデータの説明、および取込み後に変換し使用する変数と変数の型は以下の通りです。
データ | 変数名 | 変数の型 | 説明 |
---|---|---|---|
Name | f_Name | string | 魚の名前 |
Size | f_Scale | int | 魚の基準の大きさ |
ImgSize | f_ImgScale | int | 表示上の基準の大きさ |
Speed | f_Speed | int | 魚の泳ぐ速さ |
Price | f_Price | int | 魚の基準の価格 |
Level | f_Level | int | 魚をヒットさせる難易度 |
Appearance | f_App | int | 魚を出現率 |
Sprite | f_Img | Sprite | 魚の画像(別途用意) |
Unityでスクリプトファイルからテキストデータを取り込むためには、タイトル行を除いたテキストファイルファイルを Assets 内の 「Resources」という名前のフォルダに該当のファイルを配置します。
同様に画像ファイルを取り込むにはどうフォルダ内に画像ファイル(png,jpeg等)を格納します。 下の図のように 「Resources」フォルダ内にサブフォルダを作成し、そこにまとめて配置しても問題ありません。
※魚の画像フォルダをご希望の場合、教室までお問い合わせください
今回のテキストファイルは以下の条件で作成しました。
ファイル名 :fish.txt
区切り :タブクリり
文字コード :utf-8
素材の取り込み
データ取込みは「StartScene」で行います。 「01_Scene」 フォルダ内の StratScene をダブルクリックしてActive状態にしておきます。
ここでは用意したテキストデータを取り込んで、2次元配列として保管します。
Aseets 内に配置した 「02_Scripts」 フォルダ内に「DataManager」 というスクリプトファイルを作成します。
さらにHierarchy上に 「DataManager」 という空のオブジェクトファイルを作成し、スクリプトファイル 「DataManager.cs」 をアタッチしておきましょう。
ここで行うデータ取り込みの流れは以下の通りです。
❶ [fish.txt] 内のテキストデータを全部取り込む
❷ 取り込んだテキスト1行1行を1次配列に入れ込む ⇒ 180個の要素を含む1次配列
❸ テキストの行数と列数を取得して最終的に入れ込む2次配列のサイズを決める
❹ 2,で取り込んだ1行1行を、for文を使ってタブ区切りで2次配列に変換する
[DataManager.cs] を立ち上げて、以下のコードを記述します。
まず、NameSpace に使用するシステムを追加します。
DataManager.cs
using System;
ここで使用する変数は以下の通りです。
変数名 | 型 | 修飾子 | 説明 |
---|---|---|---|
fishRow | int | static private | テキスト内の行数を取得するための変数 |
fishColumn | int | static private | テキスト内の列数を取得するための変数 |
また以下の配列を用意します。
配列名 | 型 | 修飾子 | 説明 |
---|---|---|---|
textSauce | string | private | 取込んだテキストの加工前の一行を入れる配列 |
fishData | string | static public | 取込んだテキストの全データを入れる2次元配列 |
DataManagerクラスに配列と変数を宣言します。
DataManager.cs
string[] textSauce; //取込んだテキストの加工前の一行を入れる配列
static public string[,] fishData; //取込んだテキストの全データを入れる2次元配列
static int fishRow, fishColumn; //取込んだテキスト内の行数と列数を取得する変数
ここでは最終的なデータが格納される配列、fishdata[ , ] のみ public変数 にしています。fishdata[ , ] には様々なデータが登録されるので、この後作成する各クラスからもアクセスできるようにします。
それではデータ取り込みの関数 Initialization() を作成します。
DataManager.cs
void Initialization() //データ取り込み処理
{
//fish.txtのデータを取得するインスタンスを作成
TextAsset textasset = new TextAsset();
//Resourcesフォルダから対象のテキストファイルを取得
textasset = Resources.Load("fish", typeof(TextAsset)) as TextAsset;
//string型の変数を用意して、上で取得したテキスト全体を入れる
string TextALL = textasset.text;
//Splitで改行コード(\n)をキーに、一行づつの1次配列を作成
textSauce = TextALL.Split('\n');
//行数と列数を取得
fishColumn = textSauce[0].Split('\t').Length; //タブ区切りで分けられたブロック数⇒7
fishRow = textSauce.Length; //データ数⇒180
fishData = new string[fishRow, fishColumn]; //2次配列を定義 [108,7]
for (int i = 0; i < fishRow; i++)
{
//textMessageをタブごとに分けたものを一時的にtempに代入,
//temp[0]⇒魚名 [1]⇒大きさ [2]⇒Spritの大きさ [3]⇒速さ [4]⇒価格 [5]⇒難易度 [6]⇒出現率
string[] temp = textSauce[i].Split('\t');
for (int j = 0; j < fishColumn; j++) //Dataの数だけ繰り返す
{
//2次配列fishdata[,]にタブごとに分けたtempを代入していく
fishData[i, j] = temp[j];
}
}
}
作成した関数を Initialization() をStart関数 内で呼び出します。
DataManager.cs
void Start()
{
Initialization();
}
これで実行ボタンを押して、関数を呼び出してみましょう。
データが正しく呼び出されたか、まずは Inspector で確認してみます。
下の図のように Inspector の右上、三点リーダーをクリック、「Debug」 を選択します。
表示された内容からDataManagerの各種変数、配列などの値が、用意したものと同じになっていればOKです。
確認ができたら Inspector の表示形式を 「Normal」 に戻しておきましょう。
問題1
作成した配列に、正しくデータが格納されているか、foreach()関数を使って表示させてみましょう。
foreach() 文 の記述方法は以下の通りです。
foreach()文
foreach ( 型名 object名 in コレクション名(リスト、配列等))
{
処理文
}
foreach()文 ではfor文のように、インデックス番号を指定する int型変数 i を定義したり、それをループごとにインクリメント(i++)する必要はありません。
また、コレクションの要素数を取得する必要もありません。ですので、簡潔に記述することができて便利です。
このプロジェクトでは、この後も多くの配列やリストを作っていきます。
リストから任意のデータを取り出す方法や、確認する方法をマスターしておきましょう。
魚の画像取り込み
魚の画像は取得済みの 配列 : fishData[ ] の名前をキーに Resourcesフォルダから取得し、配列 : fishImage[ ] に取り込みます。
新たに使用する配列は以下のおとりです。
配列名 | 型 | アクセス | 説明 |
---|---|---|---|
fishImage | Sprite | static public | 魚の画像を入れるSprite型の配列 |
DataManagerクラス で変数の宣言、および画像の読み込み関数:SetFishImage()を作成します。
DataManager.cs
static public Sprite[] fishImage; //魚の画像を格納する配列
void SetFishImage() //魚の画像の取り込み
{
fishImage = new Sprite[fishRow]; //fishImage[]を初期化
for(int i = 0;i < fishRow;i++) //魚の数だけ繰り返す
{
string pass = "fish/" + fishData[i, 0] ; //画像のパスを取得
fishImage[i] = Resources.Load<Sprite>(pass); //配列のi番目に画像素材をセット
}
}
解説
string pass = “fish/” + fishData[ i, 0] ;
プログラムから画像を呼び出すには、テキスト同様「Resourcesフォルダ」に素材を配置します。サブフォルダから画像を呼び出すときは「/(スラッシュ)」を入れてサブフォルダを指定します。
また画像の拡張子(.jpeg .png等)は入力しなくてもOKです。
ここではいったん文字列型の変数:pass にfishフォルダ内の配列:fishData[ , ] i番目の0番目のデータ、つまり魚の名前を取得する画像名として指定しています。
fishImage[i] = Resources.Load<Sprite>(pass)
宣言した配列:fishImage[]の i 番目に上で取得した変数:pass を指定しています。Resourcesフォルダから画像を取得するには Resources.Load<Sprite>() メソッドを使用し、カッコ内に該当の素材名を指定します。
Start()関数 で作成した関数を呼び出します。
DataManager.cs
void Start()
{
Initialization(); //データ取込み 記述済み
SetFishImage(); //画像取り込み
}
それでは取り込んだ画像が正しく入っているか確認します。
魚の画像で確認するためには、UIでImageなどを使用します。
今回は取り込んだ魚の「名前」で確認したいと思います。
DataManager.cs
void SetFishImage() //魚の画像の取り込み
{ /* 記述済み
fishImage = new Sprite[fishRow];
for(int i = 0;i < fishRow;i++)
{
string pass = "fish/" + fishData[i, 0] ;
fishImage[i] = Resources.Load<Sprite>(pass);
}*/
for(int i = 0;i < fishRow; i++) //データ確認
{
Debug.Log(i + "番目:" + fishImage[i].name) ; //画像の名前を表示
}
}
確認が済んだらこの確認用の繰り返し文は不要になるので、コメントアウトしておきます。
シーンの遷移
Static 変数で指定した変数、配列はシーンを遷移しても値が保持されます。
ここで StartScene から GameScene へ遷移する仕組みを作っておきます。
Hierarchy上に UI => Buttton(Legacy) を配置します。
配置したボタンを「StartButton」に変更しておきます。
DataManagerクラスに、ボタンを押したタイミングで「GameScene」に遷移するというプログラムを作成します。
シーンの遷移を扱うので、まずは NameSpace に UnityEngine.SceneManagement を使用する宣言を行います。
DataManager.cs
using UnityEngine.SceneManagement;
続いてシーンを遷移する関数を準備します。
DataManager.cs
public void StartNewGame()
{
SceneManager.LoadScene("GameScene"); //GameScene に遷移
}
この関数を下の図のように StartButton に Assign します。
では StartButton を押したときに「GameScene」に遷移することを確認しておきましょう。
背景の作成
ここから「GameScene」のステージ上のオブジェクトを作成、配置していきます。
まずは背景画像を作成します。
この作品の釣りシーンは4つステージで構成されます。それぞれ違う背景画像にしたいと思いますので、4つの水中のフリー素材を用意します。
さらにそれぞれの水中の画像の表面に別の水面の画像を重ね、その画像を左右に揺らすことで並の演出を行います。
素材の配置
背景は画面下部に「水中」の素材を、上部に「空」の素材をセットします。
下の図のように、Canvasの配下に3つのパネルを配置します。
Canvasの設定
Inspectorから以下のように修正します。
❶ 名前:BGcanbvas に指定
❷ Canvasコンポーネント
Render Mode:Screen Space-Camera に指定
Render Camera:MainCamera に指定
Vertex Color Always:チェックを入れる
❸ CanvasScalerコンポーネント
UI Scale Mode:Scale With Screen Size に指定
Reference Resolution:x:960 y:540
空の画像
1つ目のPanelを修正します。
事前にこの背景で使用する素材を AssetStore から取得します。
「AllSky無料版」から素材を取得しますが、このAssetがとても重いので必要な素材だけimportしましょう。
「Epic_BlueSunset_Cam_0_Front+Z.png」など頭に「Epic_」が付く複数のpngファイルを取得します。
中身を確認していただき、ご自身のイメージに合うものを選択してください。
Inspectorから以下のように修正します。
❶ 名前:SkyPanel に指定
❷ RectTransformコンポーネント
Top:-100,Bottom:130 程度に指定
❸ Imageコンポーネント:
SourceImage:取得した任意の空の背景画像を指定
※サンプルでは「Epic_BlueSunset_Cam_0_Front+Z」を指定しました
Color:不透明度を100%に指定します。
水中の画像
2つ目のPanelは水中の画像になります。ステージごとに4種類の画像を用意しますが、まずは川の中の画像でベースとなる部分を作成します。
Inspectorから以下のように修正します。
❶ 名前:WaterPanel に指定
❷ RectTransformコンポーネント
Top:150,Bottom:-50 程度に指定
❸ Imageコンポーネント:
SourceImage:取得した水中の画像から「Stage01」を選択
Color:不透明度を100%に指定します。
波の演出
3つ目のPanelには水中の画像を配置し、プログラムから揺らすことで波の演出を作ってみます。
まずはInspectorから下のように指定します。
❶ 名前:WavePanel に指定
❷ RectTransformコンポーネント
Left:-100 , Right:-100 左右に揺れるので、左右に余白を確保
Top:150 , Bottom:-50 程度に指定(水中の画像と合わせる)
❸ Imageコンポーネント:
SourceImage:取得した水中の画像から「Wave」を選択
Color:不透明度を50%程度に指定します。
ここまでの課題で下のようなステージ背景が完成しています。
波のプログラム
続いて波の動きを作成していきます。
作成した WavePanel を左右に揺らすためのプログラムを管理するスクリプトファイル「Wave」を「02_Scripts」フォルダ内に作成し、WavePanel にアタッチします。
問題2
下の条件で WaveクラスにWavePanel を左右に揺らし続けるプログラムを作成してみましょう。
条件1:三角関数を使って左右の移動を管理する
条件2:どのデバイスでも同じ動きが実行されるように FixUpdate()関数を活用
ここではここで、WebGlで正しく表示されるか確認しておきます。
上部メニューの「File」から 「Build And Run」 を選択。
初回のみファイルを保存する場所を聞いてくるので、任意のフォルダを指定します。
初回は特に時間がかかるので、余裕を見て実行します。
成功すると以下のようにブラウザ上でゲームのSceneを確認することができます。