Skip to main content

各種の変換(トランスフォーム)

 今まで、物体の移動(位置)、回転と拡大縮小をUnityの「transform」コンポーネントを使ってやってきました。

image.png

 実は裏側でなにが行われているのか、学んでいきましょう。

移動(位置)

 一番簡単なのは、「移動」(位置)である。基本的に、メッシュの各頂点を移動させたい量を足すだけで実現できる。学んできた「ベクトルの足し算」を使えば、すぐ実装できる:

image.png

 ここで「v'」は移動した頂点で、「v」は元の頂点で、「t」は移動ベクトルである。

練習

MyTransform のスクリプトを作成し、MyCube で作った立方体を移動する。

  • 頂点の位置を変えないとけいないので、MyCube の頂点を読み込む(GetVertices)、書き込むメソッド(SetVertices)を作成してください。
    • GetVertices は頂点配列のコピーを返してください :
      return (Vector3[])vertices.Clone();
    • そうしないと、元の頂点の位置が失ってしまいます~
  • MyTransform で MyCubeの参照を GetComponent で取得し、頂点を変換する。
    • 移動量(位置)を Inspector で変えられるようにしてください。 
    • Translate(Vector3[] vertices)で移動を実装
    • Update
      • 頂点を取得
      • Translateで移動
      • 変換した頂点を設定
MyCube の GetVertices と SetVertices
// メッシュの頂点を返す
public Vector3[] GetVertices()
{
	// 元々の頂点データを守りたいので、コピーを返す
	return (Vector3[])vertices.Clone();
}

// メッシュの頂点を設定
public void SetVertices(Vector3[] vertices)
{
	mesh.vertices = vertices;
	mesh.RecalculateNormals(); // 方法ベクトル再計算
}
MyTransform スクリプト
// 自分で作った変換(Transform)コンポーネント
public class MyTransform : MonoBehaviour
{
    // 位置・移動量
    [SerializeField] 
    private Vector3 position;
    
    // 立方体
    private MyCube cube;

    private void Start()
    {
        // MyCubeを取得し、変換する前の頂点を保管しておく
        cube = GetComponent<MyCube>();
    }
    
    private void Update()
    {
        // 頂点を取得
        Vector3 [] vertices = cube.GetVertices();
        
        // 移動を適用
        Translate(vertices); 
        
        // 変換した頂点を適用
        cube.SetVertices(vertices);
    }

    // 頂点を移動する
    private void Translate(Vector3[] vertices)
    {
        // 1個ずつを処理
        for (int i = 0; i < vertices.Length; i++)
        {
            // ベクトルの加算で移動を実現!
            vertices[i] = vertices[i] + position;
        }
    }
}

拡大縮小(スケール)

拡大縮小は「すべての頂点を大きくする」または「小さくする」ということで、それぞれの頂点の「倍率」の値をかければ良いでしょう(ベクトルと実数の掛け算

image.png

練習

MyTransform を編集して…

  • Inspectorで倍率の係数を変えれるようにする
  • Updateで、Translate の前に Scale を適用
MyTransform スクリプト(編集分)
// 拡大縮小
[SerializeField] 
private float scale;

private void Update()
{
	// 頂点を取得
	Vector3 [] vertices = cube.GetVertices();

	// 拡大縮小
	Scale(vertices);
	
	// 移動を適用
	Translate(vertices); 
	
	// 変換した頂点を適用
	cube.SetVertices(vertices);
}

private void Scale(Vector3[] vertices)
{
	// 1個ずつを処理
	for (int i = 0; i < vertices.Length; i++)
	{
		// ベクトルの乗算で拡大縮小を実現!
		vertices[i] = vertices[i] * scale;
	}
}