Unity

UnityでフォートナイトみたいなTPSを作るチュートリアル

投稿日:2019年3月1日 更新日:

今回つくるもの
こんな感じのTPSを作ります

今回やること
  • ステージの作成
  • プレイヤーの設定
  • プレイヤーの移動
  • アニメーターの設定
  • 敵を倒せるようにする
  • 敵の作成
ステージの作成

こちらにまとめておきましたので参考にして下さい

プレイヤーの設定

こちらで作成したモデルを入れていきます

Unityの細かな操作方法、設定等は漫画にまとめておきましたので、操作が分からなかった場合は参考にして下さい

素材を作るの面倒くさいよーって人はこちらにまとめておいたのでダウンロードしてからインポートして下さい
プレイヤー以外にも銃、照準も入れてありますのでそれらを使いたい場合もダウンロードして下さい

インポートしたら、待機アニメーションと銃をドラッグ&ドロップします

プレイヤーを選択し、AddComponentをおして、CharacterControllerとCapsuleColliderを取り付け、数値を設定してちょうどいいように合わせます

MainCameraをプレイヤーに、銃をプレイヤーのLeftHandにドラッグ&ドロップします

銃をちょうどいい位置、向き、大きさに合わせます

カメラもちょうど良い位置に合わせます

プレイヤーの移動

プレイヤーが移動するようにプログラミングしていきます
今回はマウスの移動で視点切り替え、WASDで前後左右の移動をできるようにします

Playerというスクリプトを作成して以下を入力していきます

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

public class Player : MonoBehaviour {

	private CharacterController characterController;//①CharacterController型の変数
	private Vector3 Velocity;//①キャラクターコントローラーを動かすためのVector3型の変数
	public float JumpPower;//①ジャンプ力
	public Transform verRot;//①縦の視点移動の変数(カメラに合わせる)
	public Transform horRot;//①横の視点移動の変数(プレイヤーに合わせる)
	public float MoveSpeed;//①移動速度

	// Use this for initialization
	void Start () {
		characterController = GetComponent  ();//①CharacterControllerを変数に代入
	}

	// Update is called once per frame
	void Update ()
	{
		float X_Rotation = Input.GetAxis ("Mouse X");//①X_RotationにマウスのX軸の動きを代入する
		float Y_Rotation = Input.GetAxis ("Mouse Y");//①Y_RotationにマウスのY軸の動きを代入する
		horRot.transform.Rotate (new Vector3 (0, X_Rotation * 2, 0));//①プレイヤーのY軸の回転をX_Rotationに合わせる
		verRot.transform.Rotate (-Y_Rotation * 2, 0, 0);//①カメラのX軸の回転をY_Rotationに合わせる

		if (Input.GetKey (KeyCode.W))//①Wキーがおされたら 
		{
			characterController.Move (this.gameObject.transform.forward * MoveSpeed * Time.deltaTime);//①前方にMoveSpeed*Time.deltaTimeだけ動かす
		} 

		if (Input.GetKey (KeyCode.S))//①Sキーがおされたら
		{
			characterController.Move (this.gameObject.transform.forward * -1f * MoveSpeed * Time.deltaTime);//①後方にMoveSpeed*Time.deltaTimeだけ動かす
		} 
			
		if (Input.GetKey (KeyCode.A))//①Aキーがおされたら 
		{
			characterController.Move (this.gameObject.transform.right * -1 * MoveSpeed * Time.deltaTime);//①左にMoveSpeed*Time.deltaTimeだけ動かす
		} 
			
		if (Input.GetKey (KeyCode.D))//①Dキーがおされたら 
		{
			characterController.Move (this.gameObject.transform.right * MoveSpeed * Time.deltaTime);//①右にMoveSpeed*Time.deltaTimeだけ動かす
		}  

		characterController.Move (Velocity);//①キャラクターコントローラーをVelocityだけ動かし続ける
		Velocity.y += Physics.gravity.y * Time.deltaTime;//①Velocityのy軸を重力*Time.deltaTime分だけ動かす

		if (characterController.isGrounded)//①キャラクターコントローラーが地面に接触している時に
		{
			if (Input.GetKeyDown (KeyCode.Space))//①スペースキーがおされたら
			{
				Velocity.y = JumpPower;//①Velocity.yをJumpPowerにする
			}
		}
	}
}

 

作成し終えたらVarRotにはMainCamera、HorRotにはプレイヤーをドラッグ&ドロップし、JumpPower、MoveSpeedには数値の入力を行います

アニメーションをつける

