Unityで作る3D脱出ゲームの作り方を紹介している記事その28です。
僕が所属しているオンラインサロンの
先生である嶋津さんが作成された動画を
見ながら勉強した内容について、
「3D脱出ゲームの作り方」
としてまとめている記事になります。
その28となるこの記事では、
「アイテムを拡大表示してズームする方法」
についてお伝えしています。
参考となる動画はこちらです。
【Unity】ライブで教材制作!脱出ゲーム制作の残りを終わらせるぞ!パート1
このページでお伝えしている内容は、
動画の1:19:20あたりからの内容になります。
この動画で勉強すること
▶︎選択したアイテムを拡大表示するズーム方法について学ぶ。
目標1
拡大したアイテムを表示する「ズームパネル」のUIを作成する。
=>UIのCanvasを作る(ZoomCanvas)
=>ZoomCanvasの下にPanelを作る(BackGroundPanel)
=>BackGroundPanelの下にさらにPanelを作る(BlackPanel)
=>BlackPanelの色を黒に変更して大きさを調整する
=>BlackPanelの下に空のゲームオブジェクトを作成する(ZoomObjParent)
=>ZoomObjParentの下にTileのプレハブを入れる
=>ZoomCanvasのRender ModeをScreen Space Cameraに変更して、Render CameraにMain Cameraを設定する。
=>Plane Distanceを小さくする(0.5くらい)
=>Tileの位置を0,0,0にして、大きさを調整する(150,150,15くらい)
=>ZoomObjParentのPos Zを-83くらいにする
=>ZoomCanvasのBackgroundPanelを非表示にする
目標2
虫眼鏡のズームボタンを押した時に、ズームパネルが表示されるようにする。
=>C#スクリプトを作る(ZoomPanel)
=>ZoomPanelスクリプトにコードを書く(クリックした時に表示させる処理)
=>ZoomPanelスクリプトにコードを書く(ズームパネルを非表示にする処理)
=>HIerarchyのZoomCanvasにZoomPanelスクリプトをつける
=>InspectorでzoomPanelの欄にBackGroundPanelを設定する
=>ZoomButtonにButton機能をAdd Componentして設定する。
目標3
×ボタンを押すとズームパネルが閉じるようにする。
=>HIerarchyのBlackPanelの下にUIのButtonを作成する
=>ButtonのTextを「x」に変更する
=>Buttonのサイズを50,50くらいに調整して位置を右上に移動する
=>Button機能を設定する
目標4
Main Camera以外でもズームパネルを表示できるようにする。
=>ZoomPanelスクリプトの編集をする(Canvasの取得、static化)
=>CameraManagerスクリプトを編集する(ChengeCamera関数)
(#25の動画を参考にしている場合はSetZoomCamera関数)
=>ZoomPanelスクリプトの編集をする(Set RenderCamera関数)
=>CameraManagerスクリプトを編集する(OnBackButton関数)
目標5
アイテムを選択中にズームボタンを押すとそのアイテムが拡大表示されるようにする。
=>ZoomPanelスクリプトにコードを書く(ShowItem関数)
=>ItemBoxスクリプトにコードを書く(GetSelectItem関数)
=>Itemスクリプトにコードを書く(Zoom時に表示するPrefabを設定するためのコード)
=>UnityのPrefabsフォルダにZoomObjフォルダを作る
=>ZoomObjフォルダの中にズーム用のPrefabを作成する。(RedTile,BlueTile,YellowTile)
=>ItemDatabaseEntityにズーム用のPrefabを設定していく
=>ItemDatabaseスクリプトにコードを書く(CreateZoomItem関数)
=>ZoomPanelスクリプトのコードを編集する(ShowItem関数)
=>ズームアイテムが生成される位置の修正を行う(ShowItem関数の修正)
目標6
拡大表示したアイテムが重ならずに切り替わって表示されるようにする。
=>ZoomPanelスクリプトのコードを編集する(ShowItem関数)
ZoomPanelスクリプトのコード
アイテムを拡大表示させるために
作成したZoomPanelスクリプトの
コードは以下となります。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ZoomPanel : MonoBehaviour
{
// クリックされたらZoomパネルの表示
// メインカメラ以外でもパネルを出せるようにする
[SerializeField] GameObject zoomPanel = default;
Canvas canvas = default;
[SerializeField] Transform zoomObjParent = default;
GameObject zoomItem;
// どこからでも使えるようにする
public static ZoomPanel instance;
private void Awake()
{
instance = this;
}
private void Start()
{
canvas = GetComponent<Canvas>(); //Canvasの取得
HideZoomPanel();
}
public void SetRenderCamera(Camera camera)
{
canvas.worldCamera = camera;
}
//ズームボタンをクリックした時の処理
public void OnClickZoom()
{
zoomPanel.SetActive(true);
ShowItem();
}
void ShowItem()
{
// 選択中のアイテムを表示する
// 表示する = データベースから生成してやる
if(zoomItem != null)
{
Destroy(zoomItem);
}
Item selectItem = ItemBox.instance.GetSelectItem();
zoomItem = ItemDatabase.instance.CreateZoomItem(selectItem.type);
zoomItem.transform.SetParent(zoomObjParent, false);
}
public void HideZoomPanel()
{
zoomPanel.SetActive(false);
}
}
CameraManagerスクリプトのコード
今回編集したCameraManagerの
コードは以下となります。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraManager : MonoBehaviour
{
[SerializeField] GameObject backButton = default;
[SerializeField] GameObject leftButton = default;
[SerializeField] GameObject rightButton = default;
[SerializeField] Transform[] cameraPositions = default;
int currentIndex = 0;
Camera zoomCamera = default;
Camera mainCamera = default;
// どこからでもアクセスできるようにする
public static CameraManager instance;
private void Awake()
{
instance = this;
}
void Start()
{
mainCamera = Camera.main;
currentIndex = 0;
SetCameraPosition(currentIndex);
backButton.SetActive(false);
}
public void TurnRight()
{
currentIndex++;
if(currentIndex >= cameraPositions.Length)
{
currentIndex = 0;
}
SetCameraPosition(currentIndex);
}
public void TurnLeft()
{
currentIndex--;
if (currentIndex < 0)
{
currentIndex = cameraPositions.Length -1;
}
SetCameraPosition(currentIndex);
}
void SetCameraPosition(int index)
{
Camera.main.transform.position = cameraPositions[index].position;
Camera.main.transform.rotation = cameraPositions[index].rotation;
}
// ズームした時の処理(ライブ1の動画の場合はChengeCamera関数)
public void SetZoomCamera(Camera zoomCamera)
{
this.zoomCamera = zoomCamera;
backButton.SetActive(true);
leftButton.SetActive(false);
rightButton.SetActive(false);
Camera.main.gameObject.SetActive(false);
ZoomPanel.instance.SetRenderCamera(zoomCamera);
}
// バックボタンを押した時の処理
public void OnBack()
{
backButton.SetActive(false);
leftButton.SetActive(true);
rightButton.SetActive(true);
// メインカメラに戻す = Zoomカメラを非表示&メインカメラを表示
this.zoomCamera.gameObject.SetActive(false);
mainCamera.gameObject.SetActive(true);
ZoomPanel.instance.SetRenderCamera(mainCamera);
}
}
ItemBoxスクリプトのコード
今回編集したItemBoxスクリプトの
コードは以下となります。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemBox : MonoBehaviour
{
// ItemBoxが全てのSlotを把握
[SerializeField] Slot[] slots = default;
//どこからでも利用できる変数
public static ItemBox instance;
// アイテム選択を作る // 選択アイテム =>選択スロット
Slot selectSlot;
private void Awake()
{
//自分を入れる
instance = this;
}
// クリックしたらItemを受け取る
public void SetItem(Item item)
{
// TODO:左詰めで入れる=左から空いてるSlotがあれば入れる
for(int i=0; i<slots.Length; i++)
{
Slot slot = slots[i];
if (slot.IsEmpty())
{
slot.Set(item);
break;
}
}
}
// スロットをクリックした時
public void OnSlotClick(int position)
{
// 選択したところにアイテムがなかったら、何もしない
if (slots[position].IsEmpty())
{
return; //関数の実行をここで終了する
}
// 一度全て白にする
for(int i=0; i<slots.Length; i++)
{
//slots[i]の背景をなくす
slots[i].HideBackPanel();
}
// クリックしたスロットの背景を黒にする
slots[position].OnSelect();
// 選択アイテムとして、取得する
selectSlot = slots[position];
}
// アイテムを選択しているかどうかを判定する関数
public bool CheckSelectItem(Item.Type useItemType)
{
if(selectSlot == null)
{
return false;
}
if(selectSlot.GetItem().type == useItemType)
{
return true;
}
return false;
}
public void UseSelectItem()
{
selectSlot.RemoveItem();
selectSlot = null;
}
public Item GetSelectItem()
{
if(selectSlot == null)
{
return null;
}
return selectSlot.GetItem();
}
}
Itemスクリプトのコード
今回編集したItemスクリプトの
コードは以下となります。
using System;
using UnityEngine;
[Serializable] // インスペクターで表示される
public class Item
{
// 種類を持っている
public enum Type
{
RedTile,
BlueTile,
YellowTile,
Key,
Coin,
}
public Type type;
// 画像を持っている
public Sprite sprite;
//Zoom時に表示するためのPrefab
public GameObject zoomPrefab;
public Item(Item item)
{
this.type = item.type;
this.sprite = item.sprite;
}
}
ItemDatabaseスクリプトのコード
今回編集したItemDatabaseの
コードは以下となります。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemDatabase : MonoBehaviour
{
public static ItemDatabase instance;
private void Awake()
{
instance = this;
}
[SerializeField] ItemDatabaseEntity ItemDatabaseEntity = default;
//Itemをtypeから生成する
public Item spawn(Item.Type type)
{
for(int i=0; i< ItemDatabaseEntity.items.Count; i++)
{
Item itemData = ItemDatabaseEntity.items[i];
//データベースの中からtypeが一致するものを探す
if (itemData.type == type)
{
//一致したら、Itemを生成して渡す
return new Item(itemData);
}
}
return null;
}
//ズームアイテムを生成する
public GameObject CreateZoomItem(Item.Type itemType)
{
for (int i = 0; i < ItemDatabaseEntity.items.Count; i++)
{
Item itemData = ItemDatabaseEntity.items[i];
//データベースの中からtypeが一致するものを探す
if (itemData.type == itemType)
{
//一致したら、Itemを生成して渡す
return Instantiate(itemData.zoomPrefab);
}
}
return null;
}
}
アイテムの拡大表示をする方法で勉強したことのまとめ
3D脱出ゲームの作り方その28
「アイテムの拡大表示をする方法」
で勉強した内容についてのまとめです。
・アイテムの拡大表示を行うには、
まず最初に拡大したアイテムを
表示するためのU Iを作成します。
・次にズームボタンを押した時に
ズームパネルが表示されるという
処理を作成します。
・表示ができたら次は×ボタンを
押した時にズームパネルが
非表示になる処理を作成します。
・さらに、Main Cameraだけでなく
SubCamera(ZoomCamera)でも
ズームパネルが表示できるようにします。
・そして、アイテムを選択している
時にだけズームパネルの表示が
されるように処理を作成します。
・最後に、拡大表示したアイテムが
重ならずに表示されるよう修正をします。
以上で、選択したアイテムを
拡大して表示する処理が
できるようになりました。
青タイルを選んでズームボタン
(虫眼鏡)を押すと、青タイルが拡大します。
黄色タイルを選択した状態で
ズームボタンを押すと、
黄色タイルが拡大表示されます。
「アイテムを拡大表示してズームする方法」
の目標は以上で達成です!