Unity 摇杆



功能

1. 点击屏幕任意位置 显示在对应的位置

2. 松开后消失


UI结构

DynamicJoystick 组件:
- Background: 拖入Background
- Handle: 拖入Handle  
- Background Group: 拖入Background(自动获取CanvasGroup)


图片



代码

using UnityEngine;
using UnityEngine.EventSystems;

/// <summary>
/// 动态虚拟摇杆
/// </summary>
public class DynamicJoystick : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
    [Header( "摇杆组件" )]
    [SerializeField] private RectTransform background;
    [SerializeField] private RectTransform handle;
    [SerializeField] private CanvasGroup backgroundGroup; // 用CanvasGroup控制显隐

    [Header( "摇杆参数" )]
    [SerializeField] private float handleRange = 50f;
    [SerializeField] private float deadZone = 0.1f;

    private Vector2 inputVector;
    private Canvas canvas;
    private Camera cam;
    private RectTransform inputArea;

    public Vector2 Direction => inputVector.magnitude < deadZone ? Vector2.zero : inputVector;
    public float Horizontal => Direction.x;
    public float Vertical => Direction.y;

    private void Awake( )
    {
        inputArea = GetComponent<RectTransform>( );
        canvas = GetComponentInParent<Canvas>( );

        // 自动添加透明Image用于接收射线
        RaycastZone img = GetComponent<RaycastZone>( );
        if ( img == null )
        {
            img = gameObject.AddComponent<RaycastZone>( );
        }
        img.raycastTarget = true;

        // 自动添加CanvasGroup
        if ( backgroundGroup == null && background != null )
        {
            backgroundGroup = background.GetComponent<CanvasGroup>( );
            if ( backgroundGroup == null )
                backgroundGroup = background.gameObject.AddComponent<CanvasGroup>( );
        }
    }

    private void Start( )
    {
        if ( canvas.renderMode == RenderMode.ScreenSpaceOverlay )
            cam = null;
        else
            cam = canvas.worldCamera;

        // 初始隐藏摇杆(用alpha,不用SetActive)
        HideJoystick( );
    }

    public void OnPointerDown( PointerEventData eventData )
    {
        Vector2 position;

        if ( RectTransformUtility.ScreenPointToLocalPointInRectangle(
            inputArea,
            eventData.position,
            cam,
            out position ) )
        {
            // 在点击位置显示摇杆
            background.anchoredPosition = position;
            ShowJoystick( );

            // 手柄归中
            handle.anchoredPosition = Vector2.zero;
            inputVector = Vector2.zero;
        }
    }

    public void OnDrag( PointerEventData eventData )
    {
        Vector2 position;

        if ( RectTransformUtility.ScreenPointToLocalPointInRectangle(
            background,
            eventData.position,
            cam,
            out position ) )
        {
            position = Vector2.ClampMagnitude( position, handleRange );
            handle.anchoredPosition = position;
            inputVector = position / handleRange;
        }
    }

    public void OnPointerUp( PointerEventData eventData )
    {
        HideJoystick( );
        handle.anchoredPosition = Vector2.zero;
        inputVector = Vector2.zero;
    }

    /// <summary>
    /// 显示摇杆(不触发Canvas重构)
    /// </summary>
    private void ShowJoystick( )
    {
        backgroundGroup.alpha = 1f;
        //backgroundGroup.interactable = true;
        //backgroundGroup.blocksRaycasts = true;
    }

    /// <summary>
    /// 隐藏摇杆(不触发Canvas重构)
    /// </summary>
    private void HideJoystick( )
    {
        backgroundGroup.alpha = 0f;
        //backgroundGroup.interactable = false;
        //backgroundGroup.blocksRaycasts = false;
    }
}



Unity Spine AnimationReferenceAsset 使用笔记

Unity iOS打包,SDK接入,OC代码调用

评 论