1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Unityで構図のための補助線を表示する

Last updated at Posted at 2023-06-04

はじめに

Unityで映える静止画を撮影したい場合に、写真撮影でよく使われる構図を意識して撮りたい場合があります。
その際に補助線をカメラに表示できたら、(また補助線を切り替えられたら)便利だと思ったので
今回はOnDrawGizmosSelectedを利用して表示する方法を紹介します。

また、コードを整理してRenderでも利用できるようにしたプロジェクトをGithubにあげているのでよかったら見てください。

unity_1.png

背景はこちらのサンプルを利用しました。

TL;DR

以下のスクリプトをカメラにアタッチすれば利用できます。
表示されない場合はGameViewでGizmosを有効にしてください。

public class CameraComposition : MonoBehaviour
{
    private enum CompositionMode
    {
        Symmetrical, // 対称
        Bisection,   // 二分割
        Thirds,      // 三分割
        Diagonal,    // 対角線
    }
    
    [SerializeField]
    private CompositionMode compositionMode = CompositionMode.Symmetrical;
    
    private void OnDrawGizmosSelected()
    {
        var camera = gameObject.GetComponent<Camera>();
        Gizmos.color = Color.red;
        switch (compositionMode)
        {
            case CompositionMode.Symmetrical:
                DrawSymmetricalComposition(camera);
                break;
            case CompositionMode.Bisection:
                DrawBisectionComposition(camera);
                break;
            case CompositionMode.Thirds:
                DrawThirdsComposition(camera);
                break;
            case CompositionMode.Diagonal:
                DrawDiagonalComposition(camera);
                break;
        }
    }
    
    // 対称
    private void DrawSymmetricalComposition(Camera camera)
    {
        // 縦線
        Gizmos.DrawLine(
            camera.ViewportToWorldPoint(new Vector3(0.5f, 0, camera.nearClipPlane + 0.1f)),
            camera.ViewportToWorldPoint(new Vector3(0.5f, 1, camera.nearClipPlane + 0.1f))
        );
    }
    
    // 二分割構図
    private void DrawBisectionComposition(Camera camera)
    {
        // 縦線
        Gizmos.DrawLine(
            camera.ViewportToWorldPoint(new Vector3(0.5f, 0, camera.nearClipPlane + 0.1f)),
            camera.ViewportToWorldPoint(new Vector3(0.5f, 1, camera.nearClipPlane + 0.1f))
        );
        // 横線
        Gizmos.DrawLine(
            camera.ViewportToWorldPoint(new Vector3(0, 0.5f, camera.nearClipPlane + 0.1f)),
            camera.ViewportToWorldPoint(new Vector3(1, 0.5f, camera.nearClipPlane + 0.1f))
        );
    }
    
    // 三分割構図
    private void DrawThirdsComposition(Camera camera)
    {
        // 縦線
        Gizmos.DrawLine(
            camera.ViewportToWorldPoint(new Vector3(1.0f / 3.0f * 1, 0, camera.nearClipPlane + 0.1f)),
            camera.ViewportToWorldPoint(new Vector3(1.0f / 3.0f * 1, 1, camera.nearClipPlane + 0.1f))
        );
        Gizmos.DrawLine(
            camera.ViewportToWorldPoint(new Vector3(1.0f / 3.0f * 2, 0, camera.nearClipPlane + 0.1f)),
            camera.ViewportToWorldPoint(new Vector3(1.0f / 3.0f * 2, 1, camera.nearClipPlane + 0.1f))
        );
        // 横線
        Gizmos.DrawLine(
            camera.ViewportToWorldPoint(new Vector3(0, 1.0f / 3.0f * 1, camera.nearClipPlane + 0.1f)),
            camera.ViewportToWorldPoint(new Vector3(1, 1.0f / 3.0f * 1, camera.nearClipPlane + 0.1f))
        );
        Gizmos.DrawLine(
            camera.ViewportToWorldPoint(new Vector3(0, 1.0f / 3.0f * 2, camera.nearClipPlane + 0.1f)),
            camera.ViewportToWorldPoint(new Vector3(1, 1.0f / 3.0f * 2, camera.nearClipPlane + 0.1f))
        );
    }
    
    // 対角線
    private void DrawDiagonalComposition(Camera camera)
    {
        // 縦線
        Gizmos.DrawLine(
            camera.ViewportToWorldPoint(new Vector3(0, 0, camera.nearClipPlane + 0.1f)),
            camera.ViewportToWorldPoint(new Vector3(1, 1, camera.nearClipPlane + 0.1f))
        );
        // 横線
        Gizmos.DrawLine(
            camera.ViewportToWorldPoint(new Vector3(1, 0, camera.nearClipPlane + 0.1f)),
            camera.ViewportToWorldPoint(new Vector3(0, 1, camera.nearClipPlane + 0.1f))
        );
    }
}

