2011-09-09 4 views
8

1つには、ボールを打つはずのラケットがあり、ラケットはマウスによって直接制御されます。すなわち、バットはマウス軸を使ったマウスとtransform.translate()関数を使ってラケットを動かします。マウスで制御されたラケットで速く動くボールの衝突検出に問題がある

私はUnity3dの物理がマウスで直接ラケットの動きを正しく翻訳せず、ボールにそれに応じて影響を及ぼさないと思っていました。私はカスタムを書く必要があり、真実であることが判明しました。

しかし、ボールの衝突は、ラケットが動いているときに正しく検出されていません。それがまだ残っていれば、すべてがうまくいき、ボールが私のように振る舞います。

今私は、長さ0.6Fのレイ・キャスト4個をボールに付けて、複雑なベクトル計算をした後、ボールの速度を計算するカスタム・フィジックス・スクリプト(私はスクリプトのためにC#を使用しています)ラケットを打った後に、rigidbody.velocity = calculateVelocity()を使ってボールの速度に直接適用します。ラケットが動いていないときにはもう一度うまく動いていますが、ラケットを動かすときにはうまくいきません。

組み込み物理機能と衝突検出の使用:ラケットが動いているときに、ボールがラケットをまっすぐに通過することがありますが、時々速度が遅くなることがあります(信じられないほどのレベルまで)。

私のスクリプトを使用して速度を計算する:問題は同じですが、コライダー(ラケット)の法線を印刷するときに何が問題なのかを識別できます。時には右の法線を与え、時には法線ベクトルの負の値を与えます。つまり、上の面をまっすぐに通り、コライダー(ラケット)の底面でヒットを検出します。

私がしようとしているもの:

  1. をコライダーのサイズを大きくする(それはラケットの広い箱コライダーで動作しますが、その後明らかにボールが離れたラケットからかなり離れた場所から移動し、私自身のスクリプトはここで働きますが、デフォルトの物理学はラケットが動かされたときに奇妙な結果を出します)、要するに私が望む現実は得られません。

  2. 固定タイムスタンプを0.001に減らすと、物事ははるかに改善されましたが、結果から非常に遠く離れています。また、ボールは再びボールの間違った面を頻繁に選んでいます。衝突検出を連続的な動的に変更すること。どちらも改善されませんでした。

そして間違った側に加えて、衝突時に選んだ、私が観察している別の問題ではラケットを跳ね返った後、ボールが移動しているが、ラケットを速く移動され、それは代わりの完全な円弧状に移動するということですボールの前に何とか表示され、結果として2ヒットとなる。目に見えるものに基づいた推測です。

また、Unity3dの組み込み物理によってラケットの「動き」の部分が読み取られておらず、マウスがボールを打つことでラケットが動いているときに奇妙な動作が発生することが明らかです。

私は立ち往生しています。どこから移動するのかわかりません。私が間違っていることを教えてください。

答えて

8

他の人が指摘しているように、問題は、ボールが1つのフレーム内のパッドの側にあるから次のフレームの反対側にあるということです。障壁が薄すぎると、速く動く物体はそれをする傾向があります。

この問題のための3つの非常にシンプルなソリューションがあります。

  • を使用すると、コライダーのサイズを変更したときに何が起こったかである、パッドの大きさやボールを増やします。
  • パッドを通過するのに十分速く動かないように、ボールの最高速度を設定します。
  • Unityが物理計算を行う頻度を増やします。 Time Managerで変更することができ、Fixed Timestepの値を減らします。これをあまりにも減らすことに注意してください。そうしないと、次のラウンドが始まる前に物理エンジンがコールを終了できず、決してゲームに追いつくことができません。

移動するオブジェクトの最大速度を設定することは、常に実行する必要があります。ゲーム中に重要なオブジェクトが急増する危険性はありませんし、すべてを制御されていない状態にすることはできません。

+0

私はラケットとボールの両方に最高速度を設定しようとしましたが、おそらく環境全体のサイズを増やすことができます。これは、衝突者の右側を検出する可能性が高いかもしれません。私はJustin808のソリューションを実装し、すべてのサイズを増やします。 – SpeedBirdNine

+0

このことはすごくうまくいって、私はすべてのサイズを2倍にしました。今は衝突がないわけではありません。私はまだジャスティン808が話している他の問題があります。一瞬でラケットがボールの前にあり、次のフレームがボールの後ろにありますが、少なくとも私はコードで扱うことができる2つの異なる衝突を見ています!どうもありがとう!私には2分しかかかりませんでした。今私は2つの衝突を解決するジャスティンのソリューションを実装するつもりです。この時間までに誰か他の説明があれば、それも共有してください! – SpeedBirdNine

+0

問題を解決しました。ラケットのコライダーがボールを失っていないので、ボールの前と次の位置の間にレイキャストを配置する必要はありませんでした。他のものは、マウスによるラケットの動きがボールに加えられた追加の力に変換されないということです。私はこの部分を自分で書かなければならず、オリジナルの物理が干渉しないようにラケットコライダーにistriggerをtrueに設定しなければなりませんでした。しかし、今度は複数回打つという問題がありました。最初に打つと偽になり、1秒後に真実になり、ボールが別のオブジェクトに当たったときに、フラグを使って解決しました。これは動作します! – SpeedBirdNine

3

これは完全な答えではありませんが、私はこれまでのように、低速のマシンでこのような問題に対処したことを覚えています。

問題は、スプライトベースの衝突検出を使用していました。同じ座標にレンダリングされるスプライトと障害物のピクセルに依存します。フレームレートが非常に低いので、スプライトが1つのフレーム内で障害物のサイズを超えて移動すると、あるフレームに障害物が残っていて、次のフレームの障害物の右側に同じピクセルを占有する。

この場合、スプライトベースの衝突は機能しません。ベクトルの衝突を基にする必要があります。衝突のために各スプライトピクセルをチェックする代わりに、スプライトの位置と凸包を記録します。各フレームの後に、古い位置から新しい位置までのベクトルを計算し、それを各障害物の凸包と交差させます。

最初にバウンディングボックスと比較するだけでなく、ベクトルがバウンディングボックスと交差する場合にのみハルを計算するような複数のショートカットがありますが、これが基本的な考え方です。がんばろう。

+1

アイデアは良い出発点だと思われますが、できるだけ多くのビルドされたものを使ってUnity3dでそれをどのように実装するかは、最適化されています。遅いマシンについては、6GBのDDR3 RAMと1GBのATi Radeon HD5890グラフィックスカードを搭載したコアi7マシンでテストしたところ、FPSは70未満に落ちることはありません.Spriteベースの衝突検出とは何かを説明してください。 ?私はUnity3dを使用しているので、私はこの程度まで衝突検知の仕組みを制御することはできないと思う。 – SpeedBirdNine

+1

申し訳ありませんが、Unityを使用していません。スプライトベースのグラフィックスは実際のフレームバッファを計算に使用します。 OpenGLやActiveXを使用している場合は、スプライトを使用していない可能性があります。しかし、衝突のために凸包に対してベクトルをチェックするという概念は、保持されたモードのグラフィックに適用可能である。私はUnityがベクトルが船体と交差するかどうかを見る方法を持っていると想像します。 –

+0

これ以上の回答はありますか? – SpeedBirdNine

5

私が考えていることは、ボール/ラケットで起こる各間隔が移動され、衝突がないかチェックされることです。問題は、ボール/ラケットが1つの間隔で遠くに移動し、衝突を逃したことです。

1) Ball before racquet 
2) Ball after racquet 

