UnityでVRガンシューティングを作ろう

UnityでVRガンシューティングを作成します
スマホのジャイロセンサーを利用して、ゴーグルを下に向けたら歩く、上に向けたら弾を発射するようにします

Unityのヴァージョンは2018.3.5f1で作成しています
こちらに完成プロジェクトも公開していますので、上手くいかなかった場合には参考にしてください

目次

今回やること

UnityRemoteのダウンロードと設定


PCとスマホを接続してお手軽にVRを楽しむにはUnityRemoteというアプリが必要です
UnityRemoteはPCと接続してUnityでテストプレイすると画面をスマホに写してくれます
設定のやり方についてはこちらを参考にしてください

下準備

こちらのUnityパッケージをダウンロードして下さい

パッケージのインポートの仕方はこちらを参考にしてください

画面のアスペクト比を使うディバイスに合わせます
例えば、iPhone5~8とかは16:9です

MainCameraを消します

Assets→Dive→PrefabsにあるDive_Cameraをドラッグ&ドロップ

こちらを参考にC#スクリプトを作成し、GyroScriptという名前にして以下の内容を入力します

using UnityEngine;
using System.Collections;
 
public class GyroScript : MonoBehaviour {
 
	Quaternion currentGyro;
 
	void Start(){
		Input.gyro.enabled = true;
	}
 
	void Update () {
		currentGyro = Input.gyro.attitude;
		this.transform.localRotation = 
			Quaternion.Euler(90, 90, 0) * ( new Quaternion (-currentGyro.x, -currentGyro.y, currentGyro.z, currentGyro.w)); 
	}
}

作成したらDive_Cameraにドラッグ&ドロップします

Dive_Cameraを選択し、貼り付けたスクリプトのPlayerにドラッグ&ドロップします

Dive_CameraにCharacterControllerをつけます

テストプレイをする → ①(DiveMouseLook)にチェック、②(GyroScript)のチェックを外す
※マウスで操作ができます
実際にスマホでプレイする → ②(GyroScript)にチェック、①(DiveMouseLook)のチェックを外す
※スマホで操作ができます

プレイヤーの移動

C#スクリプトを作成し、Playerという名前にして以下の内容を入力します

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
	public float MoveSpeed  = 2.0f;//移動スピードの変数
	public float moveAngleX = 0.0f;//移動するようになる角度
	public GameObject player;//playerの情報を取得するための変数
	private CharacterController characterController;//CharacterControllerを使用するための変数
	
	// Update is called once per frame
	void Start()
	{
		characterController = GetComponent<charactercontroller>();//CharacterControllerを取得し,characterControllerに代入する
	}

	void Update()
    {
		float x = player.transform.eulerAngles.x;//プレイヤーの向きを取得する

		if (moveAngleX < x && x < 60.0f) {//プレイヤーの向きがmoveAngleXより大きく60度より小さい時,
			characterController.Move (this.gameObject.transform.forward * MoveSpeed * Time.deltaTime);//向いている方向にMoveSpeed*Time.deltaTime分進む
		}
	}	
}
</charactercontroller></pre>
<!-- /wp:preformatted -->

作成したらこちらもDive_Cameraにドラッグ&ドロップします

ステージの作成


ステージの作成についてはこちらにまとめてありますので参考にして進めて下さい

敵キャラの作成


敵キャラの作成についてはこちらにまとめてありますので参考にして進めて下さい

作成しない場合、こちらを参考にして素材を入れましょう

プレイヤーの攻撃

Playerが上を向いているときに攻撃するようにします
作成したPlayerスクリプトに追加して書いていきましょう

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
	public float MoveSpeed  = 2.0f;
	public float moveAngleX = 0.0f;
	public GameObject player;
	private CharacterController characterController;
	public GameObject bullet;//飛ばす弾の情報を取得するための変数 
	private float BulletSpeed = 1000;//飛ばす弾のスピードの変数
	public float attackAngleX = 300.0f;//攻撃できる角度

	// Update is called once per frame
	void Start()
	{
		characterController = GetComponent<charactercontroller>();
	}

	void Update()
    {
		float x = player.transform.eulerAngles.x;

		if (moveAngleX < x && x < 60.0f) {
			characterController.Move (this.gameObject.transform.forward * MoveSpeed * Time.deltaTime);
		}

		if (attackAngleX < x && x < 340.0f) {//プレイヤーの向きがattackAngleXより大きく340度より小さい時,
			Attack ();//Attackを実行する
		}
	}
	    
	private void Attack()//Attackを定義する 
	{
		Vector3 force;//弾を飛ばす力
		GameObject bullets = GameObject.Instantiate(bullet) as GameObject;//生成されたbulletのクローンをbulletsとする
		bullets.transform.position = player.transform.position;//bulletsをプレイヤーの場所にする
		force = player.transform.forward * BulletSpeed;//forceをプレイヤーの前方にBulletSpeedとする
		bullets.GetComponent<rigidbody>().AddForce(force);//bulletsのRigidBodyを取得し、Force分力をかける
		Destroy(bullets.gameObject,2); //bulletsを2秒後に削除する
	}
}

