Version: 2023.2
언어: 한국어
커스텀화
IMGUI 확장

IMGUI 레이아웃 모드

고정 레이아웃 대 자동 레이아웃

IMGUI 시스템을 사용할 때 UI를 정렬하고 구성하는 데 사용할 수 있는 고정 및 자동의 두 가지 모드가 있습니다. 지금까지 이 가이드에 제공된 모든 IMGUI 예제에는 고정 레이아웃이 사용되었습니다. 자동 레이아웃을 사용하려면 컨트롤 함수를 호출할 때 GUI 대신 GUILayout 을 작성해야 합니다. 하나의 레이아웃 모드를 다른 모드보다 많이 사용할 필요는 없으며 동일한 OnGUI() 함수에서 두 모드를 동시에 사용할 수 있습니다.

고정 레이아웃은 사전에 설계된 인터페이스를 사용할 때 사용하는 것이 좋습니다. 자동 레이아웃은 앞에 필요한 요소의 수를 모르는 경우나 각 컨트롤을 손으로 배치하는 것에 대해 신경쓰고 싶지 않을 때 사용하는 것이 좋습니다. 예를 들어, 게임 저장 파일을 기반으로 여러 버튼을 만드는 경우 정확히 몇 개의 버튼이 그려지는지 알 수 없습니다. 이 경우 자동 레이아웃이 더 적합할 수 있습니다. 어떤 것을 선택할지는 게임의 설계와 인터페이스를 표현하는 방법에 달려 있습니다.

자동 레이아웃을 사용하는 경우 다음과 같이 두 가지 중요한 차이점이 있습니다.

  • GUI 대신 GUILayout 이 사용됩니다.
  • 자동 레이아웃 컨트롤에는 Rect() 함수가 필요하지 않습니다.
/* Two key differences when using Automatic Layout */


// JavaScript
function OnGUI () {
    // Fixed Layout
    GUI.Button (Rect (25,25,100,30), "I am a Fixed Layout Button");

    // Automatic Layout
    GUILayout.Button ("I am an Automatic Layout Button");
}


// C#
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour {
    
    void OnGUI () {
        // Fixed Layout
        GUI.Button (new Rect (25,25,100,30), "I am a Fixed Layout Button");
    
        // Automatic Layout
        GUILayout.Button ("I am an Automatic Layout Button");
    }

}


컨트롤 정렬

사용 중인 레이아웃 모드에 따라 컨트롤 포지션 배치와 그룹화 방법을 제어하기 위한 여러 가지 후크가 있습니다. 고정 레이아웃 모드에서는 다른 컨트롤을 Groups 로 나눌 수 있으며, 자동 레이아웃 모드에서는 다른 컨트롤을 Areas, Horizontal Groups, Vertical Groups 로 나눌 수 있습니다.

고정 레이아웃 - 그룹

그룹은 고정 레이아웃 모드에서 사용 가능한 규칙입니다. 그룹을 통해 여러 컨트롤이 포함된 스크린 영역을 정의할 수 있습니다. GUI.BeginGroup()GUI.EndGroup() 함수를 사용하여 그룹 내부의 컨트롤을 정의합니다. 그룹 내부의 모든 컨트롤은 스크린의 왼쪽 상단 코너 대신 그룹의 왼쪽 상단 코너를 기반으로 배치됩니다. 이렇게 하면 런타임 시점에 그룹의 포지션을 ​​변경할 경우 그룹의 모든 컨트롤의 상대적 포지션이 유지됩니다.

예를 들어 여러 컨트롤을 스크린 중앙에 쉽게 배치할 수 있습니다.

/* Center multiple Controls on the screen using Groups */


// JavaScript
function OnGUI () {
    // Make a group on the center of the screen
    GUI.BeginGroup (Rect (Screen.width / 2 - 50, Screen.height / 2 - 50, 100, 100));
    // All rectangles are now adjusted to the group. (0,0) is the topleft corner of the group.
    
    // We'll make a box so you can see where the group is on-screen.
    GUI.Box (Rect (0,0,100,100), "Group is here");
    GUI.Button (Rect (10,40,80,30), "Click me");
    
    // End the group we started above. This is very important to remember!
    GUI.EndGroup ();
}


