【Unityの練習ゲーム作り 第二弾!】
大人気アプリ モンスト風のゲームを、Unityの練習で作ってみます。
その1 大まかな設計を考えました
今回は、自キャラの動きを作ってみます。
自キャラの動き
モンストをプレイしたことがある方はご存知の通り、モンストで自キャラは以下のように動きます。
- 指を離すと、引張方向とは反対方向に動きだす
- 指を離すタイミングで初速が変わる
- 敵キャラや壁に反射する
- 敵キャラ,壁に当たる、ステージ移動で徐々にスピードが減速する
ボタンを離すと動き出す処理
壁と自キャラにRigidbody 2DとCircle Colliderを付けます。
自キャラの動きをコントロールするスクリプトに、「ボタンを押すと動き出す処理」を、以下のように書きました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CharacterController : MonoBehaviour { Rigidbody2D rigid2d; private float speed; void Start () { this.rigid2d = GetComponent<Rigidbody2D>(); } void Update () { // Spaceキーを離すと動き出す if(Input.GetKeyUp(KeyCode.Space)) { this.speed = 100.0f; this.rigid2d.AddForce(transform.up * speed); } } } |
反射,減速する処理
壁,(今はまだないですが)敵キャラに衝突したときの反射は、Collider2DのMaterialに Physics2D Materialを追加で実現します。
これで衝突時に、オブジェクトが反射するようになりました。
移動中の減速は、スクリプトに記載します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CharacterController : MonoBehaviour { Rigidbody2D rigid2d; private float speed; void Start () { this.rigid2d = GetComponent<Rigidbody2D>(); this.speed = 0; } void Update () { // Spaceキーを離すと動き出す if(Input.GetKeyUp(KeyCode.Space)) { this.speed = 100.0f; this.rigid2d.AddForce(transform.up * speed); //Debug.Log("speed"); } } void FixedUpdate(){ this.rigid2d.velocity *= 0.995f; } } |
引張りと反対方向に動き出す
マウスでボタンを押し始めた座標 ⇨ ボタンを離した座標 の逆ベクトルで実現できそうです。
押した座標と離した座標を取得し、両者のベクトルを求め、さらに正規化と-1 しています。スクリプトでは (離した座標 – 押した座標)に-1を掛けることで逆ベクトルを求めていますが、(押した座標 – 離した座標)でも良いですね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CharacterController : MonoBehaviour { Rigidbody2D rigid2d; Vector2 startPos; private float speed; void Start () { this.rigid2d = GetComponent<Rigidbody2D>(); this.speed = 100; } void Update () { // マウスの動きと反対方向に発射される if (Input.GetMouseButtonDown(0)){ this.startPos = Input.mousePosition; } else if (Input.GetMouseButtonUp(0)){ Vector2 endPos = Input.mousePosition; Vector2 startDirection = -1*(endPos - startPos).normalized; this.rigid2d.AddForce(startDirection * speed); } // テスト用:スペースキー押下で停止 if(Input.GetKeyDown(KeyCode.Space)) { this.rigid2d.velocity *= 0; } // Spaceキーを離すと動き出す //if(Input.GetKeyUp(KeyCode.Space)) { // // this.speed = 100.0f; // this.rigid2d.AddForce(transform.up * speed); //} } void FixedUpdate(){ this.rigid2d.velocity *= 0.995f; } } |
指を離すタイミングで初速を変える
最初にUIのsliderを追加します。ハンドルは不要なのでinspectorから削除しました。
マウスを押している間は、スライダーが動作するようプログラムを修正します。
bool変数shotGaugeSet
を使用し、マウス押下時はshotGaugeValue
関数を呼び出すようにしました。
マウスを離した時、bool変数をFalseに戻すのと、using UnityEngine.
UI
を忘れずに。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class CharacterController : MonoBehaviour { Rigidbody2D rigid2d; Vector2 startPos; public Slider shotGauge; float speed=0; float gaugeLength=0; bool shotGaugeSet = false; void Start () { this.rigid2d = GetComponent<Rigidbody2D>(); } void Update () { // マウスを押した地点の座標を記録 if (Input.GetMouseButtonDown(0)){ this.startPos = Input.mousePosition; shotGaugeSet = true; } // マウスを離した地点の座標から、発射方向を計算 if (Input.GetMouseButtonUp(0)){ Vector2 endPos = Input.mousePosition; Vector2 startDirection = -1*(endPos - startPos).normalized; this.rigid2d.AddForce(startDirection * speed); shotGaugeSet = false; Debug.Log(speed); } // マウスが押されている間 ショットゲージを呼ぶ if (shotGaugeSet){ shotGaugeValue(); } // テスト用:スペースキー押下で停止 if(Input.GetKeyDown(KeyCode.Space)) { this.rigid2d.velocity *= 0; } } void FixedUpdate(){ this.rigid2d.velocity *= 0.995f; } // ショットゲージ関数 void shotGaugeValue(){ Debug.Log("呼び出し確認"); } } |
あとは、スライダーの表示が変化するよう、shotGaugeValue
関数に追記していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// ショットゲージ関数 void shotGaugeValue(){ gaugeLength += 0.025f; //ゲージがMaxでゼロに戻る if(gaugeLength> 1.025f){ gaugeLength = 0; } //ゲージ長さをlengthに代入 shotGauge.value = gaugeLength; // スピードをゲージ値から計算 speed = gaugeLength * 1000f + 500f; } |
6行目で gaugeLength> 1.025f としています。
UI表示上、Max状態から0にすぐに切り替わってしまうと、ゲームプレイに不合理感が出ると判断したためです。Max状態で少し猶予が発生するようにしました。
ゲージ値によって、初速度を変えることができました!
今回はここまで。
次回は敵キャラを追加していきます。