障害物にスナップするドラッグ可能なオブジェクトを作成するにはどうすればよいですか?


8

私はまだマウスでドラッグして別の質問(私はC#でUnityを使用しています)を持ちますが、それほど一般的ではない詳細:ドラッグが発生する経路の途中に障害物が存在する(2Dではなく3Dスペース) 。

説明させてください。"obj"と呼ばれる立方体をドラッグしたい平面があるとします。それは簡単です。これが私の簡単な実装です:

void Update () {
  Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  RaycastHit hit;
  if(Physics.Raycast(ray, out hit, 1000000))
  obj.transform.position = new Vector3(hit.point.x,0.25F,hit.point.z);
}

できます。ただし、平面上に障害物である他のいくつかの立方体もあるとします。明らかに、プレイヤーが平面上で「obj」を動かすとき、そのような動きは障害物によってブロックされるべきです。そして、障害物と衝突している間、「obj」はその障害物の側面にのみ移動して移動する必要があります。マウスを動かして "obj"が障害物との衝突をやめると、自由なドラッグスタイルの動きが再開されます。

オブジェクトが障害物に向かってドラッグされ、その端で停止し、ドラッグが障害物を通過すると再開します

課題をより困難にするために、障害物でRigidBodyコンポーネントを使用せずにそれを達成するために懸命に努力しています(ドラッグされたオブジェクトはそれを持つことができます)。それを達成するための最も効率的な方法は何ですか?どうもありがとう!

編集:コメンテーターは私の注意を喚起しました、私はスナップするときにオブジェクトが回転することを許可されていることを言及すべきです。

編集2:元の定式化の難しさを考慮して、ドラッグされたオブジェクトでのリジッドボディコンポーネントの使用を許可する質問を変更しました。ソリューションでは、障害物でリジッドボディコンポーネントを使用できません。


任意の凸形状を動かしていますか?それらは常に4面ですか?それらは常に2Dですか?
スティーブン

リジッドボディを使用しない理由を教えてください。これらは、Unityですでに利用可能なコードを再実装せずに、やりたいことを行う最も簡単な方法です。
EvilTak 2015年

@EvilTakタスクに関係するジオメトリの処理方法を学ぶのではなく、パフォーマンス上の理由から、本当に避けられない場合を除いて、リジッドボディを使用したくありません。この特定のケースでは、障害物として動作する何千ものオブジェクトが発生します
Mおよび

ところで、問題を説明するアニメーション画像を含めてくれた@Anko(またはそれをやった人)に感謝します!私はまだそうするための最良の方法を考えていました。
2015年

1
@StevenおよびEvilTak:オブジェクトは回転を許可される場合がありますが、障害物は許可されません。衝突を検出する通常の方法では十分ではないようです。メインオブジェクトがオブジェクトの内部に入り続けます。
Mおよび2015年

回答:


2

リジッドボディを使用せずに衝突を検出することは困難ですが、キューブを使用しているため、Bounds.Intersectsを使用できる場合があります。更新するたびに、ドラッグされたオブジェクトの境界が障害物の境界と交差するかどうかを確認します。もしそうなら、あなたはこれを試すことができます:

  1. ドラッグしたオブジェクトのメッシュレンダラーを無効にして、オブジェクトを非表示にします(ただし、引き続きドラッグします)。
  2. 境界交差前の最後の位置に、ドラッグしたものと同じ表示可能なプレースホルダーオブジェクトをドロップします(オブジェクトは停止しているように見えますが、実際には元のオブジェクトをドラッグしています)。
  3. 更新するたびに、ドラッグしているオブジェクトの境界が障害物の境界と交差しているかどうかを確認します。
  4. ドラッグされたオブジェクトの境界が障害物と交差しなくなったら、プレースホルダーオブジェクトを削除/非アクティブ化し、ドラッグされたオブジェクトのメッシュレンダラーを再度有効にして、再び表示されるようにします。

ブロックのドラッグを停止することはありません。障害物と交差するブロックがドラッグを停止したように見えるだけです。


以前のコメントと返信に基づいて、質問を編集して達成しやすくしました。リジッドボディをドラッグ可能なオブジェクトまたはそのプレースホルダーに使用できるとしましょう。剛体は障害物に使用できませんでした。
2015年

1

自分でやったことがなければ、ここで私が試してみたいことがあります:

  1. ドラッグしたオブジェクトをブロックするには、平面上の障害物の高さを決定します(「高」とは、適切な軸に沿って削除されることを意味します。カメラに向いているものと想定します)。
  2. 更新するたびに、レイキャストヒットの位置を保存します。
  3. 更新のたびに、現在のレイキャストヒットの位置を保存する前に、現在のレイキャストヒットの位置を前のレイキャストヒットの位置と照合します。
  4. 差> =ブロックの高さの場合、前のレイキャストヒット位置で移動オブジェクトを停止します。

オブジェクトを障害物の傾斜した平面に沿ってドラッグしたい場合は、その変形を最新のレイキャストヒットの位置に合わせ続けるだけでよいように思えます。


回答ありがとうございます、@ Evan。ただし、そのソリューションは正確ではありません。RayCastがドラッグ可能なオブジェクトのバウンディングボックスの中心から発射されると仮定します。途中の障害物が、レイキャストの左側または右側にあるドラッグ可能なオブジェクトの一部のみをブロックする場合はどうなりますか?キャストするレイの数を増やしても(ドラッグ可能なオブジェクトをX、Z次元で360度の方向にドラッグできる場合、指数関数的に高くなる可能性があります)、ドラッグ可能なオブジェクトに対する障害物の大きさによっては、レイキャストの中間になる
MAnd

わかりました、私はあなたの意味を理解していると思います。
エヴァン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.