キャラクターの回転を停止する
前回までの状態だと、キャラクターがジャンプして上部の床に届かなかった場合などに、キャラクターが倒れてしまいました。
キャラクターを選択する
Hierarchyウィンドウのcharactorを選択するか、Sceneウィンドウに配置したキャラクターをクリックしてキャラクターを選択状態にします。
Fixed Angleにチェックを入れる
InspectorウィンドウのRigidbody 2DのFixed Angleにチェックを入れます。
キャラクターが回転して転ぶことがなくなりました。
ジャンプ処理の修正
床に飛び乗った後、キャラクターが不意にジャンプのようなアニメーションを行い停止してしまいます。
アニメーションが発生する原因
これはCharactorManager.csの以下のコードに原因があります。
/// <summary>
/// 接触状態から離れた(=ジャンプ開始)
/// </summary>
/// <param name="col"></param>
public void OnCollisionExit2D(Collision2D col)
{
this._isJumping = true;
}
OnCollisionExit2Dは、キャラクターを表すGameObjectに接触した他のGameObjectが離れた際に呼び出されます。
前回の記事で、床は複数のGameObject(プレハブ)を並べて表現しました。1つ目のプレハブに接触したキャラクターが床を移動することで、そのプレハブから離れてしまうためにOnCollisionExit2Dが発生してしまい、キャラクターがジャンプのアニメーションを開始してしまうのです。
ロジックの変更
GameObjectがキャラクターと地面だけだった場合に有効だった判定ですが、複数のGameObjectを並べた床が追加されたことで不具合が発生することが分かりました。それでは、どのような判定に変更することでこの問題に対応できるでしょうか?
皆さんも少し考えてみてください。この後、私が考えた判定方法に基づいて進めていきますが、実際はこの解法は1つではないはずです。
私の考えた解法は「衝突しているGameObjectが0になったらジャンプアニメーションを行う」というものです。
説明するよりコードを見てみましょう。
CharactorManager.csのOnCollisionEnter2DとOnCollisionExit2Dの両メソッドを以下のように編集します。
// キャラクターに接触しているGameObjectのリスト
// 上部using句に以下を追加してください
// using System.Collections.Generic;
private List<GameObject> _collisionList = new List<GameObject>();
/// <summary>
/// 接触した(=着地)
/// </summary>
/// <param name="col"></param>
public void OnCollisionEnter2D(Collision2D col)
{
this._collisionList.Add(col.gameObject);
this._isJumping = false;
}
/// <summary>
/// 接触状態から離れた(=ジャンプ開始)
/// </summary>
/// <param name="col"></param>
public void OnCollisionExit2D(Collision2D col)
{
this._collisionList.Remove(col.gameObject);
// 接触しているGameObjectが0の場合はジャンプしていると判定してアニメーションを開始する
if (this._collisionList.Count == 0)
{
this._isJumping = true;
}
}
コードの解説
キャラクターが他のGameObjectに接触する度(OnCollisionEnter2D)に、リスト(_collisionList)に接触したGameObjectを保持して、離れたタイミング(OnCollisionExit2D)でリストから対象のGameObject削除することにしました。
そして接触しているGameObjectの数が0になった場合に、ジャンプのアニメーションを実行するように変更しました。
