UGUI—摇杆

作者:追风剑情 发布于:2019-10-14 17:31 分类:Unity3d

工程截图

3333.png

4444.png

UIJoystick.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.Serialization;

/// <summary>
/// 摇杆
/// </summary>
public class UIJoystick : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
{
    [SerializeField] private Image m_Background;
    [SerializeField] private Image m_Foreground;

    private RectTransform m_BackgroundRect;
    private RectTransform m_ForegroundRect;
    private float constraintRadius = 0;
    private float sqrMagnitude = 0;

    // 定义摇杆事件类
    [Serializable]
    public class OnMoveEvent : UnityEvent { }
    [Serializable]
    public class OnStopEvent : UnityEvent { }

    // 防止序列化变量重命名后丢失引用
    [FormerlySerializedAs("onMove")]
    [SerializeField]
    private OnMoveEvent m_OnMove = new OnMoveEvent();

    [FormerlySerializedAs("onStop")]
    [SerializeField]
    private OnStopEvent m_OnStop = new OnStopEvent();

    public Vector2 normalized { get; private set; }

    void Awake ()
    {
        m_Background.alphaHitTestMinimumThreshold = 0.1f;
        m_BackgroundRect = m_Background.GetComponent<RectTransform>();
        m_ForegroundRect = m_Foreground.GetComponent<RectTransform>();
        constraintRadius = (m_BackgroundRect.sizeDelta.x - m_ForegroundRect.sizeDelta.x) / 2;
        sqrMagnitude = constraintRadius * constraintRadius;
    }

    private Vector2 foregroundPosition
    {
        get { return m_ForegroundRect.anchoredPosition; }
        set { m_ForegroundRect.anchoredPosition = value; }
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        foregroundPosition = ScreenPointToLocalPointInRectangle(eventData.pressPosition);
        normalized = foregroundPosition.normalized;
        m_OnMove.Invoke();
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        foregroundPosition = Vector2.zero;
        m_OnStop.Invoke();
    }

    public void OnDrag(PointerEventData eventData)
    {
        if (!eventData.IsPointerMoving())
            return;
        //eventData.pressPosition: 事件触发时鼠标或手指的坐标
        //eventData.position: 为鼠标或手指的实时坐标
        foregroundPosition = ScreenPointToLocalPointInRectangle(eventData.position);
        normalized = foregroundPosition.normalized;
        m_OnMove.Invoke();
    }

    private Vector2 ScreenPointToLocalPointInRectangle(Vector2 screenPoint)
    {
        Vector2 localPoint = Vector2.zero;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(m_BackgroundRect, screenPoint, null, out localPoint);
        return GetAdjustedPosition(localPoint);
    }

    private Vector2 GetAdjustedPosition(Vector2 pos)
    {
        //sqrMagnitude: 开方前的值
        //magnitude: 开方后的值
        if (pos.sqrMagnitude <= sqrMagnitude)
            return pos;
        float magnitude = pos.magnitude;
        float cos = pos.x / magnitude;
        float sin = pos.y / magnitude;
        float x = constraintRadius * cos;
        float y = constraintRadius * sin;
        pos.x = x;
        pos.y = y;
        return pos;
    }
}


UIJoystickTest.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UIJoystickTest : MonoBehaviour
{
    public void OnJoystickMove(UIJoystick joystick)
    {
        Debug.LogFormat("Joystick Move: {0}", joystick.normalized);
    }

    public void OnJoystickStop()
    {
        Debug.Log("Joystick Stop");
    }
}


运行测试
22222.gif

标签: Unity3d

Powered by emlog  蜀ICP备18021003号   sitemap

川公网安备 51019002001593号