こんにちは!布浦です。
Unityの2D機能をつかう企画、5回目です。
今日は、
「5. 地面に当たったかどうかを判定する(Physics2Dスクリプト編その1)」
をやっていきたいと思います。
- 画像をSpriteとして画面に配置する
- Spriteにコマアニメを設定する(Animation View の使い方)
- 複数のアニメを切り替える仕組みをつくる(Mecanim)
- 2D物理エンジンでキャラクターを動かす(Physics2D設定編)
- 地面に当たったかどうかを判定する(Physics2Dスクリプト編その1)
- キー操作によるキャラクターの移動を実装する(Physics2Dスクリプト編その2)
地面に足がついているかを判定する仕組み
UnityのPhysicsクラスは、当たり判定を動的に便利な関数が揃っています。
使うのは、「Physics2D.Linecast」という関数です。
Physics2D.Linecastは、指定した2つの座標の間に線を引くイメージで、この線上にColliderが貼られたGameObjectがある場合trueを返してくれます。
この関数を利用して、キャラクターの足下付近に地面があるかどうかを調べます。
前々回、「キャラクターが地面に足がついているかどうか」を条件に、アニメーションを切り替える準備をしました。
前回、キャラクターに物理演算を適用して、重力で下に落ちるようにしました。
今回は、この2つを組み合わせて、物理演算で動くキャラクターのアニメーションが、状態によって切り替わるようにします。
スクリプトを書いてみる
キャラクターの動作用のコンポーネント(名前はなんでもいいです。サンプルではキャラクターが「ことり」なので、Kotoriクラスとしています)をつくって、キャラクターのGameObjectにはりつけます。
using UnityEngine; using System.Collections; public class Kotori : MonoBehaviour { //毎フレーム呼ばれる void Update() { //接地しているかどうかを判定する //自分の基点の少し上と少し下の2点を渡して、その間にColliderがあればtrueが返る bool grounded = Physics2D.Linecast( transform.position + transform.up * 1, transform.position - transform.up * 0.1f ); //接地状態を出力する Debug.Log("grounded ->" + grounded); } }
コードが書けたら、再生してみます。
この状態だと、1つ問題があるので、ずっとTrueとしか出力されません。
キャラクターのLayerを変更する
問題というのは、Physics2D.Linecast が、ことり自身のColliderも判定してしまうことです。
Unityでは、GameObject にLayer を指定することができます。
主に当たり判定や描画の対象を絞り込むために使われます。
今回は、Physics2D.Linecastの引数でLayerを指定することで、接地判定するLayerを絞り込みたいと思います。
Kotoriクラス内のコードは以下のように修正します。
//接地判定する対象のLayer public LayerMask groundLayer; void Update() { bool grounded = Physics2D.Linecast( transform.position + transform.up * 1, transform.position - transform.up * 0.1f, groundLayer ); Debug.Log("grounded ->" + grounded); }
UnityのGUI上で、「groundLayer」プロパティに値を入れます。
そして、キャラクター自身のLayerを、上記で「groundLayer」に指定したLayerとは別のものに変更します。
再生して、ログを見てみると、
地面についた瞬間、trueになっています。
Animatorのパラメーターにプログラムで値を設定する
接地判定ができたので、アニメーションのパラメータに適用します。
ログを出力していた部分を書き換えます。1行だけです。
public LayerMask groundLayer; void Update() { bool grounded = Physics2D.Linecast( transform.position + transform.up * 1, transform.position - transform.up * 0.1f//, groundLayer ); //Debug.Log("grounded ->" + grounded); //Animatorコンポーネントの「Grounded」プロパティに取得した接地状態を渡す GetComponent<Animator>().SetBool("Grounded",grounded); }
再生してみましょう!
着地したときに、アニメーションが「Fly」から「Walk」に変化します。
次回、キー操作を追加して、サンプル完成です。