[개발일지] 5. 버튼 눌렀을 때 뒤에 있는 타일(게임 오브젝트)은 안 눌리도록 하는 방법

2024. 7. 16. 00:24·유니티 프로젝트/케이크게임

[원하는 기능]

  • 버튼을 눌렀을때 뒤에 있는 타일 안 눌리도록 하는 기능  

[공부한 내용]

  유니티에서 UI 요소가 클릭되었을 때, 뒤에 있는 타일이 클릭되지 않도록 하려면 GraphicRaycaster와 EventSystem이 올바르게 설정되어 있는지 확인해야 한다.


 

  1. Canvas 설정 확인
    • Canvas 오브젝트가 있는지 확인한다. Canvas 오브젝트는 UI 요소들이 포함되어야 한다.
    • Canvas 오브젝트에 GraphicRaycaster 컴포넌트가 추가되어 있는지 확인한다(기본적으로 포함되어 있다).
    • Canvas 의 Render Mode 가 Screen Space - Overlay 또는 Screen Space - Camera 로 설정되어 있는지 확인한다. 
  2. EventSystem 설정확인
    • EventSystem 오브젝트가 있는지 확인한다(EventSystem은 UI 이벤트를 처리하는 데 필요함).
    • 만약 EventSystem 오브젝트가 없다면, Hierarchy 창에서 우클릭하여 UI > Event System을 선택하여 추가한다.
  3. UI 요소의 Raycast Target 설정 확인
    • UI 요소(버튼, 이미지 등)의 Raycast Target 속성이 활성화되어 있는지 확인한다.
    • 버튼의 경우, Button 컴포넌트는 기본적으로 Image 컴포넌트를 포함하고 있으며, Image 컴포넌트의 Raycast Target 속성이 활성화되어 있어야 한다.

 

[코드]

 

private bool IsPointerOverUIObject()
{
    PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current)
    {
        position = new Vector2(Input.mousePosition.x, Input.mousePosition.y)
    };
    List<RaycastResult> results = new List<RaycastResult>();
    EventSystem.current.RaycastAll(eventDataCurrentPosition, results);
    return results.Count > 0;
}
void Update()
{
    // 버튼 눌렀을 때 뒤에 있는 타일 못 누르도록 하기 위한 구문..
    if (IsPointerOverUIObject()) return;

    // 땅을 왼쪽 마우스키로 누르면..
    if (Input.GetMouseButtonUp(0))
    {
        // 땅에 아무것도 안 한 상태는 plow 버튼을 갖고, 갈린 상태는 버튼으로 plant 버튼을 갖는다.
        // 다른 땅을 클릭하면 전에 클릭한 땅의 버튼은 안 보여야 하므로 SetActive 로 안보이게 조정한다..
        // 수확하기 버튼은 과일이 다 자라면 계속 보여야함..
        if (farmEnableZoneTilemap.HasTile(prevSelectTile))
        {
            if (farmingData[prevSelectTile].currentState == "None" || farmingData[prevSelectTile].currentState == "plow")
            {
                farmingData[prevSelectTile].stateButton.gameObject.SetActive(false);
            }
        }

        // 현재 마우스 위치를 게임 월드 위치로 바꿔서 저장
        clickPosition = mainCamera.ScreenToWorldPoint(Input.mousePosition);
        // 게임 월드 위치를 타일 맵의 타일 셀 위치로 변환
        cellPosition = farmTilemap.WorldToCell(clickPosition);
        

        foreach (Vector3Int pos in farmingData.Keys)
        {
            // 저장해놓은 타일 중에 현재 마우스로 클릭한 위치랑 같은 타일이 있으면
            if (pos == cellPosition)
            {
                // 현재 선택한 타일의 버튼은 활성화 되도록..
                farmingData[cellPosition].stateButton.gameObject.SetActive(true);
                // 아래 방법처럼 하면 오류남. 이유는 뭐지??
                // --> GameObject 는 컴포넌트가 아니라서 오류가 나는 것이었다... 이번 기회에 알게 됐다.
                // --> 그냥 gameObject 로 바로 게임 오브젝트에 접근할 수 있었다.
                // --> 기본적인걸 까먹고 있었다.. 이번엔 잘 기억하자..
                //farmingData[cellPosition].stateButton.GetComponent<GameObject>().SetActive(true);
            }
        }

        prevSelectTile = cellPosition; // 지금 누른 타일을 이전에 누른 타일 위치를 저장하는 변수에 저장.. 
    }


    foreach (Vector3Int pos in farmingData.Keys)
    {
        if (farmingData[pos].seed != null)
        {
            if (farmingData[pos].seed.isGrown)
            {
                farmingData[pos].harvestEnableState = true; // 작물 수확할 수 있는 상태
                farmingData[pos].stateButton.gameObject.SetActive(true); // 수확하기 버튼은 항상 떠있어야 함
                farmingData[pos].currentState = "harvest";
            }
        }
    }
}
  • PointerEventData: 마우스의 현재 위치를 기준으로 PointerEventData 객체를 생성한다.
    • PointerEventData 는 이벤트 시스템의 입력 데이터를 나타내는 클래스 
  • RaycastAll 호출: 현재 이벤트 시스템에서 모든 UI 요소에대해 레이캐스트를 실행하여 해당 위치에 있는 모든 UI 요소를 감지한다.
    • EventSystem.current.RaycastAll 메서드를 사용해서 현재 이벤트 시스템에서 모든 UI 요소에 대해 레이캐스트를 실행한다.
    • 레이캐스트 결과는 results 리스트에 저장된다.
  • 레이캐스트 결과를 확인하여 하나 이상의 UI 요소가 감지되었는지 확인하다. 감지된 경우 마우스 포인터가 UI 요소 위에 있다고 판단한다.
  • if (IsPointerOverUIObject()) return; 이 구문은, 조건문이 true 일 때 해당 프레임에서는 이후 코드가 실행되지 않고, 다음 프레임에서 다시 Update 메서드가 호출되면서 처음부터 코드를 실행하게 된다(Update 메서드는 매 프레임마다 다시 호출된다).
  • IsPointerOverUIobject() 함수는 마우스 포인터가 UI 요소 위에 있는 동안 계속해서 true 를 반환한다. EventSystem 을 통해 마우스 위치에서 모든 UI 요소에대해 레이캐스트를 수행하고, 하나 이상의 UI 요소가 감지되면 true 를 반환하는 방식이다. 

 


 

