- ステージの作成
- プレイヤーの設定
- プレイヤーの移動
- アニメーターの設定
- 敵を倒せるようにする
- 敵の作成
こちらにまとめておきましたので参考にして下さい
こちらで作成したモデルを入れていきます
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をおします
作成した敵は複製して色々な場所に配置しましょう
また、こちらのスクリプトを敵に入力すれば、徘徊したり、近づいたら向かってくるなど、簡易的なAIが作れます
敵を全員倒すと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を表示する } } }
テストプレイすると、WASDで走って、マウスで向きが変わり、スペースでジャンプします
クリックすると敵を倒すことができますね
以上で一応出来上がりです♪
それを直すには以下のように追記します
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を表示する } } }
ただ、こちらビルドしないと反映されません
アプリ化とかもしたい場合はこちらを追記すると良いでしょう
お疲れ様でした♪
コメント
コメント一覧 (3件)
[…] TPS […]
初めまして、ゲタバコ先生
私は、面白いゲームを自作できるようになりたいと、先生のサイトにたどり着きました。
今回ですが、学習中に続行不可能な箇所がありましたため、ご連絡差し上げました。
対象箇所ですが、Unitydeフォートナイトみたいなtpsを作るチュートリアル
上記のキャラクターと銃をダウンロードするファイルには、キャラクターしか入っておりませんでした。
返事だいぶ遅れてしまい、すみません
データ移行等の関係で消えてしまったようです
お手数ですがAssetStore等で好きな銃をお探しくださいませ