Unity不定期便

Unityエンジンを使って、いろいろ勉強したことをメモ代わりにまとめてます。

Unityの2D機能を使った「ジャンプ」を実装するのに最適だった方法!

f:id:masatolan:20140503143421j:plain

どうもです。

Unityの2D機能を使って、横スクロールのアクションゲームを作ろうと思い、キャラクターを「ジャンプ」させようとしていろいろ悩んだ点をメモ代わりに残しておきます。

悩む前の状態…

ひとまず、以前にダウンロードした「2Dスタートキット」から、背景などを拝借して舞台を作りました。

f:id:masatolan:20140503150826j:plain

まぁ…、道路と空があるだけですが。。。

 

キャラクターは何でもよかったんですが、「2Dスタートキット」のキャラは種類が少ないのでAsset Storeから以下のゴブリンをダウンロードしました。

Goblin Archer Cartoon Character

f:id:masatolan:20140503145024j:plain

(一応アニメーションも付属してるし、無料なので練習用にはいいかも…)

 

で、ゴブリンのPrefabsをステージにドラッグ&ドロップ!

f:id:masatolan:20140503152212j:plain

 

とりあえず、ジャンプして道路に着地してくれないと困るので、「Rigidbody 2D」と「Box Collider 2D」を追加。

f:id:masatolan:20140503152219j:plain

ついでに、道路にも「Box Collider 2D」を追加してます。

 

これで、実行すればゴブリンが道路に立つところまでは完了です。

f:id:masatolan:20140503152226j:plain

 

まず、簡単に「ジャンプ」させてみる!

 今度は、ゴブリンにスクリプトを追加して、キーボードの「スペースキー」 を押したらジャンプするようにします。

スクリプトはこんな感じ。

    function Update () {
	if(Input.GetKeyDown("space")){
		rigidbody2D.AddForce(Vector2.up * 1000);
	}
}

ゴブリンのRigidBodyに、上方向の力を加えるという単純な方法ですが、これで一応ジャンプはしてくれます。

f:id:masatolan:20140503154655j:plain

これで完成!?

 と、思ってしまいそうですが、実はこのままだと大きな欠点が残っています…。

 

ジャンプ中に、スペースキーを押すとさらにジャンプしてしまうので、あっという間に画面から消えてしまいます。

f:id:masatolan:20140503154850j:plain

つまり、正しく「ジャンプ」をさせるには、ジャンプ中にスペースキーを押しても反応しないように工夫しなければいけないわけですね。

この工夫にちょっと悩んでしまい、何か最適な方法が無いのかと調べまくった結果、Unityの2Dには非常に効率的な方法が用意されている事が分かりました。

 

Unity2Dの機能を使ってジャンプ!

冒頭で「2Dスタートキット」を利用しましたが、この中にあるキャラクターがどうやってジャンプしているのかを調べてみました。

すると、どうやら「Physics2D.Linecast」を使ってスクリプトを組んでいるみたいです。

f:id:masatolan:20140503160700j:plain

Unityのリファレンスを見ましたが、コレ…めっちゃ便利ですね!

 

簡単に説明すると、キャラクターにセットした「Collider」と「特定レイヤーにあるCollider」の当たり判定を検出してくれる機能です。

つまり、今回のケースで言えば、キャラクターが地面と接触しているかどうかを検出することが出来るわけですね。

f:id:masatolan:20140503163613j:plain

これを使えば、地面から離れている時は「スペースキー」を押しても反応しないようにプログラミング出来そうです。

真面目にプログラミングしていくと、このあたりは意外と難しいのでコレは助かります。

 

実際のプログラミングとしては、以下のように3つのポイントがあります。

f:id:masatolan:20140503171816j:plain

 ③の「レイヤー」に関しては、今回のケースで言うと「地面」となるレイヤーを指定すればOKです。

ちょっと分かりにくいのが、「開始点」と「終了点」です。

 

イメージとしては以下のような感じ…。

f:id:masatolan:20140503171826j:plain

現在の地点から、少し下方向まで線を引っ張って、この線が指定のレイヤーにあるコライダーに接触すると、返り値として「false」が得られます。

ちなみに、終了点の位置は良い感じのポイントを何度か試して導き出す必要があるかと思います。線があまりに長いと、ジャンプしていても「地面と接触し続ける」というバグが起こりやすいので注意。

 

ジャンプ中は「true」が返り値として得られるので、コレをif文と組み合わせて再度プログラミングしたのがコチラ!

var grounded : boolean = false;
var groundlayer : LayerMask;

function Update () {

	grounded = Physics2D.Linecast(transform.position,
			transform.position - transform.up * 1.2,
			groundlayer);

	if(Input.GetKeyDown("space") && grounded){
		rigidbody2D.AddForce(Vector2.up * 1000);
	}
}

 

あとは、地面に好きなレイヤーを設定して、スクリプト側のレイヤーを指定します。

f:id:masatolan:20140503174652j:plain

(一応、自キャラも区別するために別のレイヤーに設定した方が良いでしょう…)

 

これで、正しいジャンプになります!

f:id:masatolan:20140503173357j:plain

ジャンプ中に、スペースキーを押しても反応しないのが分かるかと思います。

線の長さを変えて「2段ジャンプ」できるようにする…という応用ワザも簡単にできそうですね! 

ぜひ、みなさんも挑戦してみてください〜!

 

 

Physics2D.Linecast】を使った、さらに便利な使い方はコチラ!

Unityの2Dゲームで「当たり判定」の基本を30分で理解するコツ!(後編) - Unity不定期便

 

Unityのスクリプトが丁寧に解説されている書籍!
Unity4ゲームコーディング 本当にゲームが作れるスクリプトの書き方

Unity4ゲームコーディング 本当にゲームが作れるスクリプトの書き方