概要
-
Unity 2020.3
でカンタンなVRのゲームを作成します - 食べ物をカゴでキャッチするゲームを作成します
- 最終的に
WebGL
でデプロイしてブラウザで楽しめるVRのコンテンツを作成します - 一日で完成できたモノなので手順を参考にして作ってもらえれば幸いです
素材(Asset)
WebVR用のパッケージ
完成物
-
Bowl
を操作して落ちてくる食べ物をキャッチするゲームです
作成手順
ゲームの作成
3Dのプロジェクトを新規作成する
素材(Asset)を全てインポートする
- 上記の素材(Asset)を全てインポートします
サンプルのシーンをコピーする
-
RPGPP_LT
のサンプルシーンを使用します - シーン自体をコピーして複製し任意の名前をつけます
- 複製したシーンを加工していきます
サンプルのシーンのオブジェクトを整理する
-
Environment
という空のオブジェクトを作成します - 作成したオブジェクトを親にして全てのオブジェクトを子にします
-
Environment
の位置を調整します-
Position
X:0 Y:-35 Z:-85 -
Rotation
X:0 Y:110 Z:0
-
カメラの視点をマウスで動かせるようにする
-
DragMove.cs
というスクリプトを作成して以下の内容を記述します - 作成したスクリプトを
MainCamera
にアタッチします -
MoveObj
にカメラのオブジェクトであるMainCamera
をアタッチします - アタッチ後に実行するとマウスのドラッグでカメラの視点を動かすことができます
-
MainCamera
の位置を調整します-
Position
X:0 Y:0 Z:0
-
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DragMove : MonoBehaviour
{
public GameObject moveObj;
private Vector3 newAngle = new Vector3(0, 0, 0);
private Vector3 lastMousePosition;
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
// マウスクリック開始(マウスダウン)時にカメラの角度を保持(Z軸には回転させないため).
newAngle = moveObj.transform.localEulerAngles;
lastMousePosition = Input.mousePosition;
}
else if (Input.GetMouseButton(0))
{
// マウスの移動量分カメラを回転させる.
newAngle.y -= (Input.mousePosition.x - lastMousePosition.x) * 0.1f;
newAngle.x -= (Input.mousePosition.y - lastMousePosition.y) * 0.1f;
moveObj.transform.localEulerAngles = newAngle;
lastMousePosition = Input.mousePosition;
}
}
}
ゲーム全体を管理するスクリプトを作成する
-
TextMechPro
のText
でScoreText
とTimeText
というオブジェクトを作成します - 作成すると
Canvas
が自動的に生成されるのでアンカーなどで位置を調整します - 空のオブジェクトで
GameControl
を作成します -
GameControl
に以下のスクリプトを作成してアタッチします - スクリプトに
ScoreText
とTimeText
をアタッチします
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class GameManager : MonoBehaviour
{
public TextMeshProUGUI scoreText;
public TextMeshProUGUI timeText;
public static float time = 60;
public static int score = 0;
// Update is called once per frame
void Update()
{
GameEndCheck();
scoreText.text = $"SCORE: {score}";
}
void GameEndCheck()
{
if (time > 0)
{
time -= Time.deltaTime;
timeText.text = $"TIME: {Math.Floor(time)}";
}
else
{
timeText.text = "TIME: 0";
}
}
}
各食べ物のオブジェクトの設定
- 各食べ物のオブジェクトに対して回転させたり点数を設定できるようにします
- 食べ物のオブジェクトを
Ctrl + A
で全て選択している状態で以下のScale
を設定します-
Scale
X:15 Y:15 Z:15
-
-
Rigidbody
とSphereCollider
を設定します -
Fruits
というタグを設定します -
Fruit
のスクリプトをAdd Component
で追加します - スクリプトの
score
でそれぞれに個別の点数を設定することができます
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Fruit : MonoBehaviour
{
public int score = 1;
float rotateSpeed = 1.0f;
void Update()
{
transform.Rotate(new Vector3(0, rotateSpeed, 0), Space.Self);
}
}
食べ物を繰り返し生成する
- 先ほど作成した
GameControl
に以下のスクリプトを作成してアタッチします - スクリプトの
Fruits
は配列なので任意の数を設定してください - それぞれの
Element
にFREE Food Pack
のPrefab
をアタッチします - カメラの周囲(水平の円状)に食べ物のオブジェクトが生成されます
-
Unity
で動作させているときのみキーボードのスペースキーで食べ物を生成できます
using System.Collections;
using UnityEngine;
public class FruitsGenerater : MonoBehaviour
{
public GameObject[] fruits;
void Start()
{
StartCoroutine("CoroutineFruitsGenarate");
}
# if UNITY_EDITOR
void Update()
{
if (Input.GetKey(KeyCode.Space))
{
GenerateFruit();
}
}
# endif
private Vector3 RandHorizonCircleVec3(
float aMin = 0,
float aMax = 180,
float rMin = 5,
float rMax = 5,
float yHeight = 1
)
{
var angle = Random.Range(aMin, aMax);
var radius = Random.Range(rMin, rMax);
var rad = angle * Mathf.Deg2Rad;
var px = Mathf.Cos(rad) * radius;
var pz = Mathf.Sin(rad) * radius;
return new Vector3(px, yHeight, pz);
}
private void GenerateFruit()
{
int enemyRnd = Random.Range(0, fruits.Length);
GameObject fruit = Instantiate(
fruits[enemyRnd],
// RandHorizonCircleVec3(60, 100, 10, 10, 5),
RandHorizonCircleVec3(50, 110, 10, 10, 5),
Quaternion.identity
);
Destroy(fruit, 4f);
}
IEnumerator CoroutineFruitsGenarate()
{
while (true && GameManager.time > 0)
{
GenerateFruit();
yield return new WaitForSeconds(1);
}
}
}
カメラを親にしてボウルを操作できるようにする
- 以下の
Bowl.000
のオブジェクトを使用します
- MainCameraの子にして
Bowl
にリネームします -
Bowl
の位置とスケールを調整します-
Position
X:0 Y:-5 Z:-10 -
Scale
X:50 Y:60 Z:50
-
ボウルの中で食べ物をキャッチして点数を加算する
- ボウルの
Sphere
という球形のオブジェクトを作成します -
Sphere
の位置を調整します-
Position
X:0 Y:0.01 Z:0 -
Scale
X:0.005 Y:0.005 Z:0.005
-
-
Sphere
に落ちてくる食べ物が接触することで点数が加算されます -
Sphere
を作ることでボウルの中に入らないと点数が入らないようになります
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public GameObject catchVFX;
void OnCollisionEnter(Collision col)
{
if (col.gameObject.tag == "Fruits") {
GameManager.score += col.gameObject.GetComponent<Fruit>().score;
GameObject tempVfx = Instantiate(
catchVFX,
new Vector3(
col.gameObject.transform.position.x,
col.gameObject.transform.position.y,
col.gameObject.transform.position.z
),
catchVFX.transform.rotation
);
Destroy(tempVfx, 0.3f);
Destroy(col.gameObject);
}
}
}
キャッチしたときのパーティクルの設定をする
-
EffectTexturesAndPrefabs
のパーティクルの大きさを調整します-
Scale
X:5 Y:5 Z:5 - 親ではなく子のパーティクル2つのスケールを変更します
-
-
Sphere
にパーティクルのPrefab
をアタッチします
WebVR化する
作成したシーンの複製(シーンのバックアップ)
- 別のシーンファイルでWebVR化していきます
- シーンファイルを選択して
Ctrl + D
で複製できます - 複製したシーンファイルはWebVR用とわかるよう名前を変更しておきます
WebVRのパッケージをインストールしサンプルのシーンの追加
- 以下の記事に手順が記載されています
- パッケージの追加から各種設定
- サンプルシーンの追加
サンプルシーンからWebXRCameraSetのコピー
-
WebXRCameraSet
をCtrl + C
でコピーします
WebVR化するシーンにWebXRCameraSetの貼り付けて設定する
- 先ほど複製したWebVR化のシーンを開きます
- 開いて
Hierarchy
でCtrl + V
でコピーしたWebXRCameraSet
を貼り付けます - 貼り付けた後は元からある
MainCamera
は無効にしておきます -
MainCamera
からBowl
をコピーして同じ構造でWebXRCameraSet
のCameraFollower
の子にしますWebXRCameraSet/Cameras/CameraFollower/Bowl/Sphere
WebVRとしてビルドする
-
Build Settings
で複製したシーンを追加してビルドします- 元からあるシーンは削除します
- ビルドでできたファイルをウェブサーバーにアップロードすると
WebVR
として遊べます
ふりかえり
- シューティング以外にも一視点型のゲームができました
-
WebVR
となるとコントローラーの採用が難しいのでカメラで操作させるゲーム性がよさそうです - 制限がありそうですが制限があるうえでいろいろなゲーム性を考えられると思います
- 実際に作ったモノで
CameraFollower
の子にしないと動作しないのでアセらず設定しましょう