🔎

【Unity】Non-Uniform Scalingな親GameObjectを持つと子は苦労するかもしれない

2024/05/28に公開

Non-Uniform Scalingとは

X, Y, Z軸のスケール値が同一でないものを指します。
日本語では「不均等スケール」というような表現をします。

反対に、X, Y, Z軸のスケール値が全て同じであるものを、Uniform Scaling/均等スケールと言います。

Non-Uniform Scalingで起こる問題

実験用のシーンを作りました。
クリアキューブの中にUnityちゃんが入っており、親子関係になるようにしています。
初期状態では全てScale1に設定しています。
UnityChanInCube初期状態.png

Non-Uniform Scaling状態生成

キューブのScaleをY軸方向2倍に変更します。
親のスケールをY軸2倍に.png

子階層にあるUnityちゃん含め縦長になりました。
これでキューブがNon-Uniform Scalingの状態となりました。

子GameObjectを回転

この状態で、UnityちゃんをZ軸で-90度回転してみます。
UnityChanをZ軸-90回転すると….png

…あれ、Unityちゃんなんか太った…?

見比べるために、UnityちゃんのRotationを元に戻し、キューブの方をZ軸で-90度回転してみます。
親をZ軸-90度回転した場合.png
うん、身長2倍状態。
UnityちゃんのRotationを変更した場合もこの見た目になることを期待していたんだけど…。

Unityちゃんの方のRotationを変更して身長2倍を実現するには

Scaleを以下のように設定すれば同じ見た目になります。
親を回転した場合と同じになるようにUnityChanのスケール調整.png

回転角度が90の倍数の場合はこのように帳尻を合わせることができますが、例えば45度回転では変形したUnityちゃんを元に戻すことはできません。[1]

何が起こっているのか

2D画面で改めて状況を確認してみます。
今度はクリアキューブの中に緑色のキューブを入れました。
緑キューブはScale0.5に設定しています。
CubeInCube初期状態.png

子GameObject回転

緑キューブをZ軸で90度回転しました。
子をZ軸90度回転.png
回転したのに見た目が同じです。
ローカル軸の向きは変わっているので、確かに回転はされています。

次は、緑キューブをZ軸で45度回転しました。
子をZ軸45度回転すると….png
すると、緑キューブが縦長の菱形に変形しました。

緑キューブは回転しても常に縦方向に長いです。
つまり、子GameObjectの向きに関わらず、親GameObjectの軸でスケーリングされてしまっています。

子GameObjectのScale変更はどうなる?

因みに、緑キューブをZ軸で90度回転した状態で、緑キューブのScaleをY軸方向に2倍にすると、横に伸びます。
子のスケールをY軸2倍に.png
ということは、子GameObjectのLocalScaleは子GameObjectの軸でスケールされているようです。

サポート外とのこと

UnityのTransformのマニュアルに説明がありました。
(日本語版は少し訳がわかりにくいので英語の方を引用します)

For performance reasons, a child object of a non-uniformly scaled parent will not have its scale automatically updated when it rotates.

子GameObjectが回転しても、スケール方向は回転前の状態の軸(つまり親GameObjectの軸)となるということのようです。

このため、Non-Uniform Scalingな親を持つ子GameObjectは任意の方向に拡大縮小させることができません。
上記のマニュアルによると、その他にもサポート外となるものが複数あります。
また、今回の実験シーンでは確認できませんでしたが、親をNon-Uniform Scalingにしただけでフレームレートがガタ落ちしたという情報も見かけました。

対応策

サポート外なのでどうしようもない、というところではあるのですが、ヒエラルキーの構造を工夫することで避けられる場面も多いと思います。

  • スケール変更が不要なモデルを準備する。
  • Non-Uniform ScalingにしたGameObjectには子階層を作らない。
  • 2Dの場合はX, Y軸のスケール値を変更したらZ軸にも同じ値を入れるようにする。

ということを気にしながらヒエラルキーを構成していくとちょっぴり幸せになれるかもしれません。

脚注
  1. シェーダーを使えば何とかできるとは思いますが、シェーダーなら元に戻すより回転自体をシェーダーで行った方が良いですよね。 ↩︎

リリテックラボ

Discussion