-
[Unity][2D] EventSystems를 활용한 UI Control프로그래밍/Unity 2021. 11. 7. 11:46728x90
Hierarchy에서 UI에서 button을 만들면 1) Canvas 밑에 Button이 생기고 2) Canvas와 같은 라인(친구 라인?)에 EventSystem이라는게 생긴다.
Unity의 Scene에서 event를 처리하고 다루는데 사용되며, 한 Scene에 하나의 Event System만 포함되어야 한다.
EventSystem을 사용하기 위해서는 using UnityEngine.EventSystems로 불러와야 한다.
UI로 등록된 버튼들을 제어하는데 유용하게 쓰이는 것 같다!
구현하고자 하는 것은 버튼을 누르면 타일을 세팅할 수 있는 동작을 활성화하고,
다시 한번 더 누르면 비활성화 하는 시스템을 만들고자 했다.
유용하게 쓰인 함수에는 EventSystem.current.currentSelectedGameObject 이며
마우스 아래에 있는 것이 어떤 Game Object인지 받아 올 수 있으며,
뒤에 아무것도 없으면, Null을 그렇지 않으면 GameObject를 받아오고
뒤에 .name까지 붙이면 GameObject의 이름을 받아올 수 있다.
짜보면서 궁금하거나 수정이 필요하다고 생각한 점은
1) 코딩하면서 정리하다보니까 일단 Canvas의 Component로 넣어버렸는데 아무 Hierarchy의 Object에 적당히 막 넣으면 되는지?
2) 이름을 가져와서 비교하다보니까 버튼의 이름을 string 1개 길이로 했지만, 버튼이 더 많아지면 더 효율적인 방법이 필요함을 느꼈다.
일단 할게 많으니 대충 동작하면 다른것도 익히면서 진짜 필요할 때 수정을 해야겠다..
[SerializeField] 는 원래 Target_tile을 private로 설정하면 아래와 같이 안보이는게 정상이지만
SerializeField 전 [SerializeField] 를 써주고 private ~ 변수 설정해주면 public으로 쓴 것 처럼 Object를 갔다가 지정해줄 수 있다. 하지만 private라는 점.. 구현에 의미가 있는건 아니고 누가 쓰기래 따라 써보았다.
유니티 Document에는 .NET의 serialization 기능과는 아무런 영향을 주지 않고, 유니티 내부에서만 동작합니다. 라고 나와 있다.
SerializeField 후 // ==============================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Tilemaps;
using UnityEngine.EventSystems;
public class button_Event : MonoBehaviour
{
private bool UI1_active = false; // 초기엔 비활성화 상태임을 의미
private string current_UI_name;
private Button button2;
Vector3Int pos = new Vector3Int(0, 0, 0);
Vector2 MousePosition;
Camera Camera;
public Tilemap Tilemap;
[SerializeField]
private TileBase target_tile;
// Start is called before the first frame update
void Start()
{
Camera = GameObject.Find("Main Camera").GetComponent<Camera>();
button2 = GameObject.Find("2").GetComponent<Button>();
}
void Update()
{
if (Input.GetMouseButtonDown(0)) // Update 동안 마우스 왼쪽버튼을 누르면
{
if (UI1_active == true) // Update 동안 UI1이 활성상태이면
{
UI1_Activity(); // 타일 세팅 시스템을 활성화
button2.GetComponentInChildren<Text>().text = "button1 activated"; // Text로 확인
}
else
button2.GetComponentInChildren<Text>().text = "button1 deactivated";
if (EventSystem.current.currentSelectedGameObject != null) // UI에서 현재 선택된 GameObject
{
current_UI_name = EventSystem.current.currentSelectedGameObject.name;
if (current_UI_name == "1")
{
UI1_active = !UI1_active;
}
}
}
}
private void UI1_Activity() // 이전에 구현한 타일 세팅
{
MousePosition = Input.mousePosition;
MousePosition = Camera.ScreenToWorldPoint(MousePosition);
Debug.Log(Tilemap.WorldToCell(MousePosition));
pos.x = Tilemap.WorldToCell(MousePosition).x;
pos.y = Tilemap.WorldToCell(MousePosition).y;
Tilemap.SetTile(pos, target_tile);
}
}// ===============================
참고한 사이트들
https://docs.unity3d.com/kr/530/ScriptReference/EventSystems.EventSystem.html
Unity - 스크립팅 API: EventSystem
The EventSystem is responsible for processing and handling events in a Unity scene. A scene should only contain one EventSystem. The EventSystem works in conjunction with a number of modules and mostly just holds state and delegates functunality to specifi
docs.unity3d.com
https://ansohxxn.github.io/unitydocs/unityengine-eventsystems/
Unity C# > EventSystems
유니티 공식 매뉴얼 https://docs.unity3d.com/kr/current/Manual/UnityManual.html Scripting Overview http://www.devkorea.co.kr/reference/Documentation/ScriptReference/index.html
ansohxxn.github.io
https://docs.unity3d.com/kr/530/ScriptReference/SerializeField.html
Unity - 스크립팅 API: SerializeField
특별한 경우가 아니면 사용하지 않습니다. 유니티가 사용자의 스크립트를 직렬화 하는 경우에, public 필드만 직렬화합니다. 추가로 유니티가 private 필드를 직렬화하도록 설정하고 싶은 경우에, S
docs.unity3d.com
728x90'프로그래밍 > Unity' 카테고리의 다른 글
[Unity][2D] 드래그 해서 타일 깔기 (0) 2021.11.27 [Unity][2D] 드래그해서 타일 깔기 (0) 2021.11.21 [Unity][2D] 카메라 줌 인/줌 아웃 (0) 2021.10.31 [Unity][2D] UI 배치를 위한 Canvas 알아보기 (0) 2021.10.30 [Unity][2D] Grid의 Cell 좌표 구하기 (수정 예정) (0) 2021.10.27