へっぽこ技術ブログです

【AdventCalendar】マスコットアプリ文化祭の参加賞をもらうためにプロ生ちゃんをUnity2Dで動かそう

この記事は 

プロ生ちゃん Advent Calendar 2015

の12月4日分となります。たぶん。

昨日の記事は aratech さんの プロデルで簡単に画像を編集! - Qiita でした。

 

本日私が書かせていただくのは「マスコットアプリ文化祭に応募する作品のもとになる何かを作ってみよう」という まあ単なるチュートリアルっぽい何かな記事です。対象者は『プログラミング初学者』となります。(ちなみに僕も初学者です ^^;)

mascot-apps-contest.azurewebsites.net

 マスコットアプリ文化祭は「指定されたキャラクターを使ったアプリやアプリ以外の作品」であれば何でも応募できるコンテスト(?)です。この記事を読んで「こんな感じ(この程度)なら自分でもできそう」と思って応募してくれる人が増えたらいいなあと考えております。

 

それでは制作手順(チュートリアル)っぽい何か、です。

 

制作手順 1. 作りたいゲームを(適当に)考える

どんなゲームを作りましょうかと考えます。僕の場合は、3Dが大の苦手なので問答無用で2Dのゲームとしました。RPG・ADV・シミュレーションなどはシナリオを考えるのが大変ですので、ジャンルはアクションゲームっぽい感じで。自キャラを動き回らせて敵や物にぶつかった時に何かが起きる、といった感じの緩い「ゲームっぽい何か」ならなんとかなりそうと思いました。う〜ん、たぶん...

どんなものが出来上がるのかはご期待して(?)お待ち下さい。若しくは先読みしていただいても結構です ^^;

 

制作手順 2. キャラクターを用意する

まず、マスコットアプリ文化祭に参加するには指定されたキャラクターの使用が必要です。いろいろなキャラクターが用意されてるようですが、使用できる画像が単なる1枚絵であったり3Dモデルだけであったりで、僕が作りたい2Dゲームに使うキャラクターとしてはどうも使いづらいものばかりな気がしました。

そんな中で「HSPのイメージキャラクター 珠音(たまね)ちゃん」 には2Dゲームで使いやすいドット絵が用意されていました。

www.onionsoft.net

※こちらのページの HSP3オフィシャル2D素材 “珠音(たまね)” からダウンロードできる画像データの「tamadot.png」がオススメです。 

 

また、我らが「プロ生ちゃん」にも2Dキャラが用意されています。

pronama.azurewebsites.net

※こちらのページの「dot_illust.zip」がアクションゲームに使いやすい2D画像集です。

 

今回はプロ生ちゃんAdvent Calendarですので、この「dot_illust.zip」の中にある「98.png」という画像ファイルを使ってみます。ダウンロードしておいて下さい。

 

制作手順 3. 開発環境を用意する

今回はUnityで作ります。Unityには公式ページに素晴らしい「Unity2Dチュートリアル」が載っているのですがビミョーに難しいんですよね。はい、私は途中で挫折してしまいました。モノ作りって途中でやめちゃうとモヤモヤ感が残るんですよね〜。ここでUnity2Dでの完成品を作ることで、その時のモヤモヤを解消したいと思います(個人的理由^^;)。

unity3d.com

 制作手順 4. ガーッとバーっとなんか作る 

では「ゲームっぽい何か」を作ってみます。ざっくりとした解説になりますがごめんなさい。Unityを起動して 2Dの新規プロジェクトを作成し、以下の手順で作ってみました。(使用したUnityのバージョンは 5.2.2f1 Personal です)

1. 98.pngファイルには 縦横 32dotの画像が 3×4の12個の画像が用意されています。まずはこの画像を 3×4に分解し、 Unityでスプライトとして使えるようにします。

(1) 98.pngファイル を Assets に追加

f:id:Hiesuke:20151118112614p:plain

 

(2) Assets内の 98 を選択し、 Inspector の Sprite Mode を Multiple に変更

f:id:Hiesuke:20151118115107p:plain

 

(3)  Inspector の 「Sprite Editor」ボタンをクリックして スプライトエディタを開く

f:id:Hiesuke:20151118115230p:plain

Sprite Editorウインドウを大きく引き伸ばすと画像も大きく表示されて楽しい^^

 

(4) Sprite Editorの Slice をクリックして Type を Grid By Cell Sizeにする。Pixel SizeのXの欄に 32、Yの欄に 32 を入力して「Slice」ボタンをクリック

f:id:Hiesuke:20151118130822p:plain

※ 32 dot × 32 dot サイズの12個の画像に分割できました

 

(5) Sprite Editorの Apply をクリックしてからウインドウを閉じる

f:id:Hiesuke:20151118131300p:plain

 