カメラにアタッチするとモード選択することができます。

unity_2.png

unity_3.png

補足:SceneViewでCtrl+Shift+FでSceneViewの位置と方向にカメラを向けてくれます。

コード解説

まず、モードを選択できるようにenumと変数を用意します

enum CompositionMode
{
    Symmetrical, // 対称
    Bisection,   // 二分割
    Thirds,      // 三分割
    Diagonal,    // 対角線
}

[SerializeField]
private CompositionMode compositionMode = CompositionMode.Symmetrical;

Unityで補助線を表示するためにギズモを利用するためOnDrawGizmosSelectedを使います。
カメラは共通だと思うので引数で渡すようにしています。

private void OnDrawGizmosSelected()
{
    var camera = gameObject.GetComponent<Camera>();
    Gizmos.color = Color.red;
    switch (compositionMode)
    {
        case CompositionMode.Symmetrical:
            DrawSymmetricalComposition(camera);
            break;
        case CompositionMode.Bisection:
            DrawBisectionComposition(camera);
            break;
        case CompositionMode.Thirds:
            DrawThirdsComposition(camera);
            break;
        case CompositionMode.Diagonal:
            DrawDiagonalComposition(camera);
            break;
    }
}

それぞれの描画先の関数を用意します。カメラの下と右が0、上と左が1です。camera.nearClipPlaneにそのまま表示させるとfloatの誤差で表示されない場合があるので+0.1f奥にずらしています。

// 対称
private void DrawSymmetricalComposition(Camera camera)
{
    // 縦線
    Gizmos.DrawLine(
        camera.ViewportToWorldPoint(new Vector3(0.5f, 0, camera.nearClipPlane + 0.1f)),
        camera.ViewportToWorldPoint(new Vector3(0.5f, 1, camera.nearClipPlane + 0.1f))
    );
}
// 二分割構図
private void DrawBisectionComposition(Camera camera)
{
    // 縦線
    Gizmos.DrawLine(
        camera.ViewportToWorldPoint(new Vector3(0.5f, 0, camera.nearClipPlane + 0.1f)),
        camera.ViewportToWorldPoint(new Vector3(0.5f, 1, camera.nearClipPlane + 0.1f))
    );
    // 横線
    Gizmos.DrawLine(
        camera.ViewportToWorldPoint(new Vector3(0, 0.5f, camera.nearClipPlane + 0.1f)),
        camera.ViewportToWorldPoint(new Vector3(1, 0.5f, camera.nearClipPlane + 0.1f))
    );
}
// 三分割構図
private void DrawThirdsComposition(Camera camera)
{
    // 縦線
    Gizmos.DrawLine(
        camera.ViewportToWorldPoint(new Vector3(1.0f / 3.0f * 1, 0, camera.nearClipPlane + 0.1f)),
        camera.ViewportToWorldPoint(new Vector3(1.0f / 3.0f * 1, 1, camera.nearClipPlane + 0.1f))
    );
    Gizmos.DrawLine(
        camera.ViewportToWorldPoint(new Vector3(1.0f / 3.0f * 2, 0, camera.nearClipPlane + 0.1f)),
        camera.ViewportToWorldPoint(new Vector3(1.0f / 3.0f * 2, 1, camera.nearClipPlane + 0.1f))
    );
    // 横線
    Gizmos.DrawLine(
        camera.ViewportToWorldPoint(new Vector3(0, 1.0f / 3.0f * 1, camera.nearClipPlane + 0.1f)),
        camera.ViewportToWorldPoint(new Vector3(1, 1.0f / 3.0f * 1, camera.nearClipPlane + 0.1f))
    );
    Gizmos.DrawLine(
        camera.ViewportToWorldPoint(new Vector3(0, 1.0f / 3.0f * 2, camera.nearClipPlane + 0.1f)),
        camera.ViewportToWorldPoint(new Vector3(1, 1.0f / 3.0f * 2, camera.nearClipPlane + 0.1f))
    );
}

// 対角線
private void DrawDiagonalComposition(Camera camera)
{
    // 縦線
    Gizmos.DrawLine(
        camera.ViewportToWorldPoint(new Vector3(0, 0, camera.nearClipPlane + 0.1f)),
        camera.ViewportToWorldPoint(new Vector3(1, 1, camera.nearClipPlane + 0.1f))
    );
    // 横線
    Gizmos.DrawLine(
        camera.ViewportToWorldPoint(new Vector3(1, 0, camera.nearClipPlane + 0.1f)),
        camera.ViewportToWorldPoint(new Vector3(0, 1, camera.nearClipPlane + 0.1f))
    );
}

他にも構図はあるのでぜひ自分に合った構図のプリセットを用意してみてください。

23/06/27 githubにコードとか整理したプロジェクトを追加しました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?