호우동의 개발일지

Today :

article thumbnail

Event

OnGUI()를 호출하는 주체(OnGUI 보다 Low-Level)

- 사용자와의 입력과 상호작용
- 트리거들을 공통적으로 처리하는 예약된 함수들이 정의되어 있다

- 효율성을 위해 OnGUI() 내부 코드와 현재 Event의 관계 여부에 따라 무시할 수 있음

1. 현재 이벤트가 드로잉이 아닌데, 드로잉 관련 코드를 만나면 그 코드를 무시
2. MouseClick 이벤트로 OnGUI()가 호출되면 해당 흐름에서는 Drawing 수행 코드 무시

 


Event 종류

Event.current: 현재 OnGUI()를 호출하게 된 Event
Layout Event: Repaint 전 GUI들의 배치 값 관련 수집 이벤트


유니티 상단에 MyTool/OpenTool을 눌러 생성된 창 위에
마우스를 올리고 클릭, 드래그 등을 해보면

다양한 Mouse Event 종류를 확인할 수 있음

예시

 


GUI가 그려지는(Drawing) 과정

1. Layout Event 발생

- 실제로 Drawing이 되는 것은 아니다
- 전체 코드를 훑으면서 레이아웃 관련 함수들과 GUI에 대한 정보를 조사한다.
- 어디에 어떤 컨트롤(GUI 요소)을 배치해야 되나 조사

 

2. Repaint Event 발생

- 실제 Drawing 수행
- Layout Event에서 GUI 배치에 대한 조사가 끝난 상태이기 때문에 가능

 


코드 분석

위에 있던 코드를 그대로 가져와서 분석해 보겠다.

private void OnGUI()
{
    // area = Begin ~ end 사이에 그려진 모든 GUI들의 크기
    var area = EditorGUILayout.BeginVertical(GUILayout.Width(200));

    GUI.Box(area, GUIContent.none);

    EditorGUILayout.LabelField("ABC");
    EditorGUILayout.LabelField("ABC");

    EditorGUILayout.EndVertical();
}

Q. 변수 area를 선입력 받았는데 어떻게 Label에 대한 크기 정보를 담을 수 있나?


- Layout Event 단계에서 Label의 크기 정보를 미리 조사했기 때문에- Repaint Event 단계에서 GUI.Box(area,GUIContent.none) 을 통해 GUI를 그리게 된다.

 


특정 입력 식별하기

private void OnGUI()
{
    // 키보드를 누르는 이벤트일 경우 
    if (Event.current.type == EventType.KeyDown)
    {
        if (Event.current.keyCode == KeyCode.Q
            || Event.current.keyCode == KeyCode.W
            || Event.current.keyCode == KeyCode.E)
            Debug.Log($"Key is down:{Event.current.keyCode}");
    }

    // 마우스 버튼 누름 && 왼쪽 마우스 이벤트 
    if(Event.current.type == EventType.MouseDown && Event.current.button == 0)
    {
        Debug.Log("Left mouse button is down");
    }
}

- Event.current.type을 통해 해당 이벤트의 종류를 구분한다.
- Event.current.KeyCode는 해당 키 입력이 어떤 키 입력인가를 알려준다.
- Event.current.button = 0 / 1 -> 왼쪽 마우스 / 오른쪽마우스

 

상호작용 검사

- My Tool 창 안에서 QWE, 왼쪽 마우스 클릭을 제외한 다른 상호작용은 동작하지 않는다.
- QWE과 왼쪽 마우스 클릭은 코드대로 정상 작동하는 것을 Log에서 확인할 수 있다.


이벤트 소거(제거)

private void OnGUI()
{

    // 마우스 클릭상태 (클릭이벤트 발생) 
    if (Event.current.isMouse)
    {

        //현재 사용하는 이벤트를 없앰
        Event.current.Use();
    }
    if (GUILayout.Button("Button"))
    {
        Debug.Log("Clicked");
    }
}

- Event.curruent.Use()를 사용해서 현재 사용하는 이벤트를 없앤다.
-> Use 안에 공백이기 때문에 어떤 이벤트도 사용하지 않는다는 의미

- Button() 함수는 내부적으로 MouseEvent일 때만 동작한다.
-> Event.current.Use()로 인해 MouseEvent가 제거되었기 때문에 동작 X

동작 확인

버튼을 아무리 눌러도 동작하지 않는 것을 확인할 수 있다(Log가 안 뜬다.)