not 

1) Ball before racquet 
2) Ball touching racquet 

だから、あなたが何をすべきか、前のボール位置に、現在のボール位置から光線をキャストされて、あなたのボールゲームオブジェクトのあなたのFixedUpdate()メソッドです。ヒットしたはずの2点間に何かがある場合(つまり、ラケット)、レーン上の報告されたヒットポイントにボールを戻します。これにより、既存の衝突検出機能がトリガーされます。

ライダーコライダーをスキップしていないため、コライダーのサイズを大きくする理由もあります。これにはあなたの質問で言及した欠点があります。レイキャスティングはこの問題を回避し、ボール/ラケットが必要なだけ速くまたは遅く動くようにします。

0

私は3Dポンゲームにも取り組んでおり、まったく同じ問題を抱えています。私は皆さんのようにすべてを拡大しようとしています。ボールにスピードとスピンを加えたパドルについては、パドルの位置を変えても速度が変わらないことがわかるまで、私はこれに戸惑いました。パドルが移動する前にゼロ速度であった場合、物理エンジンが次のフレームを見るとゼロになります。Uncheckはケニマチックで、ベロシティプロパティを介してパドルを直接制御して問題を解決しました。壁にぶつかったときにパドルが震えましたが、パドル層から壁を取り除き、LateUpdateで手作業で境界を操作することで、パドルを修正しました。また、ベロシティを更新するときは、最初にUpdateに新しい希望のベロシティを保存して、コントロールがスムーズに動作するようにしてから、FixedUpdateの変更をコミットします。