// C#
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour {
    
    void OnGUI () {
        // Make a group on the center of the screen
        GUI.BeginGroup (new Rect (Screen.width / 2 - 50, Screen.height / 2 - 50, 100, 100));
        // All rectangles are now adjusted to the group. (0,0) is the topleft corner of the group.
    
        // We'll make a box so you can see where the group is on-screen.
        GUI.Box (new Rect (0,0,100,100), "Group is here");
        GUI.Button (new Rect (10,40,80,30), "Click me");
    
        // End the group we started above. This is very important to remember!
        GUI.EndGroup ();
    }

}


위의 예제는 스크린 해상도에 관계없이 컨트롤을 가운데에 배치합니다.
위의 예제는 스크린 해상도에 관계없이 컨트롤을 가운데에 배치합니다.

서로 여러 그룹을 중첩할 수도 있습니다. 이렇게 하면 각 그룹의 콘텐츠가 부모의 공간에 클리핑됩니다.

/* Using multiple Groups to clip the displayed Contents */


// JavaScript
var bgImage : Texture2D; // background image that is 256 x 32
var fgImage : Texture2D; // foreground image that is 256 x 32
var playerEnergy = 1.0; // a float between 0.0 and 1.0

function OnGUI () {
    // Create one Group to contain both images
    // Adjust the first 2 coordinates to place it somewhere else on-screen
    GUI.BeginGroup (Rect (0,0,256,32));

    // Draw the background image
    GUI.Box (Rect (0,0,256,32), bgImage);
    
    // Create a second Group which will be clipped
    // We want to clip the image and not scale it, which is why we need the second Group
    GUI.BeginGroup (Rect (0,0,playerEnergy * 256, 32));

    // Draw the foreground image
    GUI.Box (Rect (0,0,256,32), fgImage);

    // End both Groups
    GUI.EndGroup ();
    GUI.EndGroup ();
}


// C#
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour {
    
    // background image that is 256 x 32
    public Texture2D bgImage; 
    
    // foreground image that is 256 x 32
    public Texture2D fgImage; 
    
    // a float between 0.0 and 1.0
    public float playerEnergy = 1.0f; 
    
    void OnGUI () {
        // Create one Group to contain both images
        // Adjust the first 2 coordinates to place it somewhere else on-screen
        GUI.BeginGroup (new Rect (0,0,256,32));
    
        // Draw the background image
        GUI.Box (new Rect (0,0,256,32), bgImage);
    
            // Create a second Group which will be clipped
            // We want to clip the image and not scale it, which is why we need the second Group
            GUI.BeginGroup (new Rect (0,0,playerEnergy * 256, 32));
        
            // Draw the foreground image
            GUI.Box (new Rect (0,0,256,32), fgImage);
        
            // End both Groups
            GUI.EndGroup ();
        
        GUI.EndGroup ();
    }

}


그룹을 중첩하여 클리핑 동작을 만들 수 있습니다.
그룹을 중첩하여 클리핑 동작을 만들 수 있습니다.

자동 레이아웃 - 영역

영역은 자동 레이아웃 모드에서만 사용됩니다. GUILayout 컨트롤을 포함하는 스크린의 한정된 부분을 정의하므로 고정 레이아웃 그룹과 기능 면에서 비슷합니다. 자동 레이아웃의 특성상 거의 항상 영역을 사용합니다.

자동 레이아웃 모드에서는 컨트롤 수준에서 컨트롤이 그려지는 스크린 영역을 정의하지 않습니다. 컨트롤은 포함된 영역의 가장 왼쪽 위의 지점에 자동으로 배치됩니다. 이것은 스크린일 수 있습니다. 수동으로 배치된 영역을 만들 수도 있습니다. 영역 내부의 GUILayout 컨트롤은 해당 영역의 가장 왼쪽 위에 배치됩니다.

/* A button placed in no area, and a button placed in an area halfway across the screen. */


// JavaScript
function OnGUI () {
    GUILayout.Button ("I am not inside an Area");
    GUILayout.BeginArea (Rect (Screen.width/2, Screen.height/2, 300, 300));
    GUILayout.Button ("I am completely inside an Area");
    GUILayout.EndArea ();
}


// C#
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour {
    
    void OnGUI () {
        GUILayout.Button ("I am not inside an Area");
        GUILayout.BeginArea (new Rect (Screen.width/2, Screen.height/2, 300, 300));
        GUILayout.Button ("I am completely inside an Area");
        GUILayout.EndArea ();
    }

}


영역 내부에서 버튼과 박스 등의 시각적 요소가 있는 컨트롤은 영역의 전체 길이까지 늘어납니다.

자동 레이아웃 - 가로 및 세로 그룹

