こんにちは、shiguregakiです!
先日、「Unityの教科書 Unity 2019完全対応版 2D&3Dスマートフォンゲーム入門講座」を読み終え、チョー基礎ですがUnityでのゲーム作りの流れを学ぶことができたと思っています。
せっかくなので、ここで1つのゲームを一から作ってみようと思い、「3D玉転がし」ゲームを作ることに決めました!
別のブログ(【Unity 勉強5】3D玉転がしゲームを作ってみる!(その1))で「3D玉転がし」の簡単な設計を行い、以下のような工程で進める方針となりました。
【3D玉転がしの開発工程】
- 実現方法の検討
- デザインの検討
- デザインの作成(必要あれば)
- プロジェクトの作成
- 外枠の作成
- 操作部分(押し出し棒、バネ)の動作作成
- ビー玉の動作作成
- ステージ(釘や得点スポット)を作成
- Prefabを作る
- 監督スクリプトの作成
このブログでは「7. ビー玉の動作作成」、「8. ステージ(釘や得点スポット)を作成」をしたいと思います。
ソースコード自体は、以下で公開していますので、よろしければご覧ください。
全行程は以下のブログでまとめているので、よろしければご覧ください。
目次
3D玉転がしとは?
小学校の図工のときに作ったあれ ↓ です。
玉転がしゲームB(ビー玉あそび)
Amazon 楽天
ビー玉の動作を作成する
上で紹介した【3D玉転がしの開発工程】の「7. ビー玉の動作作成」として、ビー玉を作成し、動作をスクリプトで設定します。
事前に調査した結果、以下のような方針で作成しました。
- ビー玉の基本動作は「Rigidbody」によって作成すること
- ビー玉が壁や釘などに衝突したときの動作は「Physic Material(物理特性マテリアル)」を作成すること
- ビー玉のデザインはガラス調を出すため、「Tsumiki Tech Timesさんのシェーダー」を使うこと
- ビー玉の色はタグを使用して、スクリプト側で設定すること
ビー玉を作成する
ビー玉本体は3D Sphereで作成します。
重力落下などの基本動作は「Rigidbody」で作成します。
- Massは5にしています。
- 重力は使用するので、「Use Gravity」をチェックします。
- 玉転がしのフィールド部分はXZ面に作成しているので、Y軸方向の動きはでないように「Freeze Position」のYにチェックします。
- ※重力方向は「Edit → Project Settings → Physics」でZ軸方向に変更しています。
ビー玉にPhysic Material(物理特性マテリアル)を設定する
ビー玉が壁や釘と衝突したときに跳ね返りするために、ビー玉オブジェクトにPhysic Material(物理特性マテリアル)を設定します。
Physic Material(物理特性マテリアル)はProjectウィンドウで「Create → Physic Material」から作成できます。
以下の2種類のPhysic Material(物理特性マテリアル)を作成し、ビー玉や壁などのオブジェクトにアタッチしました。
- 衝突時に跳ね返りするPhysic Material
- ビー玉、壁、釘に設定する(以下の画像の青枠部分)
- 衝突時に跳ね返りしないPhysic Material
- 押し出し棒、フィールド上部壁に設定する(以下の赤枠部分)
【衝突時に跳ね返りするPhysic Materialの設定値】
【衝突時に跳ね返りしないPhysic Materialの設定値】
ビー玉のスクリプトを作成する
ビー玉を操作するために「MarbleController」スクリプトを作成し、ビー玉オブジェクトにアタッチします。
スクリプトは以下のようにしました。
※後工程で作成予定のGameDirector, MarbleGenerator
も組み込んでいるので、注意してください。
【MarbleController.cs】
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class MarbleController : MonoBehaviour
{
// 削除するときのspeed
float destroySpeed = 1.0f;
// 削除するまでの時間
float destroyTime = 1.0f;
GameObject GameDirector, MarbleGenerator;
Collider lastDetectCollider;
bool detectFlg = false;
bool isGenerated = false;
void Start()
{
this.GameDirector = GameObject.Find("GameDirector");
this.MarbleGenerator = GameObject.Find("MarbleGenerator");
// タグにより色の判定
if (this.tag == "RedMarble")
{
GetComponent<Renderer>().material.SetColor("_Color", new Color(1, 0.0f, 0.0f, 1));
}
else if (this.tag == "BlueMarble")
{
GetComponent<Renderer>().material.SetColor("_Color", new Color(0.227f, 0.855f, 1, 1));
}
else if (this.tag == "BlackMarble")
{
GetComponent<Renderer>().material.SetColor("_Color", new Color(0.605f, 0.590f, 0.622f, 1));
}
GetComponent<Renderer>().material.SetFloat("_DistortionE", 1.0f);
}
void Update()
{
int score = 0;
// 速度を監視して、ビー玉が停止したら一番最後に触れたコライダに応じて得点をカウント
if (this.GetComponent<Rigidbody>().velocity.magnitude <= this.destroySpeed)
{
if (this.lastDetectCollider != null && this.detectFlg == false)
{
this.detectFlg = true;
// タグごとに得点を算出
if (this.lastDetectCollider.tag == "100point")
{
score = 100;
}
else if (this.lastDetectCollider.tag == "200point")
{
score = 200;
}
else if (this.lastDetectCollider.tag == "500point")
{
score = 500;
}
else
{
score = 0;
}
// 得点をGameDirectoreに伝える
this.GameDirector.GetComponent<GameDirector>().UpdateScore(score, this.tag);
// 1秒後にビー玉を削除する
StartCoroutine(DelayMethod(this.destroyTime, () =>
{
Destroy(this.gameObject);
}));
}
}
}
private void OnTriggerEnter(Collider other)
{
// MarbleDetectorであれば、ビー玉を生成
if (other.name == "MarbleDetector" && !isGenerated)
{
// MarbleGeneratorでビー玉生成する
this.MarbleGenerator.GetComponent<MarbleGenerator>().GenerateMarble();
isGenerated = true;
}
// ScoreSpotであれば、lastDetectColliderに格納
if (other.name == "ScoreSpot")
{
this.lastDetectCollider = other;
}
}
private void OnCollisionEnter(Collision collision)
{
// BottomWallであれば、lastDetectColliderに格納
if (collision.collider.name == "BottomWall")
{
this.lastDetectCollider = collision.collider;
}
}
/// <summary>
/// 渡された処理を指定時間後に実行する
/// </summary>
/// <param name="waitTime">遅延時間[ミリ秒]</param>
/// <param name="action">実行したい処理</param>
/// <returns></returns>
/// <remarks>https://qiita.com/toRisouP/items/e402b15b36a8f9097ee9</remarks>
private IEnumerator DelayMethod(float waitTime, Action action)
{
yield return new WaitForSeconds(waitTime);
action();
}
}
Start()
内でビー玉オブジェクトに設定されたタグを読み取り、タグによって色を設定しています。- ビー玉オブジェクトは停止したら一番最後に触れたコライダ(得点スポットもしくはフィールド下部の壁)によって得点を算出し、
GameDirector
に得点を伝えます。その後、DelayMethod()
を使って1秒後に消えるようにしています。 DelayMethod()
はN秒後に実行するような関数です。- 「【Unity】スクリプトの処理の実行タイミングを操作する」を参考にしました。
OnTriggerEnter()
とOnCollisionEnter()
で一番最後に触れたコライダが得点スポットもしくはフィールド下部の壁のどちらかを監視しています。
ソースコード自体は、以下で公開していますので、よろしければご覧ください。
ビー玉のデザインをガラス調にする
ビー玉のデザインは「Tsumiki Tech Timesさんのシェーダー」を使うことにしたので、シェーダーファイルを作成し、そこにコピペしていきます。
プロジェクトウィンドウで右クリック→「Create」→「Shader」→「Standard Surface Shader」でシェーダファイルを作り、「Tsumiki Tech Timesさんのシェーダー」の一番下にあるコードをそのシェーダーにコピペしました。
また、「Create」→「Material」でマテリアルを作成し、ビー玉オブジェクトにアタッチし、インスペクタからマテリアルのシェーダを「Custom/MarbleDesignShader」に変更しました。
透明すぎてビー玉が見えにくくなっていますが、ここに色をつけることでビー玉感を出すようにします。
#ビー玉のデザインは「Unityでビー玉のデザインを表現してみる」で調査しましたので、よろしければご覧ください。
ステージ(釘や得点スポット)を作成する
上で紹介した【3D玉転がしの開発工程】の「8. ステージ(釘や得点スポット)を作成」として、ステージ上に釘や得点スポットを作成します。
事前に調査した結果、以下のような方針で作成しました。
- 釘には「Physic Material(物理特性マテリアル)」の「衝突時に跳ね返りするPhysic Material」の方をアタッチすること
- 釘のデザインは「Yughues Free PBR Metal Plates」の「MetalPlates_22」を使用すること
- 得点スポットのデザインは自作した画像を使用すること
- 得点スポットは100点、200点、500点の種類を用意し、タグによって区別すること
- 得点スポットにBox Colliderを設定して、ビー玉との当たり判定を行るようにすること
釘オブジェクトを作成する
釘オブジェクトはポール部分、頭部分を別々の3D Cylinderオブジェクトを組み合わせて作りました。
釘の頭部分のColliderは3D CylinderのColliderだと球型に広がってしまったため、「Box Collider」に変更しています。
釘には「ビー玉の動作を作成する」の章で作成した「衝突時に跳ね返りするPhysic Material」を設定しました。
釘のデザインを金属調にする
釘感だすために、金属のデザインを設定することにします。
釘のデザインは事前の調査で「Yughues Free PBR Metal Plates」の「MetalPlates_22」を使うことにしたので、それをインストールしました。
画像だとあまり違いが分かりにくいですが、「Yughues Free PBR Metal Plates」は下の画像のように金属光沢とかもいい感じに表現できています。
今回採用している「MetalPlates_22」は左側のものです。
#金属調のデザインは「Unityで金属のデザインを表現してみる」で調査しましたので、よろしければご覧ください。
複数の釘を配置する
フィールド上に釘を設置していきます。
釘と得点スポットの設定イメージは以下のようにしました。
- 釘を使ってビー玉を受けるカゴを作り、そのカゴを得点スポットとして使用することにします。
- カゴを作るために幾つかの釘が必要なので、それをまとめたのが「Nails-n」というものです。
- 「Nails-other」はそれ以外にフィールドに設置する釘をまとめたものです。
釘で作ったカゴを上記のイメージのように配置すると以下のようになりました。
ここにさらに「Nails-ohter」として、適当に釘をセットしました。
得点スポットを配置する
得点スポットのデザインは自作することにしました。
※自作といってもパワポで簡単に作ったものです。
ヒエラルキーウィンドウに「Quad」を作成し、そこに自作した得点スポットの画像を張り付けるようにしました。
さらに、ビー玉が得点スポットに入ったことを検知するために、「Box Collider」も設置しました。
得点スポットをすべての釘のカゴに紐づけると以下のようになりました。
まとめ
3D玉転がしの「7. ビー玉の動作作成」、「8. ステージ(釘や得点スポット)を作成」を作成しました。
ステージに釘や得点スポットも配置されて、だいぶ玉転がし感がでてきたのではないでしょうか。
次回は、残りの開発工程を進めていきたいと思います。
関連動画
次の工程
前の工程
全行程
広告
Unityを初めて勉強するなら「Unityの教科書 Unity 2019完全対応版 2D&3Dスマートフォンゲーム入門講座」がオススメです!
全くUnityが分からなかった状態でも概要を理解することができました。
Unityの教科書 Unity 2019完全対応版 2D&3Dスマートフォンゲーム入門講座
Amazon 楽天
以上!
コメント