Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9703

ファイブボックス Unityカリキュラム Step6 あつ森風フィッシングゲーム

$
0
0
このサイトは「プログラミング教室・ファイブボックス」の Unity学習カリキュラム ステップ6 「あつ森風、フィッシングゲーム作成」のフェーズ1になります。 サンプルカリキュラム Step1 Unityの基本 このプロジェクトでは以下のような作品を作ります。 あつ森風、フィッシングゲーム作成 (クリックでゲーム開始) フェーズ1 仕様確認と環境構築 1-1,ゲームの仕様確認 この作品の通常のフローは以下の通りです。 通常のフロー ❶魚を発生させる(乱数で魚の種類や大きさ、進行方向、ターン回数決定) ❶エサをセット(初期値は10個とし釣れるごとに1つ減少。なくなったら購入) ❷釣り糸を垂らす(エサと釣り竿の先端をRayでつなぐ) ❹魚の口先とエサがぶつかったら、特定の確率でヒットする ❺釣り上げる(釣り竿の先端にエサが触れたら魚を獲得) ❻釣った魚を記録する さらに次のオプション機能を追加 オプション機能 ❶進行中のゲーム内容のセーブとロード(釣った魚、所持金、エサなど) ❷ランキング表示機能(大きさ順、金額順、釣った数の順など) ❸釣った魚の図鑑機能(釣った数、合計金額など) ❹エサの購入 ❺釣り竿の購入 ❻ステージ管理 これらのフローと機能を順に作成していきます。 1-2,プロジェクトの作成 2D のプロジェクトを指定し、プロジェクト名に 「FishingGame」 などの適当な名前を指定、保存場所に任意の場所を指定し、「プロジェクトを作成」ボタンを押します。 Webブラウザでゲームをプレイできるように、環境を変更します。 上部のメニューから、File => Build Settings をクリック。 「WebGL」 を選択して 「Swich Platform」 をクリック。 さらに 「Player Settings」 のメニューを展開。 「Player」 => 「WebGL」アイコンタグ を選択 => 「Resolution」 の項目から [Default Canvas Width] = 960 [Default Canvas Height] = 600 に指定されていることを確認します。 作成されたプロジェクトに、初期状態で用意されている「Sceneフォルダ」、フォルダ内の 「SampleScene」 の名前をそれぞれ次のようにに変更しておきます。 フォルダ「Scene」=> 「01_Scenes」 Scene「SampleScene」=> 「GameScene」 Asset 内に次の3つのフォルダを用意しておきます。 「02_Scripts」 => スクリプトファイルを保存するフォルダ 「03_Predabs」 => プレファブを保存するフォルダ 「04_Sprites」 => 画像ファイルを保存するフォルダ その他の設定やフォルダ作成は、必要に応じて都度行っていきます。 これでプロジェクト作成の準備は完成です。 1-3,魚の配列作成 1-3-1,テキストファイルの用意 素材は こちら から取得してください。 Download後、メニューバーの「Asset」⇒「Import Package」でDownload下ファイルを指定し、取り込みます。 この作品では多くの魚のデータを使用しますので、別途用意するテキストファイルからデータを取り込みます。 取り込むデータは以下の通りです。 データ 変数名 説明 Name f_Name 魚の名前 Size f_Scale 魚の基準の大きさ ImgSize f_ImgScale 表示上の基準の大きさ Speed f_speed 魚の泳ぐ速さ Price f_Price 魚の基準の価格 Level f_Level 魚をヒットさせる難易度(大きいほど難易度が高い) Sprite f_Img 魚の画像(別途用意) FishData 上のようなイメージで作成します。 Unityの取り込むのは、タイトル行を除いたテキストファイルとなります。 テキストファイルは以下の条件で作成します。 ファイル名 :fish.txt 区切り :タブクリり 文字コード :utf-8 Aseets 内に「Resources」という名前のフォルダを作成し、用意した [fish.txt] を格納します。 画像素材は各自用意して頂くか、教室で用意した素材を取り込んで使ってください。 取り込んだ魚の画像は、事前に作成した「04_Sprits」というフォルダの中に「fish」というフォルダを作成し、その中に保存しておきます。 1-3-2,テキストデータ取り込み このフェーズでは用意したテキストデータを取り込んで、2次元配列として保管します。 まずは、Aseets 内に配置した「02_Scripts」 フォルダ内に[GameManager] というスクリプトファイルを作成します。 さらにHierarchy上に 「GameManager」 というオブジェクトファイルを作成し、スクリプトファイル 「GameManager.cs」 をアタッチしておきましょう。 データ取り込みで行う処理の流れは以下の通りです。 ❶ [fish.txt] 内のテキストデータを全部取り込む ❷ 取り込んだテキスト1行1行を1次配列に入れ込む ⇒ 108個の要素を含む1次配列 ❸ テキストの行数と列数を取得して最終的に入れ込む2次配列のサイズを決める ❹ 2で取り込んだ1行1行を、for文を使ってタブ区切りで2次配列に変換する [GameManager.cs] を立ち上げて、以下のコードを記述します。 まず、NameSpace に使用するシステムを追加します。 GameManager.cs using System; 続いて使用する変数を用意します。 GameManager.cs string[] textSauce; //テキストの加工前の一行を入れる変数 public string[,] fishdata; //テキストの複数列を入れる2次元配列 int rowLength; //テキスト内の行数を取得する変数 int columnLength; //テキスト内の列数を取得する変数 ここでは最終的なデータが格納される配列、fishdata[,] のみ public変数 にしています。 これは後に他classからも参照したいためです。 さらにデータ取り込みの関数 Initialization() を作成します。 GameManager.cs void Initialization() //データ取り込み処理 { //fish.txtのデータを取得するインスタンスを作成 TextAsset textasset = new TextAsset(); //Resourcesフォルダから対象のテキストファイルを取得 textasset = Resources.Load("fish", typeof(TextAsset)) as TextAsset; //string型の変数を用意して、上で取得したテキスト全体を入れる string TextLines = textasset.text; //Splitで一行づつを代入した1次配列を作成、(改行で分けるので1行の文字列となる) textSauce = TextLines.Split('\n'); //行数と列数を取得 columnLength = textSauce[0].Split('\t').Length; //タブ区切りで分けられたブロック数⇒6 rowLength = textSauce.Length; //データ数⇒108 fishdata = new string[rowLength, columnLength]; //2次配列を定義 [108,6] for (int i = 0; i < rowLength; i++) { //textMessageをタブごとに分けたものを一時的にtempに代入, //temp[0]⇒魚名、[1]⇒大きさ、[2]⇒Spritの大きさ、[3]⇒速さ、[4]⇒価格、[5]⇒難易度 string[] temp = textSauce[i].Split('\t'); for (int j = 0; j < columnLength; j++) //Dataの数だけ繰り返す { //2次配列fishdata[,]にタブごとに分けたtempを代入していく fishdata[i, j] = temp[j]; } } } 作成した関数を Start関数 内で起動させます。 GameManager.cs void Start() { Initialization(); } 実際に起動させてみましょう。 Inspector の表示形式を 「Debug」 にすると、詳細を確認することができます。 「GameManager」のInspectorで GameManager(Script) の [TextSouce],[RowLength],[ColumnLength] がそれぞれ取り込んだ値と同じか確認することができます。 Inspector の表示形式を 「Normal」 に戻しておきましょう。 問題1 作成した配列に、正しくデータが格納されているか、foreach()関数を使って表示させてみましょう。 答え1 foreach()文を使えば、指定した配列の中身をすべて取り出すことができます。 GameManager.cs void Initialization { /*省略*/ foreach (string s in fishdata) { Debug.Log(s); } } foreach() 文 の記述方法は以下の通りです。 foreach( 型名 オブジェクト名 in コレクション) { 処理文 } foreach文ではfor文のように、インデックス番号を指定する int型変数 i を定義したり、それをループごとにインクリメント(i++)する必要はありません。 また、コレクションの要素数を取得する必要もありません。ですので、簡潔に記述することができて便利です。 このプロジェクトでは、この後も多くの配列やリストを作っていきます。 リストから任意のデータを取り出す方法や、確認する方法をマスターしておきましょう。 1-3-3,魚のスプライト 魚のスプライトは、GameManagerクラスにスプライト用の配列を作成し、Unity側からセットします。 では 「GameManager.cs」 を立ち上げて、配列を追加します。 GameManager.cs public Sprite[] fishSprit; //魚のイラストの配列 「GameManager」 の Inspector に宣言した FishSprite[]が表示されるので、index 数に 108 を入力 後は「fish.txt」と同じ順番で、要素に魚のスプライトをセットしていけばいいだけです。 魚のスプライト名は、fish.text の魚の名前と同じになっていることを確認しながら進めましょう。 順番を間違えたり、スプライト名が違ったりすると、この後作る機能の一部が正しく動かない状態になります。 完成イメージは下のような状態です。 1-4,背景画像作成 ここからステージ上のオブジェクトを作成、配置していきます。 まずは背景画像を作成します。 背景は画面下部に「海」の素材を、上部に「空」の素材をセットします。 1-4-1,素材の準備 「海」の素材 「海」の素材は「フリー素材」を使っています。 ベースとなる画像を1つ、ベースの前面を左右に揺らし画像が動いているように見せる画像を1つ用意します。 「04_Sprits」フォルダの中に「BackGround」 フォルダを作成し、そこに入れておきます。 「空」の素材 「空」の画像は AssetStore から取得します。 「AllSky」 の無料版を選択し、取り込んでおきます。 1-4-2,「海」の背景をセット まずは、ゲーム画面の表示サイズを設定します。 [1-2]で選択したWebGL上での見え方に統一しておきましょう。 「Game」タブ を選択し、画面サイズ変更メニューから一番下にある 「+ボタン」 を押します。 展開された 「Add」メニュー で以下のように指定。 [Type] => Fixed Resolution [Width & Height] => 960 × 600 最後に 「OK」ボタン を押して確定。 続いてHierarchy上で、オブジェクトを作成。 UI => Image を選択。 生成された「Image」を Inspector から設定します。 ❶名前を 「SeaImage」 にリネーム ❷RectTransformコンポーネントで位置、サイズを下のように指定。 ❸Imageコンポーネントで「Source Image」に取り込み済みの 「SeaImg1」 を指定。 この段階では以下のような表示となっているはずです。 1-4-3,「空」の背景をセット 空の背景には、AssetStoreから取得した「AllSkyFree」の「Epic_BlueSunset」フォルダの中の「Epic_BlueSunset_Cam_0_Front+Z」という素材を使用したいと思います。 ただこのままでは使用できないので、選択した画像の Inspector から画像タイプの修正を行います Texture Type => Sprit(2D and UI) 最後は 「Apply」ボタン で確定。 先程の「海」の画像の追加と同様に、Canvas上に新たな Image のオブジェクトを追加します。 海の画像よりも奥のレイヤーにしたいので、「Canvas」の子要素の一番上に配置します。 生成された「Image」を Inspector から設定します。 ❶名前を 「SkyImage」 にリネーム ❷RectTransformコンポーネントで位置、サイズを下のように指定。 ❸Imageコンポーネントで「Source Image」に取り込み済みの 「Epic_BlueSunset_Cam_0」 を指定。 以下のようなイメージとなっています。 1-4-4,「波」の背景をセット 波はプログラムから動かしますが、その為には「worldSpace」に指定する必要があります。 Scene上に配置されるオブジェクトと同じ「worldSpaceに位置する」という意味になります。 しかしもともとのCanvasはとても大きいため、ベースの大きさを縮小します。 「Canvas」の Inspector から以下のパラメータを修正します。 ❶RectTransformコンポーネント ・PosZ の値を 10 に指定    ※今後の課題で作る釣り糸を表示するために必要になります ・Scale の X Y をそれぞれ 0.04 に指定 ❷Canvasコンポーネント ・RenderMode を World Space ・EventCamera を Main Camera Hierarchy上に新たな「image」オブジェクトを作成し、Canvasの子要素の一番下 に配置します。 Inspectorから以下のように設定します。 ❶名前を「WaveImage」に指定 ❷RectTransformコンポーネント  Width => 1500 左右に揺らすので、画面幅より大きめに指定します  Height => 500  PosY => -91 ちょうど海面と同じ高さになるように調整します ❸Imageコンポーネント  Source Image => 「Wave」 取得した画像を使います  Color => A(Alpha値:不透明度)を 0.5 後ろの海の画像が透けて見えるようにセット さらに、RigidBody2Dコンポーネントを追加します。 スクリプトファイルでのみ動かすので、Body Type を 「Kinematic」 にしておきます。 続いて波を動かすスクリプトファイルを作成します。 「02_Scripts」フォルダ内に、[ WaveManager ]スクリプトファイルを作成してください。 作成した 「WaveManager.cs」 は 「WaveImage」 にアタッチしておきます。 問題2 RigidBody2D を使って、「WaveImage」 を波のように左右に揺らし続けるプログラムを作ってみましょう。 答え2 この課題はtransform の Position を使ってみできるのですが、y座標の変更があった際など、都度プログラムの修正が必要になります。またRigidBody2Dの方が滑らかに動くようなので、今回はRigidBody2Dを使って動かします。 解答例: WaveManager.cs Rigidbody2D rb2d; void Start() { rb2d = GetComponent<Rigidbody2D>(); } void Update() { rb2d.velocity = new Vector2(Mathf.Sin(Time.time / 2), 0); //Time.time で周期をとっていますが、早すぎるので2で割って調整しています。 } これで背景の調整は完了しました。 ではここで、WebGlで正しく表示されるか確認しておきます。 上部メニューの「File」から 「Build And Run」 を選択。 初回のみファイルを保存する場所を聞いてくるので、任意のフォルダを指定します。 初回は特に時間がかかるので、余裕を見て実行します。 成功すると以下のようにブラウザ上でゲームのSceneを確認することができます。 最後までご覧いただき、ありがとうございます。 引き続きカリキュラムを参照したい場合は、「ファイブボックス」までお気軽にお問い合わせください。 https://www.fivebox.info/ Mail:ueda@fivebox.info Tel:0268-71-7294

Viewing all articles
Browse latest Browse all 9703

Trending Articles