자가라 노트

Unity

[Unity] Attribute 애트리뷰트

자가라o 2021. 8. 13. 21:00

Attribute(속성) 는 class 의 위에 표시 되어, 스크립트 프로퍼티나 함수에 특별한 동작을 나타냅니다.

유니티 - Attribute(속성) 문서

 


1. 인스펙터 노출 관련 Attribute

 

[SerializeField]

  • 데이터를 직렬화 해주는 기능으로 변수 위 혹은 왼쪽에 선언됩니다.
  • private, protected로 선언된 변수들을 public 변수와 같이 inspector에서 수정가능하게 해줍니다.
  • public과의 차이점 - 사실상 private, protected 선언이기 때문에 다른 클래스에서 접근할 수는 없습니다.
public class SomeClass : MonoBehaviour
{
    [SerializeField]
    private int intValue = 2;
    [SerializeField]
    protected float floatValue = 3f;
}

 

[System.Serializable]

  • inspector에 보이지 않는 class, struct 변수를 일반변수처럼 inspector에 노출 및 수정하고자 사용됩니다.
  • 해당 class, struct를 직렬화하여 inspector에서 수정 및 확인이 가능합니다.
[Serializable]
public class ClassA
{
    public int a;
    public int b;
}

public class SomeClass : MonoBehaviour
{
    public ClassA _classA;
}

 

[System.Nonserialized] vs [HideInInspector]

  • Nonserialized와 HideInInspector 기능 - public으로 선언된 변수를 inspector에서 숨기고자 할때 사용됩니다.
  • 차이점은 Attribute 설정이전 inspector에서 값을 변경하고 Attribute를 설정했을때
    • HideInInspector는 변경한 값이 저장되지만
    • Nonserialized는 변경한 값이 저장되지 않으며 재생시 기본값으로 재설정됩니다.
public class SomeClass : MonoBehaviour
{
    [NonSerialized]
    public int _intValue;

    [HideInInspector]
    public float _floatValue;

    private void Start()
    {
        Debug.Log(_intValue);
        Debug.Log(_floatValue);
    }
}

Attribute 설정전 inspector에서 값 설정
Attribute 설정 후 실행 로그

 


2. inspector 관련 소소한 커스텀

 

[Header(string)]

  • 매개변수로 헤더로 사용할 string 형식의 단어를 넘겨줍니다.
  • inspector에서 변수를 구분지어 보고 싶을때 사용합니다.
public class SomeClass : MonoBehaviour
{
    [Header("숫자")]
    public int _number;
    public int _count;

    [Header("String")]
    public string _name;
    public string _title;
}

 

[Space] / [Space(float)]

  • float값은 비워줄 공간의 길이입니다.
  • 값을 넣지않으면 기본값으로 설정됩니다.
public class SomeClass : MonoBehaviour
{
    public int _number;
    [Space]
    public int _count;
    [Space(50)]
    public string _name;
}

 

[Tooltip(string)]

  • ToolTip 매기변수로 string 형식의 설명을 넘겨줍니다.
  • inspector에서 변수명에 마우스를 올렸을때 설명이 나타납니다.
public class SomeClass : MonoBehaviour
{
    [Tooltip("이런저런 내용")]
    public int _number;
}

 

[HelpURL(string형식의 주소)]

  • 클래스 상단에 선언하며 매개변수로 string형식의 주소를 넘겨줍니다.
  • inspector의 component에서 물음표를 누르면 연결된 링크가 열립니다.
[HelpURL("https://zagara.tistory.com/")]
public class SomeClass : MonoBehaviour
{

}

 


 

3. inspector의 변수 관련 커스텀

 

[Range(float min, float max)]

  • int, float 숫자 형식의 변수에 사용가능합니다.
  • inspector에서 편집시 설정된 min, max 값 이내에서만 수정이 가능합니다.
  • 코드에서 수정시 최초에 범위를 벗어나는 값을 입력했다면 초기화하는 부분에서 범위 이내로 수정해주지만 그 이후 변경되는 사항에 대해서는 그대로 적용됩니다.
public class SomeClass : MonoBehaviour
{
    [Range(-3f, 5f)]
    public float _range = -8f;

    private void Start()
    {
        Debug.Log(_range);
        _range = 8;
        Debug.Log(_range);
    }
}

최초 설정된 -8은 범위값인 -3으로 수정해주지만 실행이후 변경된 값이 8의 경우 그대로 적용된 것을 볼 수 있습니다.

 

[ColorUsage(bool 알파값활성화여부, bool HDR활성화 여부)]

  • color에 적용가능한 Attribute로 알파값을 없애거나 HDR을 활성화 할 수 있습니다.
public class SomeClass : MonoBehaviour
{
    // 첫번째 매개변수 - 알파값 활성화 여부
    // 두번째 매개변수 - HDR 활성화 여부
    [ColorUsage(false, true)] 
    public Color _color;
}

알파가 없어지고 HDR이 생긴것을 확인할 수 있습니다.

 

[Multiline(int)] vs [TextArea(int min, int max)]

  • 둘다 긴 내용을 설정하거나 노출하고자 할때 사용됩니다.
  • Multiline은 매개변수로 int형식의 줄 갯수를 받으며 내용을 입력하더라도 크기 변화없이 박스내에서 작성됩니다.
  • TextArea는 매개변수로 int형식의 min,max 줄 갯수를 받으며 내용의 길이에 따라 범위내에서 유동적으로 변합니다.
    • 또 TextArea는 최대 줄수 초과시 스크롤바가 생성됩니다.