[참고자료]

https://docs.unity3d.com/kr/530/ScriptReference/EventSystems.PointerEventData.html

 

EventSystems.PointerEventData - Unity 스크립팅 API

Event payload associated with pointer (mouse / touch) events.

docs.unity3d.com

 

https://code-piggy.tistory.com/entry/Unity-PointerEventData

 

Unity - PointerEventData class

PointerEventData class Unity 엔진에서 사용되는 UnityEngine.EventSystems 클래스 중 하나이다. UI 이벤트 시스템과 함께 사용되며, UI 요소에 대한 포인터(mouse/touch) 입력 관련 정보를 처리하기 위해 사용된다.

code-piggy.tistory.com

 

https://godnr149.tistory.com/73

 

PointerEventData

PointerEventData Event payload associated with pointer (mouse / touch) events. 터치하고 있는 상태나 마우스를 클릭하고 있는 상황 (연속적으로 Input.GetKey() 상태를 유지하고 있을 때) 에서 특정 액션을 취할 수 있

godnr149.tistory.com

 

https://gameneo.medium.com/unity-raycast-%ED%84%B0%EC%B9%98-%EA%B5%AC%ED%98%84-%EC%8B%9C-ui-%EC%95%84%EB%9E%98-gameobject-%ED%84%B0%EC%B9%98-%EB%B0%A9%EC%A7%80%ED%95%98%EA%B8%B0-ea0f74534a41

 

[Unity] Raycast 터치 구현 시 UI 아래 GameObject 터치 방지하기

GameObject를 Raycast로 터치 처리 시 UI가 GameObject위에 있는 경우에도 GameObject가 터치되는 경우가 발생합니다.

gameneo.medium.com

 

'유니티 프로젝트/케이크게임' 카테고리의 다른 글
  • [개발일지] 7. 현재까지 구현한 기능 정리
  • [개발일지] 6. 주석 깨짐 현상 해결하기
  • [개발일지] 4. 씨앗 심기 & 수확하기 (+ 수확하기 버튼)
  • [개발일지] 3. 경계 내부 구간만 타일 변경
dubu0721
dubu0721
dubu0721 님의 블로그 입니다.
  • dubu0721
    dubu0721 님의 블로그
    dubu0721
  • 전체
    오늘
    어제
    • 분류 전체보기 (343) N
      • 프로그래밍언어론 정리 (5) N
      • 컴퓨터네트워크 정리 (5)
      • 알고리즘&자료구조 공부 (64)
        • it 취업을 위한 알고리즘 문제풀이 입문 강의 (60)
        • 학교 알고리즘 수업 (3)
        • 실전프로젝트I (0)
      • 백준 문제 (196) N
        • 이분탐색 (7)
        • 투포인트 (10)
        • 그래프 (7)
        • 그리디 (24)
        • DP (25)
        • BFS (18) N
        • MST (7)
        • KMP (4)
        • Dijkstra (3)
        • Disjoints Set (4)
        • Bellman-Ford (2)
        • 시뮬레이션 (3)
        • 백트래킹 (15)
        • 위상정렬 (5)
        • 자료구조 (25)
        • 기하학 (1)
        • 정렬 (11)
        • 구현 (8)
        • 재귀 (8)
        • 수학 (8)
      • 유니티 공부 (11)
        • 레트로의 유니티 게임 프로그래밍 에센스 (11)
        • 유니티 스터디 자료 (0)
        • C# 공부 (0)
      • 유니티 프로젝트 (48)
        • 케이크게임 (13)
        • 점토게임 (35)
      • 언리얼 공부 (10)
        • 이득우의 언리얼 프로그래밍 (10)
      • 진로 (1)
      • 논문 읽기 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    이분탐색
    정렬
    시뮬레이션
    BFS
    재귀
    수학
    해시
    맵
    레트로의 유니티 프로그래밍
    백트래킹
    큐
    유니티
    그리디
    골드메탈
    유니티 공부 정리
    이벤트 트리거
    스택
    바킹독
    투포인터
    오블완
    dp
    그래프
    백준
    언리얼
    자료구조
    티스토리챌린지
    우선순위큐
    이득우
    C#
    유니티 프로젝트
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
dubu0721
[개발일지] 5. 버튼 눌렀을 때 뒤에 있는 타일(게임 오브젝트)은 안 눌리도록 하는 방법
상단으로

티스토리툴바