そういえば最近ちょこちょこ作ってたゲームはもう完成したの?
ステージをもういくつか追加したらリリースしようかなってトコまではできてるよ。びっくりするくらい簡単に作れたから、簡単に作り方を紹介するね。
Unity製3Dアクションゲーム完成イメージ
今回制作したゲームは、以下の動画のように、サルのキャラクターが、斧をもってくるくる回りながら、木やら敵やらをぶっ飛ばしていくゲームです。
自分でもびっくりするほど簡単に作れてしまったので、「挑戦してみたいけど難しそう 」と二の足を踏んでいる方のために、作り方を紹介していきます。
もうリリースしても良いレベルでは? pic.twitter.com/lh5yErsuMT
— 嗚呼蛙@マンガ描き (@aaafrog) 2020年11月5日
動画見ても難しくて無理ー!という方は、簡単なところから触っていくやり方の記事も書いているので、こちらを見てみてください。
Unity製3Dアクションゲームをとりあえず動くところまで作る
ゲームと言うと大抵の場合、スタート画面があって、ステージ選択や、オプション設定などが行えるようになっていますか、そういう細かいところは意外と面倒くさい上に、作っていてあまり面白くないので、最初は実際のプレイ画面から作っていくことがおすすめです。
今回は、キャラクターが移動して、敵を攻撃できるようにするところまでやっていきます。Unityのインストールとプロジェクト作成の方法は、ここでは紹介しないので、ググってください。
また、テキストではざっくりと手順を紹介するに留めるので、詳細は動画の方を見てくださいね。
ステージとキャラクターを配置、操作できるようにする
UnityのHierarchyウインドウにPlaneを追加して地面を作り、Unityアセットストアからお好きな人型の3Dモデルをダウンロード&追加をして、キャラクターを作りましょう。アニメーションや武器も、Unityアセットストアからダウンロードしてアタッチすれば、よりそれらしくなります。
そしてキャラクターを操作するスクリプトを作成して、キャラクターにアタッチしましょう。これだけでとりあえず動くようにはなります。
以下は、以前作った脱出ゲームに使用していた借り物のスクリプトです。どこからお借りしたか思い出せないため、ご紹介できず申し訳ない。
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using UnityEngine.SceneManagement; public class PlayerManager : MonoBehaviour { private CharacterController controller; private Vector3 moveDirection = Vector3.zero; private float horizontalInput, verticalInput; [SerializeField] private float speed = 3.0f; // 歩行速度 [SerializeField] private float jumpSpeed = 8.0F; // ジャンプ力 [SerializeField] private float gravity = 9.8f; // 重力 [SerializeField] private float rotateSpeed = 3.0F; // 回転速度 void Start() { controller = GetComponent<CharacterController>(); } void Update() { horizontalInput = Input.GetAxis("Horizontal"); //左右矢印キーの値(-1.0~1.0) verticalInput = Input.GetAxis("Vertical"); //上下矢印キーの値(-1.0~1.0) if (controller.isGrounded) { gameObject.transform.Rotate(new Vector3(0, rotateSpeed * horizontalInput, 0)); moveDirection = speed * verticalInput * gameObject.transform.forward; if (Input.GetButton("Jump")) moveDirection.y = jumpSpeed; } moveDirection.y -= gravity * Time.deltaTime; controller.Move(moveDirection * Time.deltaTime); } public void DoorClick() { Debug.Log("DoorClick"); SceneManager.LoadScene("test"); } }
キャラクターを回転させるスクリプトを作成
今回作成するゲームはキャラクターが自動でぐるぐる回転するため、そのためのスクリプトを書いて、キャラクターにアタッチします。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Rotate : MonoBehaviour { void Update() { transform.Rotate(new Vector3(0, -5, 0)); } }
移動方法をマウスポインタの追従に変更
このゲームは方向キーではなく、クリック中のマウスポインタ、または、タップ中の指を追いかけるような動きにしたいため、キャラクター操作に変更を加えます。
まず、Planeのオブジェクトを選択し、InspectorのStaticにチェックを入れます。
次に、メニューバーのWindow>AI>Navigationを選択し、Inspectorの隣に表示されたNavigationのBakeを選択し、Bakeボタンをクリックします。
そして、キャラクターのオブジェクトを選択し、InspectorのAddComponentから、NavMeshAgentをアタッチします。
スクリプトも変更しないといけないため、キャラクター操作のスクリプトを以下の内容に変更します。借り物を張り合わせて作ったものです。
下の方にあるアニメーションイベント用のメソッドは、使用しているアニメーションがメソッドを呼び出そうとするので、無いとエラーが発生するため、記述しています。
実行してみると、クリック中のマウスポインタを追いかける動きに変わっていることがわかると思います。
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using UnityEngine.SceneManagement; public class PlayerManager : MonoBehaviour { UnityEngine.AI.NavMeshAgent agent; RaycastHit hit; Ray ray; void Start() { agent = GetComponent<UnityEngine.AI.NavMeshAgent>(); } void Update() { if (Input.GetMouseButton(0)) { agent.isStopped = false; ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out hit, 100f)) { agent.SetDestination(hit.point); } } if (Input.GetMouseButtonUp(0)) { agent.isStopped = true; } } // アニメーションイベント用(ないとエラーが出る) public void Run() { } public void Hit() { } public void FootR() { } }
敵オブジェクトと当たり判定の設置
キャラクターが動くようになったら次は敵を作ります。
キャラクターを配置したときと同じように、適当な3Dモデルを配置しましょう。
配置したら、敵のオブジェクトと、武器のオブジェクトにColliderをアタッチします。Colliderの種類は複数ありますが、敵や武器の形状に合うものを選択してください。たいていの場合は、BoxColliderか、CapsuleColliderで大丈夫です。
物理的な動きを加えてくれるRigidbodyも、一緒にアタッチしましょう。
実行すると、敵と武器がぶつかるようになります。
倒した敵オブジェクトを消す
倒された敵がいつまでも画面上にいたら邪魔なので、衝突した後は潔く消えるように、スクリプトを追加します。
武器のオブジェクトを選択して、InspectorのTagにWeaponを作成し、選択します。
以下のスクリプトを作成して、敵のオブジェクトにアタッチすると、当たって1秒で消えるようになります。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class AxeHitManager : MonoBehaviour { private void OnCollisionEnter(Collision collision) { if (collision.gameObject.CompareTag("Weapon")) { Destroy(this.gameObject, 1.0f); } } }
カメラをキャラクターに追従させる
今のままだと、キャラクターがカメラの外に出てしまう可能性があるので、カメラがキャラクターを追いかけるようにスクリプトを追加します。
以下のスクリプトを作成し、MainCameraオブジェクトにアタッチし、アタッチしたスクリプト内のTargetの部分に、キャラクターのオブジェクトをアタッチします。
実行すると、カメラがついてくるようになっているのがわかると思います。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CameraManager : MonoBehaviour { public GameObject target; private Vector3 distance; void Start() { distance = transform.position - target.transform.position; } void LateUpdate() { transform.position = target.transform.position + distance; } }
いかがでしょう?少ない労力の割りに、なかなかゲームっぽいものができていると思いませんか?
あとは敵を増やしていけば、どんどこ敵を倒していくゲームになります。武器を大きくすれば、一遍にたくさんの敵を倒すこともできますよ!
ぜひやってみてくださいね!
ちなみに、このゲームの作成に使用している素材は、すべてUnityアセットストアから無料でダウンロードしたものを使っています。アセットストアの使い方は以下で解説しているので、アセットストアってなに?という方はこちらも合わせて見てみてくださいね。
意外と簡単でしょ?
いや!なに書いてるかわかんないレベルで難しいよ!!
まぁ、プログラム齧ってないと「うっ」ってなるかもだけど、動画を見ての通り、必要なものをペタペタ張ってくだけだから、慣れればすごく簡単なんだよ。
慣れるまでが大変なんじゃ……
いや、いじってれば慣れるから、そこは大丈夫。動くコードを見つけたり、バグを解消する方が大変かな。