public class SomeClass : MonoBehaviour
{
    [Multiline(5)]
    public string _string0;
    [TextArea(2,5)]
    public string _string1;
}

 


 

4. 에디터 관련 소소한 커스텀

 

[AddComponentMenu(string 형식의 루트)]

  • 매개변수로 string형식의 루트 혹은 Component이름을 넣으면 inspector의 Add Component에 카테고리로 분류가 됩니다.
  • 루트를 넣지않으면 Component가 바로 노출되고
  • 루트를 넣으면 카테고리가 하위에 Component가 생성됩니다.
  • 이미 생성된 카테고리의 이름을 루트로 설정해도 해당 카테고리의 하위로 생성됩니다.
[AddComponentMenu("ThisIsTest")]
public class SomeClass : MonoBehaviour
{
    public string _string;
}

 

[UnityEditor.MenuItem(string 형식의 루트/정적 메소드명)]

  • MenuItem는 매개변수로 string형식의 루트와 실행할 정적 메소드를 받으며 상단의 메뉴바에 배치됩니다.
  • 지금까지 다른 Attribute들은 루트가 필수가 아니었지만 MenuItem은 루트가 필수적으로 포함되어야 합니다.
  • 사용될 메소드는 정적메소드로 선언되어야 합니다.
public class SomeClass : MonoBehaviour
{
    public string _string;

    [UnityEditor.MenuItem("TestEditor/MenuItemTest")]
    static void MenuItemTest()
    {
        Debug.Log("MenuItemTest");
    }
}

상단메뉴바에 배치된 모습
실행결과

 

[ContextMenu(string 형식의 메소드명)]

  • 매개변수로 실행하려는 메소드명을 넣어주면 됩니다.
  • Component를 우클릭하여 뜨는 메뉴의 하단에 삽입됩니다.
public class SomeClass : MonoBehaviour
{
    // 루트 없음
    [ContextMenu("MenuItemNoRoot")]
    void MenuItemNoRoot()
    {
        Debug.Log("MenuItemNoRoot");
    }

    // 루트 있음
    [ContextMenu("TestEditor/MenuItemRoot")]
    void MenuItemRoot()
    {
        Debug.Log("MenuItemRoot");
    }
}

 

[ContextMenuItem(string 형식의 이름, string 형식의 메소드명)]

  • 관련된 필드위에 선언하여 inspector에서 해당 필드를 우클릭하여 실행할 수 있습니다.
  • 첫번째 매개변수는 노출되는 이름 / 두번째 매개변수는 실행하려는 메소드명을 넣어줍니다.
public class SomeClass : MonoBehaviour
{
    [ContextMenuItem("reset", "resetNumber")]
    [ContextMenuItem("setFive", "setNumberFive")]
    public int _number;
    
    void resetNumber()
    {
        _number = 0;
    }

    void setNumberFive()
    {
        _number = 5;
    }
}

 


 

5. Component 관련 Attribute

 

[System.Obsolete]

  • class 상단에 선언하여 사용되며 선언시 inspector에 이 Component는 사용되지 않는다는 경고문이 노출됩니다.
  • 사용에는 지장이 없습니다.
[System.Obsolete]
public class SomeClass : MonoBehaviour
{

}

해당 Component는 사용되지않는다고 경고가 뜬다.

 

[ExecuteInEditMode]

  • 플레이 상태가 아닐때도 업데이트가 코드가 호출됩니다.
  • 하지만 플레이 상태일때처럼 매프레임 호출되진않고 에디터상의 변경이 있을때만 호출됩니다.
    • 에디터 창크기변경
    • inspector를 포함한 Tap안에서의 값, 구조변경 등등
[ExecuteInEditMode]
public class SomeClass : MonoBehaviour
{
    [Range(-5f,5f)]
    public float _num;

    public float _number;
    private void Update()
    {
        _number += Time.deltaTime;
        Debug.Log(_number);
    }
}

[Range]를 사용한 float값 변경시에도 호출됩니다.

 

[RequireComponent(typeof(Component))]

  • 매개변수로는 Component를 typeof(Component)형식으로 넣어줍니다.
  • 매개변수로 넘겨준 Component는 오브젝트에 해당 클래스 Component를 Add Component시 함께 추가됩니다.
[RequireComponent(typeof(BoxCollider))]
public class SomeClass : MonoBehaviour
{

}

 

[DisallowMultipleComponent]

  • Component가 2개 이상 중복으로 적용되지 않도록 해줍니다.
[DisallowMultipleComponent]
public class SomeClass : MonoBehaviour
{

}

2개이상 추가시 오류메세지가 뜹니다.

 

[CreateAssetMenu(fileName = string 형식의 파일 이름, menuName = string 형식의 루트)]

  • CreateAssetMenu은 ScriptableObject 스크립트를 이용해서 에셋을 생성할 수 있게 만들어줍니다.
  • Project 탭에서 우클릭 했을때 Create 하위에 생성됩니다.
  • MonoBehaviour가 아닌 ScriptableObject를 상속하여 만들어진 클래스에만 사용 가능합니다.
[CreateAssetMenu(fileName = "Test Data", menuName = "Scriptable Object/Test Data")]
public class SomeClass : ScriptableObject
{
    public int _numA;
    public int _numB;
    public int _numC;
}