こちらを参考にアニメーターの設定をしましょう
※こちらの説明だと攻撃のアニメーションも追加していますが今回は攻撃は設定しないので走るだけ設定してください
 変数もRunのみ作成で大丈夫です

続いてPlayerスクリプトに追記します
コメントを記載しているところが追記部分です

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

public class Player : MonoBehaviour {

	private CharacterController characterController;
	private Vector3 Velocity;
	public float JumpPower;
	public Transform verRot;
	public Transform horRot;
	public float MoveSpeed;
        private Animator anim;//②Animator型の変数

	// Use this for initialization
	void Start () {
		characterController = GetComponent  ();
		anim = GetComponent ();//②Animatorを変数に代入
	}

	// Update is called once per frame
	void Update ()
	{
		float X_Rotation = Input.GetAxis ("Mouse X");
		float Y_Rotation = Input.GetAxis ("Mouse Y");
		horRot.transform.Rotate (new Vector3 (0, X_Rotation * 2, 0));
		verRot.transform.Rotate (-Y_Rotation * 2, 0, 0);

		if (Input.GetKey (KeyCode.W))//
		{
			characterController.Move (this.gameObject.transform.forward * MoveSpeed * Time.deltaTime);
			anim.SetBool ("Run", true);//②アニメーターのRunをtrueにする
		} 

		else if (Input.GetKeyUp (KeyCode.W))//②Wキーがはなされたら 
		{
			anim.SetBool ("Run", false);//②アニメーターのRunをfalseにする
		}

		if (Input.GetKey (KeyCode.S))
		{
			characterController.Move (this.gameObject.transform.forward * -1f * MoveSpeed * Time.deltaTime);
			anim.SetBool ("Run", true);//②アニメーターのRunをtrueにする
		} 

		else if (Input.GetKeyUp (KeyCode.S))//②Sキーがはなされたら 
		{
			anim.SetBool ("Run", false);//②アニメーターのRunをfalseにする
		}

		if (Input.GetKey (KeyCode.A)) 
		{
			characterController.Move (this.gameObject.transform.right * -1 * MoveSpeed * Time.deltaTime);
			anim.SetBool ("Run", true);//②アニメーターのRunをtrueにする
		} 

		else if (Input.GetKeyUp (KeyCode.A))//②Aキーがはなされたら 
		{
			anim.SetBool ("Run", false);//②アニメーターのRunをfalseにする
		}

		if (Input.GetKey (KeyCode.D))
		{
			characterController.Move (this.gameObject.transform.right * MoveSpeed * Time.deltaTime);
			anim.SetBool ("Run", true);//②アニメーターのRunをtrueにする
		} 

		else if (Input.GetKeyUp (KeyCode.D))//②Dキーがはなされたら 
		{
			anim.SetBool ("Run", false);//②アニメーターのRunをfalseにする
		} 

		characterController.Move (Velocity);
		Velocity.y += Physics.gravity.y * Time.deltaTime;

		if (characterController.isGrounded)
		{
			if (Input.GetKeyDown (KeyCode.Space))
			{
				Velocity.y = JumpPower;
			}
		}
	}
}

 

敵を倒せるようにする

敵を倒すにはRayという機能を使います
RayとはUnityについてる機能のことで、透明な光線を飛ばして、色々な判定を取ることができます

照準になる画像をいれます
Create → UI → Imageをおします

PosX、PosY、PosZを0にして、○をおして照準にしたい画像を選びます
照準の画像は自分で作ってもいいですし、初めの素材のダウンロードのところにも入っています

では、再びPlayerスクリプトに追記していきます

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

public class Player : MonoBehaviour {

	private CharacterController characterController;
	private Vector3 Velocity;
	public float JumpPower;
	public Transform verRot;
	public Transform horRot;
	public float MoveSpeed;
	private Animator anim;
	private Ray ray;//③Ray型の変数
	public GameObject Explosion;//③敵を倒した時に出現させる爆発
	private int distance = 10000;//③Rayを飛ばす距離
	private RaycastHit hit;//③Rayが何かに当たった時の情報
	public GameObject Muzzle;//③Rayを発射する場所

	// Use this for initialization
	void Start () {
		characterController = GetComponent  ();
		anim = GetComponent ();
	}

