using System.Collections; using System.Collections.Generic; using NUnit.Framework; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.TestTools; using UnityEngine.UI; using UnityEngine.TestTools.Utils; public class GraphicRaycasterTests { Camera m_Camera; EventSystem m_EventSystem; Canvas m_Canvas; RectTransform m_CanvasRectTrans; Text m_TextComponent; [SetUp] public void TestSetup() { m_Camera = new GameObject("GraphicRaycaster Camera").AddComponent(); m_Camera.transform.position = Vector3.zero; m_Camera.transform.LookAt(Vector3.forward); m_Camera.farClipPlane = 10; m_EventSystem = new GameObject("Event System").AddComponent(); m_Canvas = new GameObject("Canvas").AddComponent(); m_Canvas.renderMode = RenderMode.WorldSpace; m_Canvas.worldCamera = m_Camera; m_Canvas.gameObject.AddComponent(); m_CanvasRectTrans = m_Canvas.GetComponent(); m_CanvasRectTrans.sizeDelta = new Vector2(100, 100); var textGO = new GameObject("Text"); m_TextComponent = textGO.AddComponent(); var textRectTrans = m_TextComponent.rectTransform; textRectTrans.SetParent(m_Canvas.transform); textRectTrans.anchorMin = Vector2.zero; textRectTrans.anchorMax = Vector2.one; textRectTrans.offsetMin = Vector2.zero; textRectTrans.offsetMax = Vector2.zero; } [UnityTest] public IEnumerator GraphicRaycasterDoesNotHitGraphicBehindCameraFarClipPlane() { m_CanvasRectTrans.anchoredPosition3D = new Vector3(0, 0, 11); yield return null; var results = new List(); var pointerEvent = new PointerEventData(m_EventSystem) { position = new Vector2(Screen.width / 2f, Screen.height / 2f) }; m_EventSystem.RaycastAll(pointerEvent, results); Assert.IsEmpty(results, "Expected no results from a raycast against a graphic behind the camera's far clip plane."); } [UnityTest] public IEnumerator GraphicRaycasterReturnsWorldPositionAndWorldNormal() { m_CanvasRectTrans.anchoredPosition3D = new Vector3(0, 0, 11); m_Camera.farClipPlane = 12; yield return null; var results = new List(); var pointerEvent = new PointerEventData(m_EventSystem) { position = new Vector2(Screen.width / 2f, Screen.height / 2f) }; m_EventSystem.RaycastAll(pointerEvent, results); // on katana on 10.13 agents world position returned is 0, -0.00952, 11 // it does not reproduce for me localy, so we just tweak the comparison threshold Assert.That(new Vector3(0, 0, 11), Is.EqualTo(results[0].worldPosition).Using(new Vector3EqualityComparer(0.01f))); Assert.That(new Vector3(0, 0, -1), Is.EqualTo(results[0].worldNormal).Using(new Vector3EqualityComparer(0.001f))); } [UnityTest] public IEnumerator GraphicRaycasterUsesGraphicPadding() { m_CanvasRectTrans.anchoredPosition3D = new Vector3(0, 0, 11); m_TextComponent.raycastPadding = new Vector4(-50, -50, -50, -50); m_Camera.farClipPlane = 12; yield return null; var results = new List(); var pointerEvent = new PointerEventData(m_EventSystem) { position = new Vector2((Screen.width / 2f) - 60, Screen.height / 2f) }; m_EventSystem.RaycastAll(pointerEvent, results); Assert.IsNotEmpty(results, "Expected at least 1 result from a raycast outside the graphics RectTransform whose padding would make the click hit."); } [UnityTest] public IEnumerator GraphicOnTheSamePlaneAsTheCameraCanBeTargetedForEvents() { m_Canvas.renderMode = RenderMode.ScreenSpaceCamera; m_Canvas.planeDistance = 0; m_Camera.orthographic = true; m_Camera.orthographicSize = 1; m_Camera.nearClipPlane = 0; m_Camera.farClipPlane = 12; yield return null; var results = new List(); var pointerEvent = new PointerEventData(m_EventSystem) { position = new Vector2((Screen.width / 2f), Screen.height / 2f) }; m_EventSystem.RaycastAll(pointerEvent, results); Assert.IsNotEmpty(results, "Expected at least 1 result from a raycast "); } #if ENABLE_INPUT_SYSTEM && PACKAGE_INPUTSYSTEM [UnityTest] public IEnumerator GraphicRaycasterIgnoresEventsFromTheWrongDisplay() { m_CanvasRectTrans.anchoredPosition3D = new Vector3(0, 0, 11); m_Camera.farClipPlane = 12; yield return null; var results = new List(); var pointerEvent = new PointerEventData(m_EventSystem) { position = new Vector2(Screen.width / 2f, Screen.height / 2f), displayIndex = 1, }; m_EventSystem.RaycastAll(pointerEvent, results); Assert.IsEmpty(results, "Pointer event on display 1 was not ignored on display 0"); } #endif [TearDown] public void TearDown() { Object.DestroyImmediate(m_Camera.gameObject); Object.DestroyImmediate(m_EventSystem.gameObject); Object.DestroyImmediate(m_Canvas.gameObject); } }