【Unity】 부모 GameObject의 영향을 배제한 scale 산출 방법

6512 단어 C#Unity
계층 구조의 GameObject에서 부모의 스케일을 변경할 때 자식의 크기를 변경하지 않으려는 경우가있었습니다.
이러한 경우의 localScale의 산출 방법에 대해서, 검토한 안을 남겨 둡니다.

안1: 우선은 정공법



부모의 영향을 상쇄하는 스케일 산출(정공법판)
var localScale = this.transform.localScale;
var lossyScale = this.transform.lossyScale;
this.transform.localScale
    = new Vector3(
        localScale.x / lossyScale.x,
        localScale.y / lossyScale.y,
        localScale.z / lossyScale.z);

곧 떠오르고 이해하기 쉽고 좋다고 생각합니다.
…그래도 길고 왠지 중복이라도 역시 한다.
x, y, z를 실수할 것 같고 조금 무서운 것도 있다.
좀 더 깔끔하게 쓸 수 있는 방법은 없을까…

방안 2: 인덱서 이용


Vector3 에는 인덱서가 준비되어 있으므로 이것을 사용해 보겠습니다.

부모의 영향을 상쇄하는 스케일 산출(인덱서 이용판)
var localScale = this.transform.localScale;
var lossyScale = this.transform.lossyScale;
var scaleUnaffectedByParents = Vector3.zero;
Enumerable.Range(0, 3).ToList().ForEach(i =>
    scaleUnaffectedByParents[i] = localScale[i] / lossyScale[i]);
this.transform.localScale = scaleUnaffectedByParents;

x, y, z를 실수할 가능성이 없는 것이 좋네요.
나눗셈의 기술도 한 곳이 되어 그 나름대로 깨끗이 했습니다만… 이하의 부분이 앞으로 한 걸음 부족하게 느껴 버립니다.
  • 매직 넘버가 등장한다.
  • Vector3의 프로퍼티에 인덱서로 액세스한다고 하는 것이 지금 제대로 오지 않는다.

  • 방안 3: Transform의 방법 활용



    이런 방법으로 산출하는 것도 가능합니다.

    부모의 영향을 상쇄하는 스케일 산출(Transform의 메소드 활용판)
    // localScaleを表すベクトルをワールドの向きに変換
    var worldDirectedLocalScale
        = this.transform.TransformDirection(this.transform.localScale);
    // ワールド上で上記ベクトルを示す場合のローカル上での表現方法を算出
    // これがlocalScale設定値の大きさをワールド上で実現するために必要なlocalScaleとなる
    var scaleUnaffectedByParents
        = this.transform.InverseTransformVector(worldDirectedLocalScale);
    this.transform.localScale = scaleUnaffectedByParents;
    

    쓸데없이 복잡해져 버렸습니다만, 이것이 Unity 전문가라면 바로 이해할 수 있는 것일까요?

    해설



    그림을 그려 보았습니다.
    버블 안에 들어간 Unity는 scale1배. 그리고 버블이 x, y 모두 scale2배였다고 합니다.
    (표현하기 쉽기 때문에 2D로 생각합니다)



    부모의 스케일의 영향을 제거하고 싶다는 것은 "local scale = world scale"이 되기를 원합니다.
    즉, 지금의 localScale 의 값이 worldScale 가 되는 값을, localScale 로 설정할 수 있으면 됩니다.
    設定したいlocalScale → ワールドへの変換 → (x, y) = (1, 1) 
    となってほしい。ということは、
    (x, y) = (1, 1) → ワールドからローカルへの変換 → 設定したいlocalScale
    

    그러나 이것만으로는, 로컬 스페이스와 월드 스페이스의 축의 방향이 다른 경우에 능숙하지 않습니다.
    그렇다면 방향을 맞출 필요가 있습니다.

    결과적으로 다음의 순서로 산출하게 됩니다. 번호가 이미지의 숫자와 일치합니다.
  • Unity의 localScale을 취득하면 (x, y) = (1, 1)를 취득할 수 있다.
  • 이것을 월드 스페이스에서의 방향으로 변환한다.
    45도 왼쪽으로 기울어져 있는 Unity 찬 중(x, y) = (1, 1)의 방향은 월드 스페이스상에서는 (x, y) = (0, 1.4)가 된다.
  • 이 벡터가 월드 스페이스에 있을 때 로컬 스페이스에서는 어떻게 표기하는 것인가? 가 localScal로 설정해야하는 값이므로 벡터를 로컬 공간으로 변환합니다.

  • 이것으로 원하는 값은 산출할 수 있습니다만… 보다 이해하기 쉬운 쓰는 방법이 있는데 이만큼 해설이 필요한 안은 악수군요, 라고 하는 것으로 몰래 되었습니다.
    벡터나 월드 스페이스와 로컬 스페이스에 대한 이해를 깊게 하는 퀴즈로서 기능할지도 모릅니다.

    그렇다고 해서, 안 1이나 2의 쓰는 방법으로 할 수밖에 없을 것 같습니다.

    좋은 웹페이지 즐겨찾기