자동 레이아웃을 사용하면 기본적으로 컨트롤이 위에서 아래로 배열됩니다. 하지만 컨트롤의 위치와 배치를 세밀하게 조절하고자 하는 경우가 많습니다. 자동 레이아웃 모드를 사용하는 경우에는 수직 및 수평 그룹 옵션을 사용할 수 있습니다.

다른 레이아웃 컨트롤과 마찬가지로 이 그룹을 시작하거나 끝내기 위해 별도의 함수를 호출합니다. 특정 함수는 GUILayout.BeginHorizontal(), GUILayout.EndHorizontal(), GUILayout.BeginVertical()GUILayout.EndVertical() 입니다.

수평 그룹의 컨트롤은 항상 수평으로 배열되며, 수직 그룹의 컨트롤은 항상 수직으로 배열됩니다. 물론 그룹 안에 다른 그룹을 삽입할 수도 있습니다. 이렇게 하면 컨트롤이 몇 개라도 원하는 방법으로 컨트롤을 배치할 수 있습니다.

/* Using nested Horizontal and Vertical Groups */


// JavaScript
var sliderValue = 1.0;
var maxSliderValue = 10.0;

function OnGUI()
{
    // Wrap everything in the designated GUI Area
    GUILayout.BeginArea (Rect (0,0,200,60));

    // Begin the singular Horizontal Group
    GUILayout.BeginHorizontal();

    // Place a Button normally
    if (GUILayout.RepeatButton ("Increase max\\
Slider Value"))
    {
        maxSliderValue += 3.0 * Time.deltaTime;
    }

    // Arrange two more Controls vertically beside the Button
    GUILayout.BeginVertical();
    GUILayout.Box("Slider Value: " + Mathf.Round(sliderValue));
    sliderValue = GUILayout.HorizontalSlider (sliderValue, 0.0, maxSliderValue);

    // End the Groups and Area
    GUILayout.EndVertical();
    GUILayout.EndHorizontal();
    GUILayout.EndArea();
}


// C#
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour {
    
    private float sliderValue = 1.0f;
    private float maxSliderValue = 10.0f;
    
    void OnGUI()
    {
        // Wrap everything in the designated GUI Area
        GUILayout.BeginArea (new Rect (0,0,200,60));
    
        // Begin the singular Horizontal Group
        GUILayout.BeginHorizontal();
    
        // Place a Button normally
        if (GUILayout.RepeatButton ("Increase max\\
Slider Value"))
        {
            maxSliderValue += 3.0f * Time.deltaTime;
        }
    
        // Arrange two more Controls vertically beside the Button
        GUILayout.BeginVertical();
        GUILayout.Box("Slider Value: " + Mathf.Round(sliderValue));
        sliderValue = GUILayout.HorizontalSlider (sliderValue, 0.0f, maxSliderValue);
    
        // End the Groups and Area
        GUILayout.EndVertical();
        GUILayout.EndHorizontal();
        GUILayout.EndArea();
    }

}


가로 및 세로 그룹으로 정렬된 세 개의 컨트롤
가로 및 세로 그룹으로 정렬된 세 개의 컨트롤

GUILayoutOptions를 사용하여 일부 컨트롤 정의

GUILayoutOptions을 사용하여 자동 레이아웃 파라미터의 일부를 오버라이드할 수 있습니다. 이는 GUILayout 컨트롤의 마지막 파라미터로 옵션을 제공하면 됩니다.

위의 영역 예제에서 버튼은 영역 너비의 100%까지 늘어납니다. 필요할 경우 이를 오버라이드할 수 있습니다.

/* Using GUILayoutOptions to override Automatic Layout Control properties */


//JavaScript
function OnGUI () {
    GUILayout.BeginArea (Rect (100, 50, Screen.width-200, Screen.height-100));
    GUILayout.Button ("I am a regular Automatic Layout Button");
    GUILayout.Button ("My width has been overridden", GUILayout.Width (95));
    GUILayout.EndArea ();
}


// C#
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour {
        
    void OnGUI () {
        GUILayout.BeginArea (new Rect (100, 50, Screen.width-200, Screen.height-100));
        GUILayout.Button ("I am a regular Automatic Layout Button");
        GUILayout.Button ("My width has been overridden", GUILayout.Width (95));
        GUILayout.EndArea ();
    }

}


사용할 수 있는 GUILayoutOptions 전체 리스트는 GUILayoutOption 스크립팅 레퍼런스 페이지를 참조하십시오.

커스텀화
IMGUI 확장