(6) Assets の 98 についたぽっちをクリックして分割された画像を表示させる

f:id:Hiesuke:20151118132014p:plain

f:id:Hiesuke:20151118132107p:plain

分割できました! 

 

2. せっかくアニメーション用の画像が用意されていますので、プロ生ちゃんが歩くように加工してみたいと思います。

(1)  Assetsの 98_1 を Hierarchy にドラッグ&ドロップ

f:id:Hiesuke:20151118132716p:plain

(2) Hierarchyの98_1を選択

f:id:Hiesuke:20151118132913p:plain

(3) UnityのWindowメニューから「Animation」を選ぶ

f:id:Hiesuke:20151117160153p:plain

※Animationウインドウが表示される

(4) Animationウインドウの「Create」をクリック

f:id:Hiesuke:20151118133116p:plain

(5) 今から作るアニメーションに「PronamaD」という名前を付けて保存(Save)

f:id:Hiesuke:20151118133414p:plain

(6) Animationウインドウの「Add Property」をクリックし、「Sprite Renderer」の「Sprite」にあるプラス記号をクリック

f:id:Hiesuke:20151118133726p:plain

f:id:Hiesuke:20151118133908p:plain

※スプライト画像が表示されます。ちっちゃくて可愛い!

(7) 右側の枠にある0.30の表示の左側あたりをクリックし、赤いラインを移動させる

f:id:Hiesuke:20151118134349p:plain

(8) Inspector の Sprite Rendrer にある Sprite の項目一番右の丸ぽっちをクリックして「98_2」の画像を選択する。

f:id:Hiesuke:20151118134851p:plain

※ Sprite項目の表示が 98_2 になればOK!

 

(9)再生ボタンをクリックしてアニメーションを確認する。

f:id:Hiesuke:20151118141958p:plain

 

3. 続いて、ゲームっぽくなるように諸々の設定をしておきたいと思います。

(1)  Hierarchyに先ほど作った 98_1というアニメーションの名前をPronamaD に変更

f:id:Hiesuke:20151119092131p:plain

(2) PronamaDと同じ手順で、左・上・右向きのアニメーションを作成する

  左向き … PronamaL … 98_4 と 98_5 の画像から作る

  上向き … PronamaU … 98_10 と 98_11 の画像から作る

  右向き … PronamaR … 98_7 と 98_8 の画像から作る

f:id:Hiesuke:20151119093727p:plain

(3) Hierarchyの Create をクリックして「Create Empty」を選ぶ

f:id:Hiesuke:20151119094352p:plain

 

Hierarchyに GameObjectが作成されます

f:id:Hiesuke:20151119094527p:plain

 

(4) Hierarchy の GameObject の名称を PronamaChan に変更

f:id:Hiesuke:20151119094846p:plain

(5) Hierarchy の PronamaD, PronamaL, PronamaU, PronamaR を全て PronamaChan に ドラッグアンドドロップ

f:id:Hiesuke:20151119095205p:plain

 

※ PronamaChan の下に PronamaD〜Rが配置されます。(子要素となる)

f:id:Hiesuke:20151119103853p:plain

 

(6)  HierarchyにMain Cameraを選択して InspectorのCameraにあるSizeの値を 2に変更

f:id:Hiesuke:20151119104136p:plain

※ カメラの写す範囲が狭まることで相対的にキャラクタの表示が大きくなる

 

4. それでは、上下左右に動くようにスクリプトを組んでみましょう。

(1) Project の Create をクリックして「C# Script」選ぶ

f:id:Hiesuke:20151119104714p:plain

 

(2) 作成されたスクリプトファイルの名前を PronamaChan に変更

f:id:Hiesuke:20151119105031p:plain

 

 (3) スクリプトファイル(PronamaChan.cs)をダブルクリックして編集画面に移動

 (デフォルトではMonoDevelopが起動しますね)f:id:Hiesuke:20151119105427p:plain

(4) 以下のようにプログラムを変更して保存する

using UnityEngine;
using System.Collections;

public class PronamaChan : MonoBehaviour {
	// 進行方向(X方向、Y方向)
	private int dx;  // 1なら右移動、-1なら左移動、0なら左右の移動なし
	private int dy;  // 1なら上移動、-1なら下移動、0なら上下の移動なし
	
	
	// 最初に1度だけ実行される処理
	void Start () {
		ChangeDirection (1, 0);      // 右移動
		ChangeVisible ("PronamaR");  // 右移動アニメを表示
	}
	
