2014年5月19日月曜日

Unity : 動く床に乗ったプレイヤーを動かす

プレイヤー(操作対象)が動く床の上に載ったら、
プレイヤーを床の子オブジェクトにするという方法で実装。
(注意:子オブジェクトにするため、床オブジェクトのスケーリングがプレイヤーに適用されてしまいます。)
上に乗っている場合、という判定のために床自体の Collider とは別に
上側の面に Collider を追加した。



動く床のメインオブジェクトは MovingFloor。
MovingFloorParent は空のゲームオブジェクトで、
MovingFloor のアニメーションを相対座標で動かすために親を作っている。

空のゲームオブジェクトに Box Collider 2D (Is Trigger 有効) を付けたものを MovingFloor の子オブジェクトする(とりあえず Surface と命名)。プレイヤーと接触するよう MovingFloor よりも少しだけはみ出しておく。(全体を覆うと、下や横方向から接触した場合にもプレイヤーが動く床にくっついてしまうので、上だけ)

Surface にはプレイヤーの当たり判定で判別できるよう Tag をつけておく。

プレイヤーに付けたスクリプトの OnTriggerEnter2D で、
transform.parent が null の時に Surface に接触したら、
transform.parent = other.gameObject.transform;
としてプレイヤーを子オブジェクトにする。

transform.parent が null でない時に OnTriggerExit2D で
Surface と離れたら、
transform.parent = null;
として親子関係を切り離す。以下の様な感じ。

載った瞬間にピタっとくっつき過ぎる感じなのがちょっと微妙な気もするけど、
どうしたらいいんだろう?

3 件のコメント:

  1. このコメントは投稿者によって削除されました。

    返信削除
  2. 参考になる記事をありがとうございます。

    3Dで同様の処理を組み込んでみました。
    親のスケールを変更すると、子供にも影響してしまうので、
    スケーリングしてオブジェクトを配置する場合は注意が必要です。

    void OnCollisionStay( Collision collision )
    {
    // 動く床に接触したら親子関係にする
    if (collision.gameObject.tag == "MoveBlock")
    {
    transform.parent = collision.gameObject.transform;
    }
    }
    void OnCollisionExit()
    {
    transform.parent = null;
    grounded = false;
    }

    返信削除
    返信
    1. ご指摘有り難うございます。
      確かに親オブジェクトのスケールに関して考慮できていませんでしたね。
      記事中に追記しておこうと思います。

      削除