質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.00%

Unity-テトリスっぽくブロックを動かす

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 4,075
退会済みユーザー

退会済みユーザー

unityでテトリスの3Dバージョンのようなゲームを作成しています。

ブロックを段階的に落とすにあたり、重力をゼロにし、rigidbody.movePositionで1マス分ずつ降下させ、真下にあるブロックと衝突した時点で降下を止めるスクリプトを書いたのですが、下に落ちきる前に他のブロックと隣り合うと側面が衝突判定を起こし、そこで降下が止まってしまいます。

とにかく側面が他のブロックと触れてもスルーし、下面が衝突した時にのみ降下を止めるようにしたいです。

そこで質問なのですが、衝突判定において判定する面を「ワールド座標でのy軸と直交する面が衝突した場合のみ〜」という風に指定することは可能でしょうか?
あるいは、テトリス風の動きを再現するうえで、もっと単純な方法はありますか?

解答よろしくおねがいします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

おそらく、このような離散的な動きのゲームで当たり判定を行うにあたっては、物理シミュレーションによる判定は不向きかと思います。仮に垂直方向だけがヒットするような動作を実現できても、例えばブロックを細い隙間を狙って落とす事を考えると、シミュレーション上の誤差のために本来当たるべきでない隙間の縁の上面と衝突したと判定される...などのケースが考えられます。また、水平方向の判定を完全になくしてしまうと、ブロックの間を落下中のブロックが水平方向に移動可能かどうかの判定を別途実装する必要があるのではないでしょうか。思うに、3Dであるとはいっても、当たり判定については古典的な2Dテトリスに倣って、フィールドを3次元の配列のような形で表現した方が面倒が少ないように思います。

あえて物理シミュレーションによる判定でいくとしたら、Rigidbodyは物理的相互作用はしないようにして、衝突イベントのみ検出してイベント応答メソッド中で本当に意図した衝突であるかを正確に判定する...とか、コライダーの形状を実際のブロックの3Dモデルよりも水平側面を少しだけブロック内側に引っ込めて意図しない衝突判定を回避する(この方法は案外うまく行くかもしれません)...などはどうでしょう。ただし、即興で思いついた方法なので、何か他に厄介な問題が出てくるかもしれません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/06/06 21:33

    解答ありがとうございます。

    確かに面を指定できたところで問題はありそうですね、んーむずかしい。。
    配列も考えはしたのですが、実際のテトリスとは違って枠で範囲を限定しない仕様にしたかったので断念しました。

    コライダをブロックより一回り小さくするのも先に試しはしたんですけど、テトリスみたくブロックを回転させるので側面だけでなく全方向を小さくせざるを得ないんですよね。
    でもそれだと真下のブロックとの間にできた隙間を埋めるために降下回数が1回多くなって、結果妙な動きになってしまうんです。

    やっぱりBongoさんが仰るようにイベント応答メソッドの中身を考えるのが一番近道ですかね

    キャンセル

  • 2017/06/07 03:58

    なるほど、回転も考慮すると複雑になってきそうですね...
    コライダーを側面の引っ込んだ直方体の集合として作り、ブロック回転時は回転後に個々の直方体を逆回転させて、各直方体は常にワールド座標に対して無回転になるようにする、などが必要そうです。

    他のアプローチとして、ブロックを構成する各立方体が前後左右上下にレイキャスティングして障害物までの距離を測り、周囲のブロックとの位置関係を求める、なんていう方法もあるかもしれません。

    キャンセル

  • 2017/06/08 04:22

    返信遅くなってごめんなさい。

    上のコメント欄にも書きましたが、おかげ様で解決できました!
    私が見落としていた問題点を指摘してくださったのも本当に助かりました。
    ありがとうございましたm(_ _)m

    キャンセル

0

Bongoさんの回答とほぼ同意見で、一見物理演算でテトリスのような挙動を表現できるように見えますが相性はよくありません。
また、配列で実装するのがいいという意見も同意ですが、配列ではなくても実装はできると思います。

例えば、Unityにおける1mを配列のインデックスのように扱うのはいかがでしょうか。
座標(0, 0, 0)を、三次元配列の[0, 0, 0]というふうに見立てて実装するのが手っ取り早いかと思います。

また、ブロックも様々な形があるかと思いますが、それらはあくまでも1m四方のブロックの集合体として扱うことでテトリスのような様々な形のブロックが表現できます。

このとき、その集合体がどこまで落下すればいいかについてですが、端的にいうとブロック一つ一つから地面までレイを飛ばし、最短でレイがヒットした座標まで集合体を落下させる、などというような実装で行けると思います。

その後の実装や細かい実装について言及していくとキリがないですが、結局のところ「本当のテトリスとは違って枠の概念を無くしたい」などの、独自の仕様は質問文に書いておいたほうが回答しやすいですし、求める答えが返ってきやすいかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/06/08 04:14

    解答ありがとうございます。

    御二方のおかげで無事解決できました!
    アドバイス通り、各ブロックからレイを飛ばす方法でうまくいきました。
    レイをブロックの中心から、常にワールド座標でのy軸下向きにとばすことでブロックの回転に対応できたみたいです。

    そうですね、説明不足でした。
    今後は気をつけて質問するようにしますね。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.00%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる