using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.EnhancedTouch; using UnityEngine.InputSystem.Layouts; using UnityEngine.InputSystem.OnScreen; using UnityEngine.Serialization; [AddComponentMenu("Input/����ҡ�� - ������ϵͳ(InputSystem)")] public class JoyStick_InputSystem : OnScreenControl, IPointerDownHandler { enum JoyStickType { [InspectorName("�̶���Ĭ��λ��")] FixedInDefaultPosition = 0, [InspectorName("�̶��ڴ���λ��")] FixedInClickPosition = 1, [InspectorName("���津���ƶ�")] Flexible = 2 } [Header("��������")] [Tooltip("ҡ�˱���")] [SerializeField] private RectTransform joyStickBackGround; [Tooltip("ҡ�˰�ť")] [SerializeField] private RectTransform joyStickButton; [Tooltip("ҡ�˰�ť�ƶ���Χ(�뾶)")] [FormerlySerializedAs("movementRange")] [SerializeField] private float movementRange = 50; [Tooltip("�����豸·��")] [InputControl(layout = "Vector2")] [SerializeField] private new string controlPath; [Header("��������")] [Tooltip("ҡ������")] [SerializeField] private JoyStickType joyStickType; [Tooltip("ҡ���Ƿ�Ĭ������")] [SerializeField] private bool isHideWithoutTouch; //������(�豸) private Touchscreen currentTouchScreen; //����ҡ�˵Ĵ������ private TouchControl joyStickTouch; //ҡ�˳�ʼλ�� private Vector2 joyStickStartPos; //����Ļ��ص����(��Ҫ���ڽ���Ļ�ϵ�λ��ת��ΪijUI�����ڵ����λ��) private Camera screenCamera; //ģ��(�����߱�)���� private TouchSimulation touchSimulation; //������Ⱦģʽ private RenderMode renderMode; //�������UI��RectTransform private RectTransform rectTransform; protected override string controlPathInternal { get => controlPath; set => controlPath = value; } private void Awake() { #if UNITY_EDITOR if (!gameObject.TryGetComponent(out touchSimulation)) { touchSimulation = gameObject.AddComponent<TouchSimulation>(); } #endif } private void Start() { currentTouchScreen = Touchscreen.current; //��¼ҡ�˳�ʼλ�� joyStickStartPos = joyStickBackGround.anchoredPosition; if (isHideWithoutTouch) { joyStickBackGround.gameObject.SetActive(false); } //��ȡ��������Ⱦģʽ var canvas = transform.GetComponentInParent<Canvas>(); renderMode = canvas != null ? canvas.renderMode : RenderMode.ScreenSpaceOverlay; //��ȡ�������UI��RectTransform rectTransform = transform.GetComponent<RectTransform>(); } private void Update() { UpdateJoyStickUIPos(); } private void OnDestroy() { #if UNITY_EDITOR touchSimulation = null; #endif } public void OnPointerDown(PointerEventData eventData) { //��ȡ����Ļ��ص���� if (renderMode != RenderMode.ScreenSpaceOverlay) { screenCamera = eventData.pressEventCamera; } //ҡ��û�б�����ʱ�������Ȩ if (joyStickTouch == null) { for (int i = 0; i < currentTouchScreen.touches.Count; i++) { var touch = currentTouchScreen.touches[i]; if (touch.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Began) { if ( RectTransformUtility.RectangleContainsScreenPoint( rectTransform, touch.position.ReadValue(), screenCamera ) ) { joyStickTouch = touch; RectTransformUtility.ScreenPointToLocalPointInRectangle( rectTransform, joyStickTouch.position.ReadValue(), screenCamera, out var joyStickBgPos ); SetJoyStickUI(joyStickBgPos, Vector2.zero, true); } } } } } private void UpdateJoyStickUIPos() { if (joyStickTouch == null) return; bool isActive = true; Vector2 joyStickBgPos = Vector2.zero; Vector2 joyStickBtnPos = Vector2.zero; Vector2 sendToControlValue = Vector2.zero; switch (joyStickTouch.phase.ReadValue()) { case UnityEngine.InputSystem.TouchPhase.None: break; case UnityEngine.InputSystem.TouchPhase.Began: case UnityEngine.InputSystem.TouchPhase.Moved: //����ҡ��λ������ RectTransformUtility.ScreenPointToLocalPointInRectangle( rectTransform, joyStickTouch.position.ReadValue(), screenCamera, out var touchInRectPos ); Vector2 delta = touchInRectPos - joyStickBackGround.anchoredPosition; joyStickBgPos = joyStickBackGround.anchoredPosition; if (joyStickType == JoyStickType.Flexible) { if (delta.magnitude > movementRange) { joyStickBgPos += delta.normalized * (delta.magnitude - movementRange); } } joyStickBtnPos = Vector2.ClampMagnitude(delta, movementRange); isActive = true; sendToControlValue = delta / movementRange; break; case UnityEngine.InputSystem.TouchPhase.Ended: case UnityEngine.InputSystem.TouchPhase.Canceled: //�ջ�Touch��ҡ�˵Ŀ���Ȩ joyStickTouch = null; joyStickBgPos = joyStickStartPos; isActive = false; break; case UnityEngine.InputSystem.TouchPhase.Stationary: break; } //����ҡ��λ�� SetJoyStickUI(joyStickBgPos, joyStickBtnPos, isActive); //��������������λ�� SendValueToControl(sendToControlValue); } private void SetJoyStickUI(Vector2 joyStickBgPos, Vector2 joyStickBtnPos, bool isActive) { //����joyStickBackGroundλ�� switch (joyStickType) { case JoyStickType.FixedInDefaultPosition: break; case JoyStickType.FixedInClickPosition: case JoyStickType.Flexible: joyStickBackGround.anchoredPosition = joyStickBgPos; break; } //����joyStickButtonλ�� joyStickButton.anchoredPosition = joyStickBtnPos; //���� if (isHideWithoutTouch && joyStickBackGround.gameObject.activeSelf != isActive) { joyStickBackGround.gameObject.SetActive(isActive); } } }