Unityでの惑星サイズの世界のフロート制限の克服


8

私の知る限り、Unityで世界の原点から100万ユニットを超えることは、浮動小数点の精度の問題のため、ほとんど不可能です。

半径が1M単位を超える世界を作成するにはdouble、座標にvarを使用するか、いくつかの空間分割手法を使用して、大規模なシーンを階層チャンクに分割する必要があります。最小のチャンクは約10000単位です。つまり、各ワールド空間の位置が表現されます。チャンク階層によって、オブジェクトのインとfloat、最後のチャンク内のローカル位置(および場合によっては回転とスケーリング)を表すvarの束。

どちらの方法でも、これを行うには完全に新しい座標系を実装する必要があるため、Unityでそれが可能かどうか、可能であれば、物理学などの既存のUnityシステムでそれをどのように機能させるかについて知りたいのです。

PS惑星の周りで同時に物事を進行させたいので、プレイヤーが移動するときに世界を原点に移動することはできません。

ありがとう!

回答:


5

あなたは非常に静的な言葉で考えています。

オブジェクトが半世界離れているからといって、問題はありません。エンティティ座標が世界ではなくチャンクに相対的に格納されている場合、これは簡単に実現できます。ネイティブコードでボクセルの世界を作成する場合の方法へようこそ。

それでは、ロケールと呼ばれる概念を想定してみましょう。これは、互いに近接している一連のチャンクです。重要なのは、特定のロケールの内部のフロートスペースが安全制限を超えないことです。個別の処理ロケールを決定する必要があります。最初に、エンティティnの位置の半径内にあるすべてのチャンク(プレーヤーまたは他の何か)を取得することから始めます。私の現在のエンジンでは、2つの異なるロケールの1つのチャンクでも重複している場合、これらのロケールが1つのロケール/一意のチャンクのセットにマージされるようにします。これにより、特定のフレームで、単一のチャンク内のすべてのエンティティを2回以上処理することがなくなります。

ロケール/チャンクセットが用意できたので、それらとそのコンテンツに対してゲームロジックを実行できます。そして、プレイヤーや原点からどれだけ離れているかは関係ありません。重要なのは、各セットのほぼ中央にあるチャンクを取得し、それを原点(つまりfloat[0.0,0.0,0.0])として扱い、そこから外に向かって作業することです。ゲームの典型的な視野範囲を考えるとfloat、深刻な問題を起こすことなく、数kmを超えて表示する必要がないことを保証します。

Unityを除いて、1つのオプションは、エンジンをゼロから作成することです。おそらく、libfixmathのようなものを使用します。小数点は引き続き使用できますが、浮動小数点ではないため、これらの精度の問題は発生しません。しかし、私は他の理由でチャンクとロケールが必要になることを保証しますので、それはおそらく努力する価値がありません。


あなたは私が数キロ以上離れて見る必要はないと言っていましたが、私は宇宙から完全に観察することができるはずである惑星サイズの世界についてはどうですか(outerraを参照)?
Maks Maisak

@MaksimMaisakゲームロジックに数値精度が必要です。レンダリングは行いません。宇宙から詳細で正確な世界を見る必要はありません。私が上記で説明した正確な地上システムから、あまり正確ではないスペースの視点にシームレスに切り替えることができる高さがあります(カードを正しくプレイした場合)。ただし、レンダリングとゲームロジックには違いがあることに注意してください。
エンジニア

そして、スペースをどのようにチャンクに分割しますか?チャンクから始めてロケールにグループ化しますか、それともロケールから始めてチャンクに分割しますか?
Maks Maisak

チャンクから始めます。ここでの「ロケール」は、「チャンクの周辺」を意味するだけなので、チャンクの概念が前提条件です。
エンジニア、

チャンクはどのようにして「オーバーラップ」することができますか?
Maks Maisak

6

それはよく出てくる質問です。ここで繰り返すのではなく、私がすでに同じ問題に与えたかなり詳細な別の答えにあなたを自由に転送します:Unityでカスタム座標系は可能ですか

そこから、私が最も示唆することは、あなたが驚くべき論文を読むことです:http : //citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.471.7201&rep=rep1&type=pdf。それはあなたが説明する問題に取り組むいくつかの方法(Arcane Engineerが彼の回答で説明したローカル座標を含む)を比較し、最近の有名なフロート原点ソリューションについての詳細に行きます。これは、実際には、ほとんどの場合私が行くものです(実際、それは私がアプリケーションで使用しているものです)。

確かに、float originソリューションはニーズに合わないと述べました。しかし、世界の非常に離れた場所で物事が発生し続けたい場合でも、そうではない場合があります。ほぼすべてのAIを好きな場所で発生させることができます。衝突チェックや正確な位置決めをプレーヤーから遠すぎて(フロートの不正確なしきい値を超えて)行うべきではありません。しかしとにかく、率直に言って、実際のアプリケーションでは、処理の制限により、ゲーム内で多くの衝突と配置を行うことはできません。それでも、ゲームの特性によっては、フロートオリジンソリューションに見られる制限にさえソリューションがある場合があります。繰り返しますが、このソリューションを完全に読む前に、そのソリューションを破棄しないことをお勧めします。

それでも、ローカル座標系(どこに行くかによっては非常に複雑なソリューションになる可能性があります)を試す必要があると決めた場合、私のリンクされた回答の2番目の項目はあなたのためです。その中で最も重要な部分は、先駆的なゲームであるダンジョンシージで最初にそのソリューションを実装した人が書いた紙です。http//scottbilas.com/files/2003/gdc_san_jose/continuous_world_paper.pdf

数年前のビデオもあり、Unityの人々がそのソリューションについてコメントし、Unityでのコンセプトの最新の実装についても説明しています。

https://www.youtube.com/watch?v=VKWvAuTGVrQ

それが役に立てば幸い。


3

すでに解決策が決まっているかどうかはわかりませんが、あなたや他の読者にとって将来役立つかもしれない他の2つのリソースについて触れたいと思います。

  • この最近のCppCon講演:"Demystifying Floating Point"は、プログラミング言語に関係なく非常に関連があります。精度について提示された非常に興味深い点の1つは、フロート精度のスイートスポットが[-1、+ 1]の範囲にあることです。したがって、正規化された浮動小数点数は、それらを使用できる場合に最適な方法です。

  • アイデアを得るために調べておきたいもう1つの場所は、古典的なダンジョンシージゲームです。ゲームは、ノード/タイルベースの継続的なワールドシステムを使用し、すべての位置は現在のノードを基準にしています。このホワイトペーパーには、ゲーム使用されるシステムの非常に詳細な説明があります。また、ブログにいくつかの段落を書きました。このセットアップは当時は目新しいものでしたが、おそらく今日はそれほど有用ではありません。上記のリンクされた論文は、彼らが抱えていたいくつかの問題について言及しています。それにもかかわらず、それは歴史的な観点から興味深いものであり、アイデアやインスピレーションの源としてあなたに役立つかもしれません。

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