	// Update is called once per frame
	void Update ()
	{
		float X_Rotation = Input.GetAxis ("Mouse X");
		float Y_Rotation = Input.GetAxis ("Mouse Y");
		horRot.transform.Rotate (new Vector3 (0, X_Rotation * 2, 0));
		verRot.transform.Rotate (-Y_Rotation * 2, 0, 0);

		if (Input.GetKey (KeyCode.W))
		{
			characterController.Move (this.gameObject.transform.forward * MoveSpeed * Time.deltaTime);
			anim.SetBool ("Run", true);
		} 

		else if (Input.GetKeyUp (KeyCode.W)) 
		{
			anim.SetBool ("Run", false);
		}

		if (Input.GetKey (KeyCode.S))
		{
			characterController.Move (this.gameObject.transform.forward * -1f * MoveSpeed * Time.deltaTime);
			anim.SetBool ("Run", true);
		} 

		else if (Input.GetKeyUp (KeyCode.S)) 
		{
			anim.SetBool ("Run", false);
		}

		if (Input.GetKey (KeyCode.A)) 
		{
			anim.SetBool ("Run", true);
			characterController.Move (this.gameObject.transform.right * -1 * MoveSpeed * Time.deltaTime);
		} 

		else if (Input.GetKeyUp (KeyCode.A))
		{
			anim.SetBool ("Run", false);
		}

		if (Input.GetKey (KeyCode.D)) 
		{
			anim.SetBool ("Run", true);
			characterController.Move (this.gameObject.transform.right * MoveSpeed * Time.deltaTime);
		} 

		else if (Input.GetKeyUp (KeyCode.D))
		{
			anim.SetBool ("Run", false);
		} 

		characterController.Move (Velocity);
		Velocity.y += Physics.gravity.y * Time.deltaTime;

		if (characterController.isGrounded)
		{
			if (Input.GetKeyDown (KeyCode.Space))
			{
				Velocity.y = JumpPower;
			}
		}

		if (Input.GetMouseButton(0))//③マウスが左クリックされたら 
		{
			Ray ray = new Ray(Muzzle.transform.position, Muzzle.transform.forward);//③RayをMuzzleの場所から前方に飛ばす
			Debug.DrawRay(ray.origin, ray.direction, Color.red);//③Rayを赤色で表示させる

			if (Physics.Raycast (ray, out hit, distance)) {//③Rayがdistanceの範囲内で何かに当たった時に

				if (hit.collider.tag == "Enemy")//③もし当たった物のタグがEnemyだったら 
				{
					Destroy (hit.collider.gameObject);//③当たった物を消去して、
					Instantiate (Explosion.gameObject, hit.collider.gameObject.transform.position, gameObject.transform.rotation);//③Rayが当たった場所に爆発を生成する
				}
			}
		}
	}
}

 

入力し終わったら爆発エフェクト、MainCameraをドラッグ&ドロップします
※爆発エフェクトはAssetStoreでダウンロードしておいて下さい

敵を作成する

今回はとりあえずCapsuleにしておきます(凝りたい人はプレイヤーの作成で行ったようなことをやってみて下さい)
Create → 3DObject → Capsuleをおします

動きはシンプルにプレイヤーに向かってくるようにします
新しくEnemyスクリプトを作成し、以下を入力していきます

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

public class NewBehaviourScript : MonoBehaviour
{
	public GameObject target;//敵がついていくターゲット

    // Update is called once per frame
    void Update()
    {
		transform.LookAt (target.transform);//ターゲットの方を向く
		transform.position += transform.forward * 10f * Time.deltaTime;//向いている方向に進む
    }
}

 

入力してスクリプトをCapsuleにつけてTargetの部分にプレイヤーをドラッグ&ドロップします

敵にEnemyというタグをつけます
敵を選択し、Untagged → AddTagをおします

Enemyと入力し、Saveをおします

作成した敵は複製して色々な場所に配置しましょう
また、こちらのスクリプトを敵に入力すれば、徘徊したり、近づいたら向かってくるなど、簡易的なAIが作れます

ゲームクリアをつくる

Create → UI → Textをおします

画像のように調整します

敵を全員倒すとClearの文字が表示されるようにPlayerスクリプトに追記していきます

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

public class Player : MonoBehaviour {

	private CharacterController characterController;
	private Vector3 Velocity;
	public float JumpPower;
	public Transform verRot;
	public Transform horRot;
	public float MoveSpeed;
	private Animator anim;
	private Ray ray;
	public GameObject Explosion;
	private int distance = 10000;
	private RaycastHit hit;
	public GameObject Muzzle;
	private GameObject[] enemyObjects;//④敵の数を取得するための配列
	public GameObject Clear;//④クリア時に出現する文字

	// Use this for initialization
	void Start () {
		characterController = GetComponent  ();
		anim = GetComponent ();
		Clear.SetActive (false);//④Clearの文字を非表示にする
	}