弾の作成

まずは、弾にするSphereを出します
Create → 3DObject → Sphereを選択します

isTriggerにチェックを入れます

Rigidbodyをつけます
AddComponent → 検索欄に「Ri」と入力 → RigidBodyを選択します

RigidbodyのUse Gravityのチェックをはずします

タグをつけます
Untagged → AddTagをおして、

「+」をおして、タグ名を「bullet」と入力し、Saveをおします

Sphereを選択した状態で、Untagged → bulletを選択します

プレファブにします
設定を終えたSphereをAssets内にドラッグ&ドロップします

Dive_Cameraを選択して、Dive_CameraをPlayerに、作成したプレファブをbulletにドラッグ&ドロップします

敵の動き


こちらを参考に作成して下さい

敵の設定

敵キャラを選択し、AddComponentをおし、CapsuleColliderを2つとRigidBodyをいれます

①当たり判定の位置
②当たり判定の半径と高さ
③チェックをつける
④当たり判定の位置
⑤当たり判定の半径と高さ

  • ①②④⑤を調整して敵キャラを包むように設定
  • ①と④、②と⑤は同じ値にする
  • ③はチェックをつけるとすり抜けるようになる。これは地面の判定とダメージ用の判定を分けています

RigidBodyの設定

画像のようにチェックを入れます
これによって衝突した時に移動したり回転したりしなくなります

敵のダメージ処理

Enemyスクリプトに追記します

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class Enemy : MonoBehaviour
{
	public GameObject target;
	private NavMeshAgent agent;
	public GameObject Explosion;//敵を倒したときに表示する爆発

	// Start is called before the first frame update
    void Start()
    {
		agent = GetComponent<navmeshagent>();
	}

    // Update is called once per frame
    void Update()
    {
		agent.destination = target.transform.position;
	}

	void OnTriggerEnter (Collider col)//衝突した時の動作は
	{
		if(col.gameObject.tag == "bullet")//もし衝突したもののタグがbulletなら
		{
			Instantiate(Explosion.gameObject, this.transform.position, Quaternion.identity);//このオブジェクトの場所に、回転させずに爆発のクローンをつくる
			Destroy(this.gameObject);//このオブジェクトを消す
		}
	}
}

爆発エフェクトをExplosionにドラッグ&ドロップします
※爆発エフェクトはこちらを参考にダウンロードしてください

ゲームクリアの作成

表示する文字の作り方はこちらを参考にしてください

Playerスクリプトに追記していきます

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
	public float MoveSpeed  = 2.0f;
	public float moveAngleX = 0.0f;
	public GameObject player;
	private CharacterController characterController;
	public GameObject bullet;
	private float BulletSpeed = 1000;
	public float attackAngleX = 300.0f;
	private GameObject[] enemyObjects;//敵の数をはかるための配列
	public GameObject ClearText1;//左側のカメラに表示するクリアの文字
	public GameObject ClearText2;//右側のカメラに表示するクリアの文字

	// Update is called once per frame
	void Start()
	{
		characterController = GetComponent<charactercontroller>();
		ClearText1.SetActive(false);//ClearText1を非表示にする
		ClearText2.SetActive(false);//ClearText2を非表示にする
	}

	void Update()
    {
		float x = player.transform.eulerAngles.x;

		if (moveAngleX < x && x < 60.0f) {
			characterController.Move (this.gameObject.transform.forward * MoveSpeed * Time.deltaTime);
		}

		if (attackAngleX < x && x < 340.0f) {
			Attack ();
		}

		enemyObjects = GameObject.FindGameObjectsWithTag("Enemy");//enemyObjectsはEnemyのタグがついているオブジェクトとする

		if (enemyObjects.Length == 0)//もし,enemyObjectsの数が0になったら,
		{
			ClearText1.SetActive(true);//クリアの文字を表示する
			ClearText2.SetActive(true);//クリアの文字を表示する
		}
	}
	    
	private void Attack()
	{
		Vector3 force;
		GameObject bullets = GameObject.Instantiate(bullet) as GameObject;
		bullets.transform.position = player.transform.position;
		force = player.transform.forward * BulletSpeed;
		bullets.GetComponent<rigidbody>().AddForce(force);
		Destroy(bullets.gameObject,2); 
	}
}

Clearの文字を2つドラッグ&ドロップします

以上で終わりです
お疲れ様です♪

おまけ:作成したゲームを動画にする


こちらを参考にやってみてください

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

目次