テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】Auto Sync Transformと移動時の判定、それと注意点

たぶん2017.2辺りからAuto Sync Transformという項目が追加されました。 この設定はパフォーマンスの観点からOFFが推奨ですが、ONにすべきタイミングもあるかもしれないので、その辺り少し紹介です。

Transform変更時に即座にColliderに反映させるAuto Sync Transform

Auto Sync TransformはProject SettingsのPhysicsの設定項目の一つです。
この項目をONにすると、Transformで座標を変更するたびにColliderの情報を更新するというものです。
つまり同じTransformを何度も操作するようなコードを記述していると、もしかしたら無駄な負荷を生じさせているのかもしれません。

docs.unity3d.com

f:id:tsubaki_t1:20181005231406j:plain

確認のため下のようなコードを書いてみます。

gist.github.com

このコードを実行した時、Auto Sync Transformの有無で結果が変わります。

ONだった場合、座標の変化は即座に反映するので4.5fという数値になります。逆にOFFだった場合、前フレームの最終的な座標である9.5fという数値になります。

つまりAuto Sync TransformがOFFの場合、対象の座標移動後にRaycast等のAPI接触結果を取得するために1フレーム待たなければならないという事です。
更新のタイミングはFixedUpdate後です。

テストを使用している場合に注意

これが問題になるのは、テストの時かもしれません。
例えば下のようにテスト時にCollider付きGameObjectを生成している場合、Auto Sync Transformの有無により結果が変わります。

gist.github.com

Auto Sync TransformをONにしていると全てのテストは通りますが、OFFだと生成直後や動かした直後にyield return null;を挟まないと反映されません。

f:id:tsubaki_t1:20181006005342j:plain f:id:tsubaki_t1:20181006005354j:plain

更に驚くことに、この結果はRun IN Playerを実行した場合にも変化します。
問題となるのは「1フレーム待つ」のテストが失敗している事で、その原因は「オブジェクトが生成されていない」となります。

f:id:tsubaki_t1:20181006005821j:plain

この原因はyield return null;だとFixedUpdateまで到達しないことじゃないかなと思います。試しにyield return null;yield return new WaitForFixedUpdate();に変更したところ、エディターでのテストと同じ結果になりました。

f:id:tsubaki_t1:20181006010153j:plain

後はテスト時に前のテストのゴミが残るかなーと予想していたんですが、とりあえず試した感じは残りませんでした。
はて?

感想

Collider関連をテストする時には、Auto Sync Transformは有効にしとくのが良さそうです。
逆に普通に動かす場合、Auto Sync TransformがOFFなのは理にかなっていそうです。でも当たり判定をPhysics系APIを基本としている場合は少しトラップになるかな?

軽い気持ちで調べたら意外と深刻だったでござる