Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
Unity公式チュートリアル 玉転がしゲーム (Roll-a-Ball)を つくってみよう
レベル:初級 所要時間:1時間25分 対応バージョン:Unity 2018.4.22f1(LTS)+日本語パック 簡単な玉転がしゲームを作ってみましょう。Unityでゲームづくりをする上での基本的な操作や、ゲームオブジェクト、コンポーネント、プレハブ、物理演算、スクリプトなどの機能を学ぶことができます。 ※Unityのインストール方法は「Unityインターハイブログ」の記事「Unity Hubを使ってUnityをインストールしよう」と「Unityエディターを日本語化しよう」をご確認ください。
マニュアル改訂:2020年5月 1
このチュートリアルでつくるゲーム キーボードのテンキー(↑←→↓)を操作して玉を転がし、アイテムを集めるシンプルな3Dゲームです。
全てのアイテムを集めるとクリア、障害物に当たるとはじめからやり直しとなります。
2
プロジェクトを作成する まずは新規のプロジェクトを作成しましょう。
1. Unity Hubからプロジェクト→新規作成を選択し、Unityエディターを起動します。(複数のバージョンがある場合は、新規作成の右側の▼ボタンをクリックしてバージョン2018.4.22f1を選択しましょう)
2. テンプレートは3Dを選択し、プロジェクト名に作成するゲーム名を入力します。今回は"Roll-a-Ball"とします。
3. 作成をクリックしてUnityエディターを起動します。
3
シーンを保存する Unityエディターが開いたら、まずシーンを保存しましょう。
1. ファイル(File)→別名で保存(New Scene)を選択 2. 保存先はScenesを選択し、SampleSceneが入っている画面でファイル名をstage01と入力し、保存をクリック
プロジェクトとシーン
Unity では、ゲーム全体の構成を「プロジェクト」、ゲームの各部を構成する独立した各場面や各ステージを「シーン」と呼びます。手の込んだゲームはタイトル画面やゲーム画面などたくさんのシーンを含み、ときには複数のシーンを 1度に組み合わせることもあります。
4
エディターのレイアウトを統一する ゲームづくりをスタートする前に、このチュートリアルでUI(ユーザーインターフェース)の位置を分かりやすく説明するためにエディタのUI表示を統一します。
● エディター画面右上のLayoutを選択し、2x3(2 by 3)を選択 ● ゲーム(Game)タブのFree Aspectを選択し、4:3を選択 ● プロジェクトブラウザの下にあるバーを一番左へずらす
5
インターフェースの使い方 Unityはこの画面でスクリプト制作以外のほとんどの操作を行います。
各ビューの境目にマウスポインタを合わせると幅や高さを調整できます。最初はシーンビューを使うことが多いので、広めに調整しておくといいでしょう。
6
各タブの名称と機能は以下のとおりです。
1. シーン(Scene)ビュー
シーンビューには制作中のゲーム世界(シーン)が表示され、自由な位置・角度から眺めることができます。
2. ゲーム(Game)ビュー
ゲームビューはゲーム画面です。 ゲームのプレイヤーは基本的にこの画面を見ながらゲームをプレイします。現在は「Main Camera」に映っているものが表示されています。
3. ヒエラルキー(Hierarchy)ビュー
シーン内に存在するオブジェクトの一覧が表示されます。 編集中のシーン内でオブジェクトをコピー/ペーストしたり、名前をつけて整理することもできます。
4. プロジェクト(Project)ブラウザ
制作中のプロジェクト(ゲーム全体)に含まれるシーン、スクリプト、グラフィックやサウンドなどのデータ、その他のファイルが表示されます。
5. インスペクター(Inspector)ビュー
シーンの中で選択中のオブジェクトが持つ属性を表示・編集するためのビューです。 属性には座標やメッシュといった外見上のものから、衝突判定や物理制御に関するパラメーターなどもあります。
7
シーンビューの移動方法
シーンビューは最初は青とグレーしか表示されていません。まずは3Dキューブを作成してみましょう。
1. ヒエラルキービューの作成(Create)を選択 2. 3Dオブジェクト(3D Object)→キューブ(Cube)を選択
続いて以下の操作を試してみましょう。
操作 動作
右クリックを押しながらドラッグ 視点を回転させる
マウスホイール Sceneビューの拡大・縮小
ホイールボタンを押しながらドラッグ Sceneビューの並行移動
オブジェクトを選択してFキー オブジェクトにフォーカスを当てる
ヒエラルキービューにあるオブジェクト名をダブルクリック
オブジェクトにフォーカスを当てる
オブジェクトを選択してDeleteキー オブジェクトを消す
8
地面の作成 まずは地面を作成します。これで、シーン内に地面の役割を持ったゲームオブジェクト(GameObject)が作成されます。
1. ヒエラルキービューの作成を選択 2. 3Dオブジェクト→平面(Plane)を選択
9
GameObject(ゲームオブジェクト)とは?
Unityでは、シーン内に配置される全ての要素を「ゲームオブジェクト」と呼びます。 ゲームオブジェクトには物理オブジェクト、ライト(照明)、目に見える3Dメッシュ、 あるいは目に見えないサウンド、トリガーなど様々な形があります。いずれもUnityによって挙動が管理され、 任意にスクリプトを割り当てて制御できるという共通点があります。
地面を並べる 地面の大きさを調整します。大きさを調整するには地面を並べるか、地面を引き伸ばす方法があります。特に理由はないですが、今回は地面を並べることとします。 1. ヒエラルキービューでPlaneを選択した状態で右クリックし、複製(
Duplicate)をクリックします。 2. シーンビューには2つのPlaneが重なった状態になり、2つ目のPlane(Plane(1))が選択されている状態になります。
3. 画面左上のパネルで移動ツールが選択されていることを確認し、シーンビューに表示されている赤・青・緑の矢印をドラッグして適当に位置を動かしましょう。
10
4. 2の作業を繰り返し、4枚の地面(Plane)を作成します。 5. 各オブジェクトの名称を変更しましょう。ヒエラルキービューのオブジェクトを右クリックして名前を変更するか、インスペクタービューから名前の変更を行います。
● Plane → Ground1 ● Plane(1) → Ground2 ● Plane(2) → Ground3 ● Plane(3) → Ground4
11
4つの地面の座標を設定 座標の管理はインスペクタービューのトランスフォーム(Transform)コンポーネントが行っています。位置(Position)、回転(Rotation)、拡大/縮小(Scale)で管理します。各Groundの位置を以下のように設定してみましょう。
● Ground1 → x:5 y:0 z:-5 ● Ground2 → x:5 y:0 z:5 ● Ground3 → x:-5 y:0 z:-5 ● Ground4 → x:-5 y:0 z:5
数値の入力(位置がおかしいときは)
数値にマイナス(-)を付け忘れていないか確認しましょう。
12
シーンを保存する ここまでのデータを保存しておきましょう。
1. 画面上部のメニューからファイルを選択 2. 保存(Save Scene)を選択
シーンはこまめに保存
UnityやPCがシャットダウンしてしまうと作業したデータが消えてしまいます。シーンはこまめに保存しましょう。
Ctrl(Command)+Sキーを押すと、簡単に保存ができます。変更を加えたらCtrl(Command)+Sキーで保存するクセをつけておくとよいでしょう。
13
地面に色を塗る Unityでモデルに色を塗る方法は2つあります。モデルの表面にテクスチャを設定するか、モデル全体の色や質感を設定することです。 今回はモデル全体の色をマテリアル(Material)ファイルを使って設定します。
マテリアル(Material)ファイルを作成する 1. プロジェクトブラウザの作成(Create)を選択 2. マテリアル(Material)を選択 3. 作成されたNew Materialの名前をGroundMaterialに変更
14
マテリアルに模様と色を設定 1. 先ほど作成したGroundMaterialを選択 2. アルベド(Albedo)の左の二重丸(◎)を選択し、Default Checkerを選択
3. アルベドの右側の枠をクリックして色を設定(好きな色を設定しましょう)
地面にマテリアル(Material)を設定 作成したマテリアルを使って地面に色を塗ります。
GroundMaterialを選択し、ヒエラルキービューのGround1、Ground2、Ground3、Ground4へドラッグ&ドロップします。 またはシーンビューのGround1~4オブジェクトにドラッグ&ドロップします。
15
壁の作成 四方を壁で囲うステージを作成しましょう。壁はボールがGroundの外へ逃げることを防ぐ役割を持っています。
1. ヒエラルキービューの作成を選択 2. 3Dオブジェクト→キューブを選択 3. 作成したCubeの名前をWallに変更
16
壁の色を設定する 地面と同じように壁の色も設定しましょう。
1. プロジェクトブラウザの作成を選択 2. マテリアルを選択 3. 名前をWallMaterialに変更 4. WallMaterialを選択し、アルベドの色を設定(赤や黄色など、危険色に設定しましょう)
5. WallMaterialをドラッグ&ドロップしてWallオブジェクトの色を変更
17
壁の配置 壁のサイズを変更しましょう。今回はサイズを引き伸ばす方法を選択します。左上のパネルでスケールモードを選択してください。そしてオブジェクトを選択し、引き延ばしたい方向に伸びているブロックをドラッグします。
18
このようにマウス操作でもオブジェクトのスケールを拡大/縮小できますが、今回は人によって違いが出ないよう、インスペクタービューで数値を入力して調整します。Wallを選択した状態で、インスペクタービューの位置(Position)と拡大/縮小(Scale)に以下の数値を入力してください。
● 位置(Position) → x:-0.5 y:0.5 z:-9.5 ● 拡大/縮小(Scale)→ x:19 y:1 z:1
四方を囲むようにつくるので、同じものをあと3個つくります。ヒエラルキービューでWallを右クリックして複製を選択し、名前をWall 1
19
に変更します。そして同じようにインスペクタービューで位置と拡大/縮小の数値を入力します。
● 位置(Position) → x:0.5 y:0.5 z:9.5 ● 拡大/縮小(Scale) → x:19 y:1 z:1
Vキーを押しながらモデルを頂点スナップ移動
モデルを選択した状態で、Vキーを押しながらモデルの頂点をクリックすると頂点スナップ移動ができます。他モデルの頂点に吸い付くように移動できる便利なテクニックです。
20
オブジェクトの回転 あと2つ壁をつくります。残りの壁を制作するには2つの方法があります。Wallの複製を90度傾けるか、Wallの拡大/縮小(Scale)を【x:1, y:1, z:19】と異なる方向へ伸ばして作成するかです。今回はWallの複製を90度傾ける方法について紹介します。
1. ヒエラルキービュー上でWallを右クリックし複製して、名前をWall 2に変更
2. わかりやすいよう、オブジェクトの位置を少しずらす 3. 画面左上のパネルから回転ツールを選択 4. オブジェクトの周囲の球状の枠をドラッグして回転させる
45度ずつ回転 Ctrl(Command)キーを押しながらドラッグすると45度ずつ回転させることができます。
21
このようにマウス操作でもオブジェクトを回転させることができますが、今回はインスペクタービューで数値を入力して調整します。Wall 2を選択した状態で、インスペクタービューの位置(Position)と回転(Rotation)に以下の数値を入力してください。
● 位置(Position) → x:-9.5 y:0.5 z:0.5 ● 回転(Rotation) → x:0 y:90 z:0
22
残る壁は1つです。Wall 2を複製、名前を変更してWall 3を作成しましょう。そして位置を調整します。
● 位置(Position) → x:9.5 y:0.5 z:-0.5
これでステージの地面と壁は完成です!
23
オブジェクトの整理 プロジェクトブラウザやヒエラルキービューにオブジェクトが増えてくると全てを管理するのが面倒になります。フォルダーや空(から)のオブジェクトを使用して整理しましょう。
フォルダでマテリアルの整理 マテリアルを1つのフォルダーに格納してまとめます。
1. プロジェクトブラウザの作成を選択 2. フォルダー(Folder)を選択 3. 作成したNew Folderの名前をMaterialに変更 4. GroundMaterialとWallMaterialをMaterialフォルダーへドラッグ&ドロップ
空のオブジェクトで地面と壁の整理 ヒエラルキービューのGroundとWallを空(から)のオブジェクトにまとめます。
1. ヒエラルキービューの作成を選択 2. 空のオブジェクトを作成(Create empty)を選択 3. 作成したGameObjectの名前をStageへ変更 4. WallとGroundを選択し、Stageオブジェクトへドラッグ&ドロップ
24
まとめて選択 Ctrl(Command)キーやShiftキーを押しながら選択すると複数のオブジェクトやファイルを同時に選択できます。
25
プレイヤー(玉)の作成 プレイヤーとなる玉を作成します。
1. ヒエラルキービューの作成を選択 2. 3Dオブジェクト → スフィア(Sphere)を選択 3. 名前をPlayerに変更 4. インスペクタービューで位置の数値を入力
● 位置 → x:0 y:1.5 z:0
コンポーネントの追加 Playerへコンポーネントを追加しましょう。Playerを選択した状態でインスペクタービューのコンポーネントを追加(Add Component)を
1. シーンビューまたはヒエラルキービューでPlayerを選択 2. インスペクタービューでコンポーネントを追加(Add Component)を選択
3. 物理(Physics)→ リジッドボディ(Rigidbody)を選択
26
ゲームを再生する ゲーム再生ボタンをクリックし、ゲームの挙動を確認してみましょう。
Playerに追加したリジッドボディ(物理演算)の機能が働き、オブジェクトは地面に落下します。
27
正しく動作を確認できたら再びゲーム再生ボタンをクリックし、ゲームの再生を終了します。
作業をするときはゲームの再生を終了すること ゲーム再生中に行った作業は、再生が終了するとリセットされます。作業をするときは必ずゲームの再生を終了してから行うようにしましょう。
28
プレイヤーを任意の方向へ転がす機能の追加 プレイヤー(玉)を転がすゲームにするには、キー入力を受けPlayerオブジェクトを転がす機能が必要です。 この機能はC#(シーシャープ)スクリプトを書いてつくります。
1. シーンビューまたはヒエラルキービューでPlayerを選択 2. インスペクタービューでコンポーネントを追加を選択 3. 新しいスクリプト(New Script)を選択 4. 名前(Name)にPlayerControllerと入力 5. 作成して追加(Create And Add)を選択
これでPlayerオブジェクトに「何も機能を持たないコンポーネント」が追加されました。
29
この作業で、プロジェクトブラウザのAssetsフォルダーにPlayerControllerが作成されます。これが今回作成した新しいスクリプトです。
まずはマテリアルと同じようにScriptフォルダを作成し、ドラッグ&ドロップで移動させましょう。
1. プロジェクトブラウザの作成 → フォルダーを選択 2. フォルダー名をScriptに変更 3. PlayerControllerを選択し、Scriptへドラッグ&ドロップ
スクリプトの編集 PlayerControllerをダブルクリックしましょう。通常はVisual Studioが起動し、スクリプトの編集画面が表示されます。
まずはサンプルコードとして提供されているコードを削除し、クラス定義のみにします。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
}
30
今回作成したいスクリプトは「ボタンを押したら転がる」機能です。 分解すると、以下の通りになりそうです。
1. 毎フレーム、キー入力を受け付ける 2. キー入力がされたらプレイヤーのリジッドボディ(Rigidbody)に力を加える
スクリプト(コード)の記述 このマニュアルではC#スクリプトについて説明もしていますが、最初は説明の意味がわからないと思います。まずは無理に意味を理解しようとせず、書かれているコードを全く同じように記述しましょう。
31
入力機能の追加 まずは「毎フレーム入力を受け付ける」部分をスクリプトで記述します。Unityのスクリプトは、特定のメソッドを定義すると自動的にメソッドを特定のタイミングで呼び出します。
例えば、クラス内に
void Update() { }
と記述すると、{}の内側に記述した処理を毎フレーム更新時に呼び出します。
void FixedUpdate() { }
と記述すると、{}の内側に記述した処理を物理演算でキャラクターが動く度に呼び出します。
今回は物理演算を使用するので、FixedUpdate内に処理を記述します。コードを以下のように変更します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
void FixedUpdate ()
{
}
}
32
次に入力をFixedUpdate内で取得します。 以下のコードを記述すると、xとzの中にキーボード入力(Horizontal=↑↓、Vertical=←→)が代入されます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
void FixedUpdate ()
{
// 入力をxとzに代入
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
}
}
スクリプトを編集したら保存しましょう。ファイル(File) → 保存(Save)を選択します。Ctrl(Command)+Sキーでも保存ができます。
33
// によるコメントアウト C#スクリプト内で // を記述すると、以降の内容は処理されなくなります。日本語でスクリプトの内容や動作を説明したり、メモ書きとして使用します。本マニュアルでは見やすくするために過去のコメントを省略しています。
34
物理演算機能の追加 取得したキー入力を元にrigidbodyコンポーネントに力を加えます。 同一オブジェクトのコンポーネントを取得するにはGetComponentを使用します。今回はリジッドボディ(Rigidbody)を取得するので、「GetComponent()」と記述します。 using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
void FixedUpdate ()
{
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
// 同一のGameObjectが持つRigidbodyコンポーネントを取得
Rigidbody rigidbody = GetComponent();
}
}
取得したrigidbodyに入力の力を加えます。力を加えるにはPublic関数のAddForceを使います。
35
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
void FixedUpdate ()
{
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Rigidbody rigidbody = GetComponent();
// rigidbodyのx軸(横)とz軸(奥)に力を加える
rigidbody.AddForce(x, 0, z);
}
}
これで機能はひと通り作成しました。それではゲームを再生してみましょう。
テンキー(↑↓←→)を入力すると玉(Player)が非常にゆっくり動きます。
36
もう少し早く動くようにしたいですね。ゲームの再生を終了し、rigidbody.AddForceに与える力を10倍くらいにしてみましょう。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
void FixedUpdate ()
{
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Rigidbody rigidbody = GetComponent();
// xとzに10をかけて押す力をアップ
rigidbody.AddForce(x * 10, 0, z * 10);
}
}
再びゲームを再生してみるとスムーズになったはずです。しかしゲームバランスに直結する項目なので、じっくり調整したいですね。毎回スクリプトを開いて調整するのは大変なので、この値をインスペクタービューからサクっと調整できるようにしましょう。
まずはPlayerControllerクラスにspeed変数を追加します。 その後、speed変数をxとzに掛けるよう変更します。
37
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
// speedを制御する
public float speed = 10;
void FixedUpdate ()
{
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Rigidbody rigidbody = GetComponent();
// xとzにspeedを掛ける
rigidbody.AddForce(x * speed, 0, z * speed);
}
}
Playerを選択してインスペクタービューのPlayer Controller (Script)を見ると速度(speed)欄が追加され、数値を調整できるようになりました。
初期値は10となっていますが、自由に数値を変えてゲームを再生してみましょう。
38
カメラを動かす Playerの動きに合わせてカメラを動かしましょう。最も簡単な方法は、Playerを親オブジェクト、MainCameraを子オブジェクトに設定することです。親子関係にあるオブジェクトは、どちらかが動けばもう片方も同じ動きをします。
1. ヒエラルキービューのMainCameraを選択 2. MainCameraをヒエラルキービューのPlayerへドラッグ&ドロップ
ゲームを再生せずPlayerオブジェクトを動かしてみましょう。カメラはプレイヤーを追随して移動しています。
39
ではゲームを再生してみてください。ゲームビューを見ると世界がグルングルン回っています。
Player自体が転がって移動しているため、親子関係にあるカメラも転がってしまうためです。 これを解決するにはPlayerが転がらないように移動するか、カメラがプレイヤーを追跡するコンポーネントを作るかです。今回はカメラがプレイヤーを追跡するコンポーネントを作ります。
40
その前にMain CameraをPlayerオブジェクトから外しておきましょう。
プレイヤーを追跡するコンポーネントの作成 カメラがプレイヤーを追跡するコンポーネント(新しいスクリプト)を作成します。 機能を分解してみましょう。
1. Playerの位置を取得する 2. 毎フレームPlayerの位置へ座標を調整する
まずはFollowPlayerコンポーネントを作成し、MainCameraへ追加します。
1. ヒエラルキービューでMainCameraを選択 2. インスペクタービューでコンポーネントの追加を選択 3. 新しいスクリプトを選択し、名前をFollowPlayerにして作成して追加を選択
4. プロジェクトブラウザでAssetsフォルダー内に作成されたFollowPlayerをScriptフォルダーへ移動
41
Scriptフォルダーに入れたFollowPlayerをダブルクリックし、Visual Studioを起動します。
42
プレイヤーを追跡する カメラがプレイヤーを追跡する方法はいくつか考えられるのですが、今回はシーン上にあるPlayerオブジェクトへの参照を事前に設定し、参照を元にオブジェクトの座標を取得する方法を選択します。
まずはコードの設定です。 先ほどと同じようにpublicで宣言しますが、今度はTransformの変数を定義します。 これはTransformのコンポーネントを持つオブジェクトを登録するためです。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FollowPlayer : MonoBehaviour
{
public Transform target; // ターゲットへの参照
void Update ()
{
// 自分の座標にtargetの座標を代入する
GetComponent().position =
target.position;
}
}
コードを記述したらUnityエディターへ戻り、MainCameraを選択してインスペクタービューのコンポーネント一覧を確認しましょう。 FollowCameraコンポーネントにTargetの項目が追加されていることがわかります。
この項目へ登録したいオブジェクト(Player)をドラッグ&ドロップします。
43
さて再生してみましょう。するとカメラの位置は変更されましたが、プレイヤー(玉)が映っていません。MainCameraとPlayerが同じ座標にいるため、主観視点になってしまっています。
Offsetを設定する これはこれで面白いのですが、遊びやすくするにはプレイヤー(玉)が見えるようにカメラの位置を設定したいですね。
そこでゲーム再生時にあるカメラとプレイヤー距離を維持する機能(スクリプト)を追加します。 ゲームを再生した時にPlayerとMainCameraの相対距離を求めて保持しておき、毎フレーム、カメラの位置をPlayerの位置との相対距離で設定する事で実現します。
44
先ほどターゲットとして設定したPlayerの位置(Position)が x:0, y:1.5, z:0 にあることを確認しましょう。そしてMainCameraの位置を以下のとおりにします。
● 位置(Position) → x:0 y:9 z:-5 ● 回転(Rotation) → x:60 y:0 z:0
次にFollowPlayerコンポーネント(スクリプト)のコードを変更します。
45
Startはコンポーネントの起動時に1度だけ呼び出されるメソッドです。ここでoffsetへ相対距離を取得しておきます。相対距離を使用して、常に一定の距離を離してPlayerを追跡するようにします。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FollowPlayer : MonoBehaviour
{
public Transform target; // ターゲットへの参照
private Vector3 offset; // 相対座標
void Start ()
{
//自分自身とtargetとの相対距離を求める
offset = GetComponent().position -
target.position;
}
void Update ()
{
// 自分自身の座標に、targetの座標に相対座標を足した値を
設定する
GetComponent().position =
target.position + offset;
}
}
46
ゲームを再生してみてください。プレイヤーはステージ内を自由に走り回り、カメラもちょうどいい位置で追跡していますね!
ここまでで全体の約60%です。残りはあと40%なので一度休憩を入れましょう。おっと、次の作業に移る前にゲーム再生を終了することを忘れずに。
47
Itemオブジェクトの追加 さあ、次はプレイヤーが集めるItemオブジェクトを作ります。まずItemの元となる3Dモデルを作成します。
1. ヒエラルキービューの作成を選択 2. 3Dオブジェクト → カプセル(Capsule)を選択 3. 名前をItemに変更
作成したカプセル(Item)は少し大きすぎるので、大きさと位置を調整します。
● 位置(Position) → x:0 y:1 z:0 ● 拡大/縮小(Scale) → x:0.5 y:0.5 z:0.5
48
Itemオブジェクトの構成をPrefabへ書き出す この作成したItemはこのあと複数つくることになります。1個ずつ色や大きさを調整するのは大変ですね。そのためにオブジェクト構成情報をprefab(プレハブ)として書き出します。
まずは今回も専用のPrefabフォルダーを作成してそこに整理しましょう。
1. プロジェクトブラウザでAssetsを選択し作成 → フォルダーを選択 2. 名前をPrefabに変更
続いてItemオブジェクトをPrefabとして書き出します。
1. ヒエラルキービューのItemを選択 2. ItemをプロジェクトブラウザのPrefabフォルダーへドラッグ&ドロップ
49
青いアイコンのPrefabオブジェクトができます。
50
Itemオブジェクトの配置 PrefabのItemをシーンへ配置します。
1. プロジェクトブラウザのPrefabフォルダーのItemを選択 2. シーンビューへドラッグ&ドロップ
6個のPrefabを円形に配置してみましょう。ヒエラルキービューにもItem (1)~Item (6)が追加されていることがわかります。
最初にセットアップしたItemは、オブジェクトを選択してDeleteキーで消しておきましょう。
アイテムの色を設定する Item(1)の色を設定しましょう。
1. プロジェクトブラウザの作成を選択 2. マテリアルを選択 3. 名前をItemMaterialに変更 4. ItemMaterialを選択し、アルベドの色を設定(好きな色を設定しましょう)
5. ItemMaterialをドラッグ&ドロップしてItem(1)オブジェクトの色を変更
51
Prefabの更新 Item(1)を使ってマテリアルを設定しました。この調整を他のItem(2)~Item(6)にも適用します。
1. ヒエラルキービューでItem(1)を選択 2. インスペクタービューでオーバーライド(Overrides)を選択し、すべてを適用する(Apply All)を選択
同じPrefabであるItem(2)~Item(6)にもマテリアルが適用されました!
52
PlayerとItemの接触判定 Itemに、Playerが接触したときの判定をコンポーネントに追加します。
1. ヒエラルキービューでItem(1)を選択 2. インスペクタービューでコンポーネントの追加→ 新しいスクリプトを選択
3. 名前をItemScriptに設定し作成して追加を選択 4. プロジェクトブラウザのAssetsフォルダー内に作成されたItemScriptをScriptフォルダーにドラッグ&ドロップ
5. ItemScriptをダブルクリックして開く 接触判定の関数は2種類あります。 ● OnTriggerEnter :物理的な反射を持たないTriggerとの接触判定 ● OnCollisionEnter :物理的な反射を持つColliderとの接触判定
プレイヤーとアイテムが接触したときにスルッと抜けて欲しいのでOnTriggerEnterを使って実装します。 using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemScript : MonoBehaviour
{
// トリガーとの接触時に呼ばれるコールバック
void OnTriggerEnter (Collider hit)
{
}
}
53
Itemの接触判定をTriggerに変更 判定方式をTriggerにしたため、接触判定もTriggerに設定する必要があります。 Item (1)のColliderをTriggerに設定します。
1. ヒエラルキービューのItem (1)を選択 2. インスペクタービューのカプセルコライダー(CapsuleCollider)コンポーネントのトリガーにする(Is Trigger)にチェックを入れる
54
Playerとの接触判定 先ほどの処理で、Item(1)があらゆるTriggerとの接触判定を行うことができるようになりました。しかし今回、Item(1)と接触判定を持つのはPlayerのみとしたいです。
いくつかの方法があるのですが、今回はシンプルで汎用的なタグを確認する方法を使います。OnTriggerEnterの引数であるhitには、接触対象の情報が含まれます。この接触対象のタグを調べ、Playerならば特別な処理を行うようにItemScriptを以下のように修正します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemScript : MonoBehaviour
{
// トリガーとの接触時に呼ばれるコールバック
void OnTriggerEnter (Collider hit)
{
// 接触対象はPlayerタグですか?
if (hit.CompareTag ("Player")) {
// 何らかの処理
}
}
}
55
Playerにタグを設定する Playerオブジェクトにタグを設定してみましょう。
1. ヒエラルキービューでPlayerを選択 2. インスペクタービューのタグ(Tag)をPlayerに設定
56
接触判定時にItemを削除する プレイヤーがアイテムに接触したらアイテムが消えるように設定します。消える=シーンからの削除にはDestroyメソッドを使用します。 using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemScript : MonoBehaviour
{
// トリガーとの接触時に呼ばれるコールバック
void OnTriggerEnter (Collider hit)
{
// 接触対象はPlayerタグですか?
if (hit.CompareTag ("Player")) {
// このコンポーネントを持つGameObjectを破棄する
Destroy(gameObject);
}
}
}
57
Prefabの更新 ここまでItem(1)を使って調整してきました。先ほどと同じように、この調整を他のItem(2)~Item(6)にも適用します。
1. ヒエラルキービューでItem(1)を選択 2. インスペクタービューでオーバーライド(Overrides)を選択し、すべてを適用する(Apply All)を選択
ゲームを再生してみましょう。アイテムに接触するとアイテムが消えることがわかります。ゲームらしくなってきましたね!
58
アイテムの整理 ヒエラルキービューのItem(1)~Item(6)を整理しましょう。
1. ヒエラルキービューで作成→空のオブジェクトを作成を選択 2. 名前をItemsに変更 3. Item(1)~Item(6)をすべて選択し、Itemsへドラッグ&ドロップ
59
「残りのアイテム数」を表示するUIの作成 UI(ユーザーインターフェース)は、主にゲーム中の画面に表示される数字や文字を指します。ここでは画面左下に残りのアイテム数を表示するUIを作成します。
60
Canvasの設定 まずはUIを表示するCanvasを用意します。
1. ヒエラルキービューの作成→UI→キャンバス(Canvas)を選択
シーンビューでは巨大なキャンバスオブジェクトが確認できます。UIは他の3Dモデルと違い、ゲーム中の画面の手前に表示されるので、巨大であることは無視してください。
61
キャンバスのサイズを設定します。
1. ヒエラルキービューでCanvasを選択 2. インスペクタービューでキャンバススケーラ(CanvasScaler)のUIスケールモード(UI Scale Mode)を画面サイズに拡大(Scale With Screen Size)に設定
62
テキストの設定 UIに表示するテキスト(文字や数字)を設定します。
1. ヒエラルキービューの作成→UI→テキスト(Text)を選択 2. 名前をScoreLabelに変更 ※作成したテキスト(Text)は自動的にCanvasの子オブジェクトとなります。
現在はデフォルトのNew Textというテキストが表示されています。まずは表示位置を左下へ移動し、フォントの大きさを調整します。
1. ヒエラルキービューでCanvas→ScoreLabelを選択 2. 短形トランスフォーム(RectTransform)の値を以下のように設定
● 位置X(PosX):-230 ● 位置Y(PosY):-230 ● 位置Z(PosZ):0 ● 幅(Width):300 ● 高さ(Height):100
3. テキスト(Text)コンポーネントのテキスト(Text)欄に0と記入し、フォントサイズ(Font Size)を60に設定
63
64
GameControllerの作成 次に、シーン内の残りのアイテムの数を、先ほど作成したScoreLabelに通知して表示する仕組みを作成します。
この機能を実装する方法は無数にありますが、今回は一番簡単なGameControllerに管理させる方法を使います。アイテム数のようなゲーム全体の進行に関する機能はGameControllerが持つのが望ましいです。このGameControllerがシーン内のアイテム(Item)の残数を数え、変更があればScoreLabelに通知するという仕組みです。
ではGameControllerを作成していきましょう。
1. ヒエラルキービューの作成→空のゲームオブジェクトを選択 2. 名前をGameControllerに変更 3. インスペクタービューでタグをGameControllerに設定
65
タグの設定 今回はItem(1)~Item(6)に新しくItemタグを設定し、このタグを持つオブジェクトの数を計測する方法を使用します。
1. 画面上部のメニューの編集(Edit) → ProjectSettings → Tags And Layersを選択
2. タグ(Tag)の左にある▼ボタンを選択し、右側にある+ボタンを選択
3. New Tag NameにItemと入力してSaveを選択
66
ItemオブジェクトにItemタグを設定する 作成したItemタグをItem(1)~Item(6)に設定しましょう。先ほどの作業で一覧にItemタグが追加されています。
1. ヒエラルキービューでItem(1)を選択 2. インスペクタービューでタグをItemに設定 3. オーバーライド→すべてを適用するを選択
オーバーライド→すべてを適用するを行うことで、同じPrefabであるItem(2)~Item(6)すべてに設定が適用されます。
67
Itemをカウントする機能を追加 GameControllerにItemのタグを持つオブジェクトをカウントする機能を追加します。GameControllerオブジェクトにGameControllerコンポーネントを作成して追加しましょう。
1. ヒエラルキービューでGameControllerを選択 2. インスペクタービューでコンポーネントを追加を選択 3. 新しいスクリプトを選択し、名前をGameControllerにして作成して追加を選択
4. プロジェクトブラウザのAssetsフォルダー内に作成されたGameControllerをScriptフォルダーに移動
5. GameControllerをダブルクリックして開く GameControllerに以下のようにコードを記述します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour
{
public void Update ()
{
int count = GameObject.FindGameObjectsWithTag ("Item").Length;
}
}
68
残りのアイテム数を表示する 残りのアイテム数を、UIのScoreLabelに表示するようにします。
まずはGameControllerからTextコンポーネントへアクセスする方法として、Textコンポーネントへの参照を設定する方法を利用します。
まずは参照に使用するコードを作成します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour
{
public UnityEngine.UI.Text scoreLabel;
public void Update ()
{
int count = GameObject.FindGameObjectsWithTag ("Item").Length;
}
}
69
次に取得したItem数をtextに代入します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour
{
public UnityEngine.UI.Text scoreLabel;
public void Update ()
{
int count = GameObject.FindGameObjectsWithTag ("Item").Length;
scoreLabel.text = count.ToString ();
}
}
70
GameControllerとScoreLabelの紐付け 作成したGameControllerとScoreLabelを紐付けます。
1. ヒエラルキービューでGameControllerを選択 2. ScoreLabelをScoreLabelの欄へドラッグ&ドロップ
ゲームを再生してみてください。 画面左下に残りのアイテム数が表示され、プレイヤーがアイテムを取得する度にアイテム数が減ることがわかりますね!
71
クリア時のUIを作成 次は、アイテム数と同じUIテキストの機能を使ってクリア時(アイテムをすべて取った時)の表示を作成します。
1. ヒエラルキービューの作成→UI→テキストを選択 2. 名前をWinnerLabelに変更
72
ラベルの設定 続いてWinnerLabelの内容を設定します。
1. ヒエラルキービューでWinnerLabelを選択 2. インスペクタービューで短形トランスフォームを以下の値に設定
● 位置X:0 ● 位置Y:0 ● 位置Z:0 ● 幅:300 ● 高さ:100
3. テキスト欄にYOU WINと入力 4. フォントサイズを60に設定
73
クリア条件の設定 続いてGameControllerに少し手を加えてクリア条件を設定します。
今回のゲームではアイテムを全て回収する=残りのアイテムが0になることが勝利条件です。シーン内にItemタグを持つオブジェクトが見つからなかったら(全てなくなったら)勝利とします。
1. プロジェクトブラウザでGameControllerをダブルクリックして開く
2. コードを以下のように修正
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour
{
public UnityEngine.UI.Text scoreLabel;
public void Update ()
{
int count = GameObject.FindGameObjectsWithTag ("Item").Length;
scoreLabel.text = count.ToString ();
if (count == 0) {
// クリア時の処理
}
}
}
74
GameControllerからWinnerLabelへの参照を設定 最後にクリア時に初めて「YOU WIN」の文字が表示されるようにします。今回もWinner Labelへの参照が必要ですが、今までと同様にエディター側で設定します。 GameControllerを以下のように修正します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour
{
public UnityEngine.UI.Text scoreLabel;
public GameObject winnerLabelObject;
public void Update ()
{
int count = GameObject.FindGameObjectsWithTag ("Item").Length;
scoreLabel.text = count.ToString ();
if (count == 0) {
// クリア時の処理
}
}
}
GameControllerからWinnerLabelへの参照を設定します。
1. ヒエラルキービューでGameControllerを選択 2. ヒエラルキービューのWinnerLabelをインスペクタービューの
GameControllerコンポーネントのWinner Label Objectへドラッグ&ドロップ
75
ここでゲームを再生してみましょう。YOU WINの表示が最初から出てしまっていますね。
76
「YOU WIN」を非表示にする クリア条件を満たすまで、YOU WINを非表示にします。
Unityで描画されているものを非表示にする方法はいくつかありますが、今回はオブジェクトを非アクティブにする事で非表示にします。
1. ヒエラルキービューでWinnerLabelを選択 2. インスペクタービューでオブジェクトのチェックを外す
これでシーンビューやゲームビューからもYOU WINの表示が消えました。
77
クリア時に「YOU WIN」と表示する クリア時に非アクティブの「Winner Label」をアクティブにすることで、ゲームクリア時にYOU WINと表示します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour
{
public UnityEngine.UI.Text scoreLabel;
public GameObject winnerLabelObject;
public void Update ()
{
int count = GameObject.FindGameObjectsWithTag ("Item").Length;
scoreLabel.text = count.ToString ();
if (count == 0) {
// オブジェクトをアクティブにする
winnerLabelObject.SetActive (true);
}
}
}
78
ゲームをプレイ ゲームを再生してみましょう。プレイヤーがすべてのアイテムを取り、アイテム数が0になるとYOU WINの文字が表示されるようになりましたね!
しかし、これだけではただアイテムを集めるだけの作業になってしまっていて面白みに欠けます。最後の仕上げとして、接触してはいけない障害物を作成しましょう。完成まであとひと息です!
79
障害物の作成 まずは障害物の3Dモデルを作成します。
DangerWallプレハブの作成 1. ヒエラルキービューの作成→3Dオブジェクト→キューブを選択 2. 名前をDangerWallに変更 3. ヒエラルキービューのDangerWallをプロジェクトブラウザのPrefabフォルダーにドラッグ&ドロップしてPrefabのDangerWallを作成
80
DangerWallの色を設定 DangerWallは接触してはいけない危険な壁です。より危険度が高く見えるよう「光る壁」としてマテリアルを設定します。
1. プロジェクトブラウザで作成→マテリアルを選択 2. 名前をDangerWallMaterialに変更 3. DangerWallMaterialをMaterialフォルダーに移動 4. インスペクタービューで以下を設定
● アルベド(Albedo):赤や黄色など危険色(地面や壁とは別の色にする)
● 放出(Emission):チェックを入れ、色をアルベドと同様の色を設定。強度(Intensity)を1.3に設定
81
5. DangerWallMaterialをヒエラルキービューのDangerWall(またはシーンビューのDangerWallオブジェクト)へドラッグ&ドロップ
6. ヒエラルキービューのDangerWallを選択し、インスペクタービューのオーバーライド→すべてを適用するを選択
82
83
DangerWallの配置 DangerWallのサイズと位置を調整しましょう。
1. ヒエラルキービューのDangerWallを選択 2. インスペクタービューのトランスフォームコンポーネントを以下のように設定
● 位置(Position) :X:4 Y:0.5 Z:3 ● 回転(Rotation) :X:0 Y:0 Z:0 ● 拡大/縮小(Scale):X:10 Y:1 Z:1
このとき、調整したDangerWallがItemと重なってしまうとクリアできなくなります。もし重なる場合はItemの位置を少しずらしましょう。
84
DangerWallの複製 DangerWallを複製し、位置・回転・拡大/縮小の数値を調整してステージ内に配置してみましょう。この部分は好きなように複製、配置して構いません。ここでは例として以下のように設定してみます。
1. ヒエラルキービューのDangerWallを選択し、右クリックして複製を選択
2. さらにもう一度複製を選択し、DangerWallオブジェクトを合計3個にする
3. DangerWallオブジェクトの名前をDangerWall 1、DangerWall 2、DangerWall 3に変更
4. それぞれの位置・回転・拡大/縮小の数値を調整 DangerWall 1 * position (x:4, y:0.5, z:3) rotation (x:0, y:0, z:0) scale(x:10, y:1, z:1) DangerWall 2 * position (x:4, y:0.5, z:-4) rotation (x:0, y:0, z:0) scale(x:10, y:1, z:1) DangerWall 3 * position (x:-5, y:0.5, z:4) rotation (x:0, y:90, z:0) scale(x:10, y:1, z:1) ゲームを再生して、DangerWallとItemが重なっていないことを確認しましょう。この時点ではDangerWallはただの壁で、接触しても何も起こりません。
85
DangerWallの整理 DangerWallオブジェクトが増えてきましたね。Item同様、空のゲームオブジェクトを作って整理しましょう。
1. ヒエラルキービューの作成→空のオブジェクトを作成を選択 2. 名前をDangerWallsに変更 3. DangerWallオブジェクトを全てDangerWallsへドラッグ&ドロップ
DangerWallとStageの静的(static)化
先ほどマテリアルで設定した放出(Emission)による発光エフェクトは、発光する側のオブジェクトと光を受けるオブジェクトの両方を静的(static)に設定することで効果を発揮します。
1. DangerWallsを選択した状態でインスペクタービューの静的(static)にチェックを入れる
2. 表示されるダイアログでYes, change childrenを選択 3. Stagesを選択した状態でインスペクタービューの静的(static)にチェックを入れる
4. 表示されるダイアログでYes, change childrenを選択
86
ライティング(Lighting)設定とマテリアルの調整
オブジェクトを静的に設定することで放出の発光エフェクトが反映されるようになりました。この時、発光エフェクト等の情報が裏で処理・保存されています。この処理のことをベイク(Bake、焼き付け)と呼びます。
地面の色が濃いとベイクによる変化がわかりにくいかもしれません。プロジェクトブラウザでGroundMaterialを選択し、色を調整してみましょう。
87
自動ベイクと手動ベイク 見栄えは良くなりましたが、ベイクはPCに負荷がかかります。また、ベイク途中でシーンを再生してしまうと表示がおかしくなることがあります。
オブジェクトを動かしたり、マテリアルを調整するたびに自動的にベイクがかかるのを避けるためには、以下の手順でライティングの自動生成をオフにして手動でベイクしましょう。
1. 画面上部のメニューからウインドウ(Window)→レンダリング(Rendering)→ライティング設定(Lighting Settings)を選択
2. 下方にある自動生成(Auto Generate)のチェックをオフにする 3. 自動生成の右にあるライティングの生成(Generate Lighting)を選択
88
89
太陽光の輝度を下げる DangerWallはマテリアルの設定で放出(Emission)の強度を1.3にしたため、光っているのですが太陽光の強度(Intensity)が高く、少し分かり難いです。太陽光の強度を下げて調整してみましょう。
1. ヒエラルキービューのDirectionalLightを選択 2. インスペクタービューでライト(Light)コンポーネントの強度(
Intensity)を0.6に設定
90
障害物の接触判定の設定 最後に、障害物に当たったらシーンを再起動する機能を作成します。
1. ヒエラルキービューでDangerWall 1を選択 2. インスペクタービューでコンポーネントを追加を選択 3. 新しいスクリプトを選択し、名前をDangerWallScriptに設定して作成して追加を選択
4. オーバーライド→すべてを適用するを選択 5. DangerWallScriptをScriptフォルダーに移動
91
スクリプトによる判定 DangerWallScriptをダブルクリックして開き、「接触したか」の判定を受けるコールバックを設定します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DangerWallScript : MonoBehaviour
{
// オブジェクトと接触した時に呼ばれるコールバック
void OnCollisionEnter (Collision hit)
{
// 何かの処理
}
}
92
接触したらシーンを再読込 DangerWallの接触対象がPlayerタグを持つオブジェクトの場合、シーンを再読込し、ゲームを最初の状態にリセットします。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class DangerWallScript : MonoBehaviour
{
// オブジェクトと接触した時に呼ばれるコールバック
void OnCollisionEnter (Collision hit)
{
// 接触したオブジェクトのタグが"Player"の場合
if (hit.gameObject.CompareTag ("Player")) {
// 現在のシーン番号を取得
int sceneIndex = SceneManager.GetActiveScene().buildIndex;
// 現在のシーンを再読込する
SceneManager.LoadScene(sceneIndex);
}
}
}
ゲームを再生してみてください。DangerWallに当たるとゲームがリセットされてしまうため、精密な操作を要求するゲームになりましたね!
93
ゲームの完成 さあ、これでゲームは完成です!ぜひゲームを家族や友達にプレイしてもらってください。
また、さらに独自の改造を行うことも考えられます。ここからは開発者のセンスや発想、技術力でゲームを調整し、つくりこむことができます。
● 障害物(DangerWall)やアイテム(Item)の数を増やす
● 壁(Wall)を新しく作成して設置する
● プレイヤー(Player)やアイテム(Item)にマテリアルを設定して色をつける
● プレイヤー(Player)のスピードを変える
本チュートリアルはこれで終了となります。お疲れ様でした!
94