	// Update is called once per frame
	void Update ()
	{
		float X_Rotation = Input.GetAxis ("Mouse X");
		float Y_Rotation = Input.GetAxis ("Mouse Y");
		horRot.transform.Rotate (new Vector3 (0, X_Rotation * 2, 0));
		verRot.transform.Rotate (-Y_Rotation * 2, 0, 0);

		if (Input.GetKey (KeyCode.W))
		{
			characterController.Move (this.gameObject.transform.forward * MoveSpeed * Time.deltaTime);
			anim.SetBool ("Run", true);
		} 

		else if (Input.GetKeyUp (KeyCode.W)) 
		{
			anim.SetBool ("Run", false);
		}

		if (Input.GetKey (KeyCode.S))
		{
			characterController.Move (this.gameObject.transform.forward * -1f * MoveSpeed * Time.deltaTime);
			anim.SetBool ("Run", true);
		} 

		else if (Input.GetKeyUp (KeyCode.S)) 
		{
			anim.SetBool ("Run", false);
		}

		if (Input.GetKey (KeyCode.A)) 
		{
			characterController.Move (this.gameObject.transform.right * -1 * MoveSpeed * Time.deltaTime);
			anim.SetBool ("Run", true);
		} 

		else if (Input.GetKeyUp (KeyCode.A))
		{
			anim.SetBool ("Run", false);
		}

		if (Input.GetKey (KeyCode.D))
		{
			anim.SetBool ("Run", true);
			characterController.Move (this.gameObject.transform.right * MoveSpeed * Time.deltaTime);
		} 

		else if (Input.GetKeyUp (KeyCode.D))
		{
			anim.SetBool ("Run", false);
		} 

		characterController.Move (Velocity);
		Velocity.y += Physics.gravity.y * Time.deltaTime;

		if (characterController.isGrounded)
		{

			if (Input.GetKeyDown (KeyCode.Space))
			{
				Velocity.y = JumpPower;
			}
		}

		if (Input.GetMouseButton(0)) 
		{
			Ray ray = new Ray(Muzzle.transform.position, Muzzle.transform.forward);
			Debug.DrawRay(ray.origin, ray.direction, Color.red);

			if (Physics.Raycast (ray, out hit, distance)) 
			{
				if (hit.collider.tag == "Enemy") 
				{
					Destroy (hit.collider.gameObject);
					Instantiate (Explosion.gameObject, hit.collider.gameObject.transform.position, gameObject.transform.rotation);
				}
			}
		}

		enemyObjects = GameObject.FindGameObjectsWithTag("Enemy");//④enemyObjectsにEnemyのタグがついているオブジェクトを代入する

		if (enemyObjects.Length == 0)//④もしenemyObjectsの数が0なら
		{
			Clear.SetActive (true);//④Clearを表示する
		}
	}
}

 

入力し終わったらClearの文字をドラッグ&ドロップします

テストプレイすると、WASDで走って、マウスで向きが変わり、スペースでジャンプします
クリックすると敵を倒すことができますね

以上で一応出来上がりです♪

番外編:マウスのカーソルの管理
PCでプレイをするとマウスのカーソルが表示されていたり、画面外に出たりと、邪魔くさかったりします
それを直すには以下のように追記します

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

public class Player : MonoBehaviour {

	private CharacterController characterController;
	private Vector3 Velocity;
	public float JumpPower;
	public Transform verRot;
	public Transform horRot;
	public float MoveSpeed;
	private Animator anim;
	private Ray ray;
	public GameObject Explosion;
	private int distance = 10000;
	private RaycastHit hit;
	public GameObject Muzzle;
	private GameObject[] enemyObjects;
	public GameObject Clear;
        private CursorLockMode wantedMode = CursorLockMode.None;//⑤マウスのカーソルの状態を初期化

	// Use this for initialization
	void Start () {
		characterController = GetComponent  ();
		anim = GetComponent ();
		Clear.SetActive (false);
	}

