Android에서 Canvas on Touch의 UI 개체를 감지하는 방법은 무엇입니까?
예를 들어, 나는 다음과 같은 5 객체가 캔버스가 Image
, RawImage
, Buttons
, InputField
등을.
Button UI 개체를 터치하면 다음 작업을 수행합니다. 각 버튼은 클릭 할 때마다 다른 프로세스를 수행합니다.
코드는 다음과 같습니다.
private void Update()
{
if (Input.touches.Length <= 0) return;
for (int i = 0; i < Input.touchCount; i++)
{
if (Button1.touch)
if (Input.GetTouch(i).phase == TouchPhase.Began)
login();
else if (Button2.touch && Input.GetTouch(i).phase == TouchPhase.Began)
LogOut();
}
}
그럼 어떻게할까요?
둘째 : Gameobject가 터치를 감지하는 방법은 무엇입니까? 위와 동일합니까?
답변
새 UI에 입력 API를 사용하지 않습니다. UI 이벤트를 구독하거나 이벤트에 따라 인터페이스를 구현합니다.
다음은 새 UI 구성 요소에서 이벤트를 감지하는 적절한 방법입니다.
1 . Image
, RawImage
및 Text
구성 요소 :
필요한 인터페이스를 구현하고 해당 기능을 재정의합니다. 아래 예는 가장 많이 사용되는 이벤트를 구현합니다.
using UnityEngine.EventSystems;
public class ClickDetector : MonoBehaviour, IPointerDownHandler, IPointerClickHandler,
IPointerUpHandler, IPointerExitHandler, IPointerEnterHandler,
IBeginDragHandler, IDragHandler, IEndDragHandler
{
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("Drag Begin");
}
public void OnDrag(PointerEventData eventData)
{
Debug.Log("Dragging");
}
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("Drag Ended");
}
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name);
}
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("Mouse Down: " + eventData.pointerCurrentRaycast.gameObject.name);
}
public void OnPointerEnter(PointerEventData eventData)
{
Debug.Log("Mouse Enter");
}
public void OnPointerExit(PointerEventData eventData)
{
Debug.Log("Mouse Exit");
}
public void OnPointerUp(PointerEventData eventData)
{
Debug.Log("Mouse Up");
}
}
2 . Button
구성 요소:
이벤트를 사용하여 버튼 클릭에 등록합니다.
public class ButtonClickDetector : MonoBehaviour
{
public Button button1;
public Button button2;
public Button button3;
void OnEnable()
{
//Register Button Events
button1.onClick.AddListener(() => buttonCallBack(button1));
button2.onClick.AddListener(() => buttonCallBack(button2));
button3.onClick.AddListener(() => buttonCallBack(button3));
}
private void buttonCallBack(Button buttonPressed)
{
if (buttonPressed == button1)
{
//Your code for button 1
Debug.Log("Clicked: " + button1.name);
}
if (buttonPressed == button2)
{
//Your code for button 2
Debug.Log("Clicked: " + button2.name);
}
if (buttonPressed == button3)
{
//Your code for button 3
Debug.Log("Clicked: " + button3.name);
}
}
void OnDisable()
{
//Un-Register Button Events
button1.onClick.RemoveAllListeners();
button2.onClick.RemoveAllListeners();
button3.onClick.RemoveAllListeners();
}
}
당신이 버튼에 버튼을 클릭 이외의 무언가를 감지하는 경우, 예를 들어, 버튼의 아래가 아닌 버튼을 클릭, 사용을 위해 방법 1을 사용 IPointerDownHandler
하고 OnPointerDown
방법 1에서 기능.
3 . InputField
구성 요소:
이벤트를 사용하여 InputField 제출 등록을 등록합니다.
public InputField inputField;
void OnEnable()
{
//Register InputField Events
inputField.onEndEdit.AddListener(delegate { inputEndEdit(); });
inputField.onValueChanged.AddListener(delegate { inputValueChanged(); });
}
//Called when Input is submitted
private void inputEndEdit()
{
Debug.Log("Input Submitted");
}
//Called when Input changes
private void inputValueChanged()
{
Debug.Log("Input Changed");
}
void OnDisable()
{
//Un-Register InputField Events
inputField.onEndEdit.RemoveAllListeners();
inputField.onValueChanged.RemoveAllListeners();
}
4 . Slider
구성 요소:
드래그하는 동안 슬라이더 값이 변경되는시기를 감지하려면 :
public Slider slider;
void OnEnable()
{
//Subscribe to the Slider Click event
slider.onValueChanged.AddListener(delegate { sliderCallBack(slider.value); });
}
//Will be called when Slider changes
void sliderCallBack(float value)
{
Debug.Log("Slider Changed: " + value);
}
void OnDisable()
{
//Un-Subscribe To Slider Event
slider.onValueChanged.RemoveListener(delegate { sliderCallBack(slider.value); });
}
다른 이벤트의 경우 방법 1을 사용하십시오 .
5 . Dropdown
구성 요소
public Dropdown dropdown;
void OnEnable()
{
//Register to onValueChanged Events
//Callback with parameter
dropdown.onValueChanged.AddListener(delegate { callBack(); });
//Callback without parameter
dropdown.onValueChanged.AddListener(callBackWithParameter);
}
void OnDisable()
{
//Un-Register from onValueChanged Events
dropdown.onValueChanged.RemoveAllListeners();
}
void callBack()
{
}
void callBackWithParameter(int value)
{
}
UI가 아닌 개체 :
6. 3D 객체 (메시 렌더러 / 모든 3D 충돌체)
PhysicsRaycaster
카메라에 추가 한 다음 방법 1의 이벤트 를 사용합니다 .
아래 코드는 자동으로 PhysicsRaycaster
메인 Camera
.
public class MeshDetector : MonoBehaviour, IPointerDownHandler
{
void Start()
{
addPhysicsRaycaster();
}
void addPhysicsRaycaster()
{
PhysicsRaycaster physicsRaycaster = GameObject.FindObjectOfType<PhysicsRaycaster>();
if (physicsRaycaster == null)
{
Camera.main.gameObject.AddComponent<PhysicsRaycaster>();
}
}
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name);
}
//Implement Other Events from Method 1
}
7. 2D 오브젝트 용 (스프라이트 렌더러 / 모든 2D 충돌체)
Physics2DRaycaster
카메라에 추가 한 다음 방법 1의 이벤트 를 사용합니다 .
아래 코드는 자동으로 Physics2DRaycaster
메인 Camera
.
public class SpriteDetector : MonoBehaviour, IPointerDownHandler
{
void Start()
{
addPhysics2DRaycaster();
}
void addPhysics2DRaycaster()
{
Physics2DRaycaster physicsRaycaster = GameObject.FindObjectOfType<Physics2DRaycaster>();
if (physicsRaycaster == null)
{
Camera.main.gameObject.AddComponent<Physics2DRaycaster>();
}
}
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name);
}
//Implement Other Events from Method 1
}
EventSystem 문제 해결 :
UI, 2D 개체 (Sprite Renderer / 모든 2D Collider) 및 3D 개체 (Mesh Renderer / 모든 3D Collider)에서 클릭이 감지되지 않았습니다.
A. EventSystem이 있는지 확인하십시오. EventSystem이 없으면 클릭을 전혀 감지 할 수 없습니다. 가지고 있지 않다면 직접 만드십시오.
로 이동하여 게임 오브젝트 —> UI —> 이벤트 시스템 . 아직 존재하지 않는 경우 EventSystem이 생성됩니다. 이미 존재하는 경우 Unity는이를 무시합니다.
B. UI 구성 요소 또는 UI 구성 요소가있는 GameObject는 Canvas
. 이는 a Canvas
가 UI 구성 요소의 부모 여야 함을 의미합니다 . 이것이 없으면 EventSystem이 작동하지 않고 클릭이 감지되지 않습니다.
이는 UI 개체에만 적용됩니다. 그것은 하지 않습니다 2D (스프 렌더 / 모든 2D 충돌 장치) 또는 3D 개체 (메쉬 렌더러 / 어떤 3D 충돌 장치)에 적용됩니다.
C. 3D 개체 인 PhysicsRaycaster
경우 카메라에 부착되지 않습니다. 그것이 PhysicsRaycaster
카메라에 부착되어 있는지 확인하십시오 . 자세한 내용은 위의 # 6 을 참조하십시오.
D. 2D Object 인 Physics2DRaycaster
경우 카메라에 부착되지 않습니다. 그것이 Physics2DRaycaster
카메라에 부착되어 있는지 확인하십시오 . 자세한 내용은 위의 # 7 을 참조하십시오.
E .If이는 인터페이스 등의 기능에 대한 클릭을 감지하고자하는 UI 객체 인 OnBeginDrag
, OnPointerClick
, OnPointerEnter
과에 언급 된 다른 기능 # 1 다음 검출 코드 스크립트가이 UI 개체에 연결해야합니다 당신이 클릭 감지합니다.
F. 또한 이것이 클릭을 감지하려는 UI 객체 인 경우 앞에 다른 UI 객체가 없는지 확인합니다. 클릭을 감지하려는 UI 앞에 다른 UI가 있으면 해당 클릭을 차단합니다.
이것이 문제가 아닌지 확인하려면 클릭을 감지하려는 개체를 제외한 캔버스 아래의 모든 개체를 비활성화 한 다음 클릭이 작동하는지 확인합니다.
답변
특정 이벤트 를 전달하기 만하면 EventTrigger
이미 이러한 요소가있는 UI 요소에 Componenet을 추가 할 수 있습니다 .Events
method/Function
답변
OnMouseDown도 사용할 수 있습니다. OnMouseDown은 사용자가 GUIElement 또는 Collider 위에있는 동안 마우스 버튼을 눌렀을 때 호출됩니다. 이 이벤트는 Collider 또는 GUIElement의 모든 스크립트로 전송됩니다.
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement; // The new load level needs this
public class ExampleClass : MonoBehaviour
{
void OnMouseDown()
{
// Edit:
// Application.LoadLevel("SomeLevel");
// Application.LoadLevel() is depreciating but still works
SceneManager.LoadScene("SomeLevel"); // The new way to load levels
}
}
답변
마 되지 모바일 성능과 멀티 터치 문제에 대한 ()하면 onMouseDown 사용합니다.
이 코드는 멀티 터치 용 UI 개체에서 작동합니다.
내 대답에서는 ” Button “태그와 함께 Image 요소를 사용 하고 사용자가 Image 요소를 터치 할 때 호출되어야 하는 ButtonDown () 공용 메서드 가있는 ButtonController 스크립트 가 있습니다.
참고 : 이미지 요소에는 2D 충돌체가 있습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class TouchScript : MonoBehaviour
{
void Update()
{
PointerEventData pointer = new PointerEventData(EventSystem.current);
List<RaycastResult> raycastResult = new List<RaycastResult>();
foreach (Touch touch in Input.touches)
{
if(touch.phase.Equals(TouchPhase.Began))
{
pointer.position = touch.position;
EventSystem.current.RaycastAll(pointer, raycastResult);
foreach(RaycastResult result in raycastResult)
{
if(result.gameObject.tag == "Button")
{
result.gameObject.GetComponent<ButtonController>().ButtonDown();
}
}
raycastResult.Clear();
}
}
}
}