1

注意:この問題はUnityでの作業中に発生しましたが、Unityに固有のものはなく、プログラミングロジックに関するものなので、恥ずかしがらないでください。

Unityを使用していて、スクリプトでオブジェクトを回転しています。たとえば、180度まで回転させると、オブジェクトはそれほど正確には回転せず、179度から181度の間で停止する傾向があります。したがって、回転が完了したかどうかを確認するには、回転角がtargetAngle+/-1であるかどうかを確認します。これは機能します。

使ってチェックします

if (transform.eulerAngles.z > lowerLimit && transform.eulerAngles.z < upperLimit)

どこ

lowerLimit = targetAngle-1;
upperLimit = targetAngle + 1;

ここで、targetAngleが0のときに問題が発生します。この場合、スクリプトは回転角が-1から1の間にあるかどうかをチェックします。ただし、-1は実際には359である必要があるため、角度が359から1の間にあるかどうかをチェックする必要があります。 。

どうすればこれを実装できますか?言い換えれば、私はラップアラウンド記数法を実装する方法を尋ねていると思います。

編集

1つの回避策が見つかりました。targetAngleが0の場合、私は特別に扱います。それは機能しますが、最もエレガントではありません。

         if (targetAngle == 0.0)
        {
            if ((transform.eulerAngles.z > 359.0 && transform.eulerAngles.z <= 360.0) || (transform.eulerAngles.z >= 0.0 && transform.eulerAngles.z <= 1)) 
            {
                rotate = false;            
            }
        }
        else
        {
            if (transform.eulerAngles.z > targetAngle - 1 && transform.eulerAngles.z < targetAngle + 1)
            {
                rotate = false;            
            }
        }
4

2 に答える 2

3

あなたができる...

lowerLimit = (targetAngle % 360) + 359; //360 - 1;
upperLimit = (targetAngle % 360) + 361; //360 + 1;

if (((transform.eulerAngles.z + 360) % 360) > lowerLimit
 && ((transform.eulerAngles.z + 360) % 360) < upperLimit)

これにより、チェックがゼロから離れ、ポジティブ/ネガティブチェックを処理する必要がなくなります。

編集

%演算子はtargetAngle、回転を+/- 359度に制限しているため、目標角度721は1になり、目標角度-359は1になります。これは、すべての場合にうまくいくはずです。

編集2

コメントで言及した最後のケースを修正するには、同じラッピングロジックを値に適用する必要があると思いtransform.eulerAngles.zます。おそらく今、このラッピングを追加の関数に入れるのが最善なので、これを試してください:

int wrapNumber(int input) // replace int with whatever your type is
{
  // this will always return an angle between 0 and 360:
  // the inner % 360 restricts everything to +/- 360
  // +360 moves negative values to the positive range, and positive ones to > 360
  // the final % 360 caps everything to 0...360
  return ((input % 360) + 360) % 360;
}

lowerLimit = wrapNumber(targetAngle) + 359; //360 - 1;
upperLimit = wrapNumber(targetAngle) + 361; //360 + 1;

if (wrapNumber(transform.eulerAngles.z) + 360 > lowerLimit
 && wrapNumber(transform.eulerAngles.z) + 360 < upperLimit)

これを使用する必要がある頻度によっては、場合によっては不要なオーバーヘッドを取り除くことができます。たとえば、% 360wrapNumber内のfinalは、入力が正の場合にのみ必要です。これを1分間に10回呼び出す場合は、おそらく問題にはなりません。1秒間に100回呼び出す場合は、この状況でどのように機能するかを確認することをお勧めします。

于 2011-07-17T10:22:41.463 に答える
1

これは古いスレッドかもしれませんが、ラッピングを処理しようとしている多くの異なるスニペットを調べた後、Unityにはビジネスを単純に処理する優れた組み込み関数があることがわかりました。少なくとも私の場合、必要な最終結果はlerpでした。 LerpAngleに変更するだけで、確実な結果が返されました。

Mathf.LerpAngleはあなたの友達です..ポップなどに関する私のすべての問題を解決しました。

http://docs.unity3d.com/ScriptReference/Mathf.LerpAngle.html

于 2015-11-18T08:47:08.880 に答える