	// Update is called once per frame
	void Update ()
	{
		float X_Rotation = Input.GetAxis ("Mouse X");
		float Y_Rotation = Input.GetAxis ("Mouse Y");
		horRot.transform.Rotate (new Vector3 (0, X_Rotation * 2, 0));
		verRot.transform.Rotate (-Y_Rotation * 2, 0, 0);
                Cursor.lockState = wantedMode;//⑤マウスカーソルの状態を操作できるようにする
                Cursor.lockState = wantedMode = CursorLockMode.Confined;//⑤マウスカーソルの状態を画面内にロックする
                Cursor.visible = false;//⑤マウスのカーソルを非表示にする
		
                if (Input.GetKey (KeyCode.W))
		{
			characterController.Move (this.gameObject.transform.forward * MoveSpeed * Time.deltaTime);
			anim.SetBool ("Run", true);
		} 

		else if (Input.GetKeyUp (KeyCode.W)) 
		{
			anim.SetBool ("Run", false);
		}

		if (Input.GetKey (KeyCode.S))
		{
			characterController.Move (this.gameObject.transform.forward * -1f * MoveSpeed * Time.deltaTime);
			anim.SetBool ("Run", true);
		} 

		else if (Input.GetKeyUp (KeyCode.S)) 
		{
			anim.SetBool ("Run", false);
		}

		if (Input.GetKey (KeyCode.A)) 
		{
			characterController.Move (this.gameObject.transform.right * -1 * MoveSpeed * Time.deltaTime);
			anim.SetBool ("Run", true);
		} 

		else if (Input.GetKeyUp (KeyCode.A))
		{
			anim.SetBool ("Run", false);
		}

		if (Input.GetKey (KeyCode.D))
		{
			anim.SetBool ("Run", true);
			characterController.Move (this.gameObject.transform.right * MoveSpeed * Time.deltaTime);
		} 

		else if (Input.GetKeyUp (KeyCode.D))
		{
			anim.SetBool ("Run", false);
		} 

		characterController.Move (Velocity);
		Velocity.y += Physics.gravity.y * Time.deltaTime;

		if (characterController.isGrounded)
		{

			if (Input.GetKeyDown (KeyCode.Space))
			{
				Velocity.y = JumpPower;
			}
		}

		if (Input.GetMouseButton(0)) 
		{
			Ray ray = new Ray(Muzzle.transform.position, Muzzle.transform.forward);
			Debug.DrawRay(ray.origin, ray.direction, Color.red);

			if (Physics.Raycast (ray, out hit, distance)) 
			{
				if (hit.collider.tag == "Enemy") 
				{
					Destroy (hit.collider.gameObject);
					Instantiate (Explosion.gameObject, hit.collider.gameObject.transform.position, gameObject.transform.rotation);
				}
			}
		}

		enemyObjects = GameObject.FindGameObjectsWithTag("Enemy");//④enemyObjectsにEnemyのタグがついているオブジェクトを代入する

		if (enemyObjects.Length == 0)//④もしenemyObjectsの数が0なら
		{
			Clear.SetActive (true);//④Clearを表示する
		}
	}
}

 

ただ、こちらビルドしないと反映されません
アプリ化とかもしたい場合はこちらを追記すると良いでしょう
お疲れ様でした♪

このサイトについて

ここには、自己紹介やサイトの紹介、あるいはクレジットの類を書くと良いでしょう。

検索

このサイトについて

ここには、自己紹介やサイトの紹介、あるいはクレジットの類を書くと良いでしょう。

検索

-Unity

執筆者:


comment

メールアドレスが公開されることはありません。

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

関連記事

Unityでデータを別PCに移す

今回やること Unityで作成したデータを別のPCに移行します Unityパッケージの作成 ProjectのAssetsを選択し、左上のAssetsをおし、ExportPackageをおします 項目に …

no image

UnityでAndroidSDKとNDKのパスを通す

macの場合、Unity → Preference をおします Windowsの場合、Edit → Preference をおします ExternalToolsのそれぞれの Download ボタンを …

no image

Scratch → Unity対応表を使って迷路ゲームを作ってみよう

今回作るゲーム 今回やることの説明 こんな感じの迷路ゲームを作っていきます。 今回はキャラの移動を実装していきます。 それ以外の要素はパッケージに入っているので、 パッケージのPlayerスクリプトに …

no image

衝突判定のまとめ

入力する箇所 衝突するオブジェクトがすり抜けない場合 void OnCollisionEnter (Collision col) { if(col.gameObject.tag == “getabak …

Unityの便利機能を使いこなそう #1 Terrainでステージを作ろう

Terrainについて Terrainはゲームの地形を作るツールです 画像のような地形を簡単に作ることができます Terrainを出す Create → 3D Object → Terrainを選択し …

ゲタバコ倶楽部へようこそ

  • 318853総閲覧数:
  • 122今日の閲覧数:
  • 246610総訪問者数:
  • 107今日の訪問者数:

住所
Akita,Japan

営業時間
月~日: 10:00 AM – 10:00 PM

このページはゲタバコ先生の日々思うことや活動、プログラミングの習得方法を発信するページです。
仕事のご依頼、メッセージ等、サービス概要をご覧の上で、お気軽にご連絡ください。

getabakosensei@gmail.com