	// フレーム処理ごとに実行される処理
	void Update () {
		if (Input.GetKey (KeyCode.RightArrow)) {     // 右矢印キー押された
			ChangeDirection(1, 0);      // 右移動に変更
			ChangeVisible("PronamaR");  // 右移動アニメを表示
		}
		else if (Input.GetKey (KeyCode.DownArrow)) { // 下矢印キー押された
			ChangeDirection(0, -1);     // 下移動に変更
			ChangeVisible("PronamaD");  // 下移動アニメを表示
		}
		else if (Input.GetKey (KeyCode.LeftArrow)) { // 左矢印キー押された
			ChangeDirection(-1, 0);     // 左移動に変更
			ChangeVisible("PronamaL");  // 左移動アニメを表示
		}
		else if (Input.GetKey (KeyCode.UpArrow)) {   // 上矢印キー押された
			ChangeDirection(0, 1);      // 上移動に変更
			ChangeVisible("PronamaU");  // 上移動アニメを表示
		}

		// このオブジェクトの表示位置をカッコ内の式で示した分だけ変更する(移動する)
		transform.Translate(dx * Time.deltaTime, dy * Time.deltaTime, 0);
	}

	// 他のオブジェクトと衝突した時に呼び出される関数
	void OnCollisionEnter2D(Collision2D coll){
		ChangeDirection (0, 0);  // 移動停止
	}

	// このオブジェクトの進行方向(X方向・y方向)を変更する関数
	void ChangeDirection(int x, int y) {
		dx = x;
		dy = y;
	}

	// 指定された子要素だけを表示する関数
	void ChangeVisible(string name) {
		transform.FindChild("PronamaR").gameObject.SetActive(false);
		transform.FindChild("PronamaD").gameObject.SetActive(false);
		transform.FindChild("PronamaL").gameObject.SetActive(false);
		transform.FindChild("PronamaU").gameObject.SetActive(false);
		transform.FindChild( name ).gameObject.SetActive(true);
	}
}

(5) AssetsのPronamaChanを Hierarchy のPronamaChanにドラッグ&ドロップする

 (スクリプトを PronamaChanオブジェクトに適用させる)

f:id:Hiesuke:20151120100437p:plain

※ プロ生ちゃんが歩き回ります。カーソルキーで移動方向変更です。足の運びが移動量と一致してるように見えないのは仕様です ^^; 

なんとなくゲーム(っぽい何か)ができそうになってきた! ……気がする 

 

5. 自キャラがとりあえずできたので障害物などの要素を作ります。

(1)  32×32サイズで黒・黄色・赤の3枚の画像を用意します。お好きなペイントソフトで作成してください。(下の画像をダウンロードしてもOK)

  f:id:Hiesuke:20151120094448p:plain  Black.png

  f:id:Hiesuke:20151120094532p:plain  Yellow.png

  f:id:Hiesuke:20151120094548p:plain  Red.png

 

(2) 3つの画像を Assets にドラッグ&ドロップします。

f:id:Hiesuke:20151120095210p:plain

 

(3) AssetsのBlackを Hierarchyにドラッグ&ドロップする

f:id:Hiesuke:20151120101803p:plain

 

(4) HierarchyのBlackを Wallという名前に変更する

f:id:Hiesuke:20151120102658p:plain

 

(5) Hierarchyの Wallを Assetsにドラッグ&ドロップする

f:id:Hiesuke:20151120103058p:plain

 ※ Assetsの中に以下のような Wallが作成されます。これは「プレファブ(Prefab)」と呼ばれるもので、同じものをたくさん使いたい時にそれらのテンプレート(雛形)として機能します。障害物などは同じものをたくさん画面に配置することになるのでプレファブ化をしておくと後が楽チンになるのです。

f:id:Hiesuke:20151120104022p:plain

 

(6) HierarchyのWallを削除(delete)する

f:id:Hiesuke:20151120104408p:plain

 

(7) 同じ手順で YellowをCoinという名称で、RedをBoxという名称でプレファブ化する

f:id:Hiesuke:20151120105340p:plain

 

6. 障害物を画面(シーン)に配置してみます。

(1) Assetsの Wall(プレファブ)を Scene上にドラッグ&ドロップする

f:id:Hiesuke:20151120110413p:plain

 

(2) Scene上のWallをプロ生ちゃんの右側に引き伸ばして配置する

※これを選んだ状態にして

 f:id:Hiesuke:20151120112107p:plain

※こんな感じに伸ばしてください

f:id:Hiesuke:20151120112151p:plain

 

 (3) 同様に Scene上に更に3つ Wallを配置してプロ生ちゃんを囲む

f:id:Hiesuke:20151121155647p:plain

 

(4) 下図の様にCoinを3つ、Boxを1つ Scene上に置く(サイズ変更しない。重ねない)

f:id:Hiesuke:20151121160230p:plain

 ※ まだ障害物に衝突しても何も起きません

 

7. 障害物にぶつかった時の処理を設定しましょう

