ファッションでの「重ね着」のことをレイヤードって言うよね
こんにちは!
普段からユニクロのスウェット上下姿で仕事をしているので、 たまに着替えると、デニムパンツですら変な気合が入るあらたまです!
さて、今日はUnity入門の第28回目。今回も引き続きキャラクターのジャンプを作っていきたいと思います!
おさらい
前回 では、スペースキーを押すとキャラクターがジャンプするようにしましたね。
しかし、空中でスペースキーを押すと、何度でも多段ジャンプができてしまいました。
今回は、その多段ジャンプができないように変更していきましょう!
変更の手順
まず最初に今回の手順をお伝えすると
- タイルマップに「レイヤー」を割り当てる
- キャラクターが「レイヤー」に接触しているときだけ、ジャンプ処理を有効にする
どうやら今回のポイントは「レイヤー」になりそうですね。それでは始めていきましょう!
「レイヤー」ってなに?
「レイヤー(Layer)」は単語としては「層」や「階層」という意味です。
「複数重なっているもののうちの一部」という意味ですね。 日本語では「オゾン層」とか「高層階」とかの言葉に入っています。
Unityでは「レイヤー」をゲームオブジェクト同士の重なり順を設定するのに使います。 背景よりキャラクターは前面に、キャラクターより得点数を前面に表示する、というような感じですね。
地面用の「レイヤー」を準備する
ヒエラルキーウィンドウで「Tilemap」を選択したあと、
インスペクターウィンドウで「Layer」のセレクトボックスをクリックします。
レイヤーの一覧が表示されました。
「Builtin Layer」となっているのは、Unity側であらかじめ準備されているレイヤーです。
「User Layer」が自分で自由に定義できるレイヤーです。
今回は地面用のレイヤーを作りたいので「User Layer 8」に「Ground」というレイヤー名を付けます。
タイルマップに地面用のレイヤーを割り当てる
もう一度、インスペクターウィンドウで「Layer」のセレクトボックスをクリックします。
インスペクターウィンドウで「Layer」のセレクトボックスをクリックすると
さきほど入力した「Ground」レイヤーが選択肢に表示されています!
これをクリックすると、、
タイルマップが「Ground」レイヤーに割り当てられました。
「レイヤー」に接触しているときだけ、ジャンプ処理を有効にする
つづいて地面に接地しているとき(Groundレイヤーに接触しているとき)だけ、ジャンプできるようにしていきましょう!
プロジェクトウィンドウで「Scripts」フォルダを選択し、
「CharaControl」ァイルを選択後インスペクターウィンドウで「Open」をクリックします。
スクリプトの編集画面(プログラミング画面)が表示されました!
現在のスクリプトの状態はこのようになっていますね。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharaControl : MonoBehaviour {
// キャラクターの移動スピード(インスペクターウィンドウで値を設定)
public float speed;
// Rigidbody2Dを保持するメンバ変数
private Rigidbody2D rb2d;
// ジャンプ力
public float jumpForce;
// コンポーネントの初期化処理
void Start()
{
// ゲームオブジェクトが持っているRigidbody2Dコンポーネントを
// 取得してメンバ変数に保持
rb2d = GetComponent<Rigidbody2D>();
}
private void Update()
{
if (Input.GetKeyDown("space"))
{
rb2d.AddForce(Vector2.up * jumpForce);
}
}
// 画面表示更新処理
void FixedUpdate()
{
// 横矢印キーの押されている状況を取得
float moveHorizontal = Input.GetAxis("Horizontal");
// AddForceメソッドに渡すために、Vector2型に変換
Vector2 movement = new Vector2(moveHorizontal, 0);
// AddForceメソッドでキャラクターのRigidbody2Dコンポーネントに力を加える
rb2d.AddForce(movement * speed);
}
}
ここに太字の部分を追加します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharaControl : MonoBehaviour {
// キャラクターの移動スピード(インスペクターウィンドウで値を設定)
public float speed;
// Rigidbody2Dを保持するメンバ変数
private Rigidbody2D rb2d;
// ジャンプ力
public float jumpForce;
// 地面用レイヤー
public LayerMask groundlayer;
// コンポーネントの初期化処理
void Start()
{
// ゲームオブジェクトが持っているRigidbody2Dコンポーネントを
// 取得してメンバ変数に保持
rb2d = GetComponent<Rigidbody2D>();
}
private void Update()
{
if (Input.GetKeyDown("space"))
{
bool grounded = Physics2D.Linecast(transform.position,
transform.position - transform.up,
groundlayer);
if (grounded){
rb2d.AddForce(Vector2.up * jumpForce);
}
}
}
// 画面表示更新処理
void FixedUpdate()
{
// 横矢印キーの押されている状況を取得
float moveHorizontal = Input.GetAxis("Horizontal");
// AddForceメソッドに渡すために、Vector2型に変換
Vector2 movement = new Vector2(moveHorizontal, 0);
// AddForceメソッドでキャラクターのRigidbody2Dコンポーネントに力を加える
rb2d.AddForce(movement * speed);
}
}
groundlayer
メンバ変数のgroundlayerは地面とするレイヤーを保持します。
ここに入る値は、インスペクタビューで設定します。
grounded = Physics2D.Linecast
「Physics2D.Linecast」は、第一引数と第二引数で指定された点を結ぶ直線が、 第三引数で指定されたレイヤーに接触していたらtrueを返す命令です。
第一引数の「transform.position」はスプライトの中心点です。
第二引数で使われている「transform.up」は、スプライトの中心点から上端の長さです、つまりはスプライトの高さの半分ですね。
これを「transform.position(スプライトの中心点)」から引くことにより、スプライトの下端を求めています。
第三引数にはメンバ変数「groundlayer」を指定しています。
まとめると、「スプライトの中心点から下端を結んだ直線」が「地面とするレイヤー」に接触していればtrueを変数「grounded」に入れている、ということですね。
if (grounded)
上で値を設定したgroundedがtrueであった場合のみ、ジャンプを実行しています。
メンバ変数「groundlayer」を設定する
続いて、メンバ変数「groundlayer」の値を設定します。
シーンビューでキャラクターを設定した状態で、
インスペクターウィンドウの「Groundlayer」で「Ground」を選択します。
「Groundlayer」に「Ground」が設定されました!
テストプレイで動作確認をする
それでは、テストプレイをして変化を確認してみましょう!
キャラクターが地面に接地してるときのみ、ジャンプできるようになりました!
今回はここまでです!
次回からはキャラクターにアニメーションをつけていきたいと思います。
次回へ続く。