(1) Hierarchyの PronamaChanをクリックして選択する

f:id:Hiesuke:20151121162011p:plain

 

(2) Inspectorの Add Component ボタンをクリックし、Physics 2Dを選ぶ

f:id:Hiesuke:20151121162038p:plain

 

(3) 更にRigidbody 2Dを選ぶ

f:id:Hiesuke:20151121162106p:plain

※ この状態で実行するとプロ生ちゃんが落下します *^_^*

 

(4)  Inspectorに追加された Rigidbody 2Dにある Gravity Scaleの値を 0 にする

f:id:Hiesuke:20151124131356p:plain

※ 重力がゼロになるのでプロ生ちゃんが落下しなくなります

 

(5) 更に Add Component → Physics 2D と選び、Box Collider 2Dを選ぶ

 f:id:Hiesuke:20151121163853p:plain

※ PronamaChanのInspectorに Box Collider 2Dが追加されます

 

(6) 緑色の線がプロ生ちゃんの衝突範囲となります。広すぎるので狭めましょう

f:id:Hiesuke:20151124132637p:plain

InspectorのBox Collidor 2Dにある Edit Colliderアイコンをクリックする

f:id:Hiesuke:20151124132753p:plain

緑色の線をつまんで、プロ生ちゃんの周囲に狭める

f:id:Hiesuke:20151124133002p:plain

 

(7) Assetsの Wallを選択し、InspectorからAdd Component → Physics 2D →Box Collider 2Dと選ぶ

f:id:Hiesuke:20151120104022p:plain f:id:Hiesuke:20151121163853p:plain

 ※ これで プロ生ちゃんと全ての黒い壁(Wall)の双方に衝突検知ができるようになりました。動作確認して、プロ生ちゃんが黒い壁を超えられなくなっていればOK

※ これはスクリプトファイル(PronamaChan.cs)に『衝突を検知した時に移動を無くす』という命令文がすでに記述されているからです。確認してみてください

 

(8) Assetsの Coinを選択し、上と同様の手順で Rigidbody 2Dと Box Collider 2Dを加える。Gravity Scaleの値はゼロにする

f:id:Hiesuke:20151124134607p:plain

※動作確認してみてください。黒い壁(Wall)と違って黄色いコイン(Coin)は押せます

 

(9) 黄色いコインを押しているうちにプロ生ちゃんが回転しての向きが斜めになっていくことがあります。これを解消しましょう (方向を上下左右に限定する)

f:id:Hiesuke:20151124134914p:plain

Hierarchyの PronamaChanを選択し、InspectorのRigidbody 2Dにある Constraintsの三角形をクリックして開く

f:id:Hiesuke:20151124135616p:plain

Freeze Rotationのチェックボックスにチェックを入れる

f:id:Hiesuke:20151124135712p:plain

 ※ プロ生ちゃんが回転(ローテーション)しなくなります。確認してみましょう

 

8. 最後にちょっとだけゲームっぽくしてみましょう。今までの手順を思い出して作業してみてください。

黄色のコイン(Coin)を赤い箱(Box)の所まで運んで、衝突したらコインが消えるようにする

  (1) AssetsのBoxを選択し、Box Collider 2Dを追加

f:id:Hiesuke:20151121163853p:plain

※ これでBoxにも衝突検知できるようになりました

 

(2) C# Script(ファイル名はCoinとする)を新規作成し、以下の関数を追記する

	// 他のオブジェクトと衝突した時に呼び出される関数
	void OnCollisionEnter2D(Collision2D coll){
		if (coll.gameObject.name == "Box") { // ぶつかった相手がBoxなら
			Destroy (this.gameObject);  // 自分自身を消滅させる
		}
	}

 

(3) スクリプトCoin を プレファブCoinにドラッグ&ドロップする

f:id:Hiesuke:20151124155914p:plain

 

動作確認してみてください。なんとな〜くゲームになりそうなモトが出来上がっているのではないかと思います。

衝突の判定などのスクリプトの書き方をいろいろ調べて、改良を行っていただけたらと存じます。みんなで「参加賞を」もらいましょう!

 

 

おまけ 

絵柄を変える

(1)  画像ファイルをAssetsにドラッグ&ドロップする

(2) 追加した画像をプレファブ(Coin, Box, Wallなど)のSprite RendererにあるSpriteという項目にドラッグ&ドロップする

f:id:Hiesuke:20151124160513p:plain

 

※以下のような感じになりました。(画像は珠音ちゃん素材からの流用です)

f:id:Hiesuke:20151124154835p:plain

 プロジェクトは一応 こちら に置いておきます。ご自由にお使いください。

 

長々とお付き合いありがとうございました。
明日は masami256 - Qiita さんの記事です。

それではみなさん、 Happy Programming !!