天天看點

Unity中實作虛拟搖杆

一:示範視訊

Unity中實作虛拟搖杆

二:使用方法

using UnityEngine;
using System;

/// <summary>
/// 自制虛拟搖杆
/// </summary>
public class FSVjoy : MonoBehaviour
{
    [Header("操作區域")]
    public RectTransform handleArea;
    [Header("搖杆區域")]
    public RectTransform area;
    [Header("搖杆操作區域")]
    public RectTransform thumb;

    [Header("是否自由位置")]
    [Header("————————————————————————————————————————")]
    public bool autoPos;
    [Header("是否始終可見")]
    public bool alwaysVisible;

    float maxDragDist;//最大拖拽距離
    bool inDrag;//是否在拖拽中

    public Action<Vector2> onDrag;

    private void Awake()
    {
        maxDragDist = (area.rect.width - thumb.rect.width) / 2;

        UpdatShow(alwaysVisible);
    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            if (!InHandleArea(Input.mousePosition)) return;

            UpdatShow(true);
            if (autoPos)
            {
                area.anchoredPosition = Input.mousePosition;
            }

            inDrag = true;
        }
        if (Input.GetMouseButtonUp(0))
        {
            UpdatShow(alwaysVisible);

            inDrag = false;
        }

        if (inDrag)
        {
            Vector2 offset = (Vector2)Input.mousePosition - area.anchoredPosition;
            if (offset.magnitude < maxDragDist)
            {
                thumb.localPosition = offset;
            }
            else
            {
                thumb.localPosition = offset.normalized * maxDragDist;
            }

            onDrag?.Invoke(offset);
        }
    }

    #region Tools

    /// <summary>
    /// 更新顯示
    /// </summary>
    void UpdatShow(bool isShow)
    {
        area.gameObject.SetActive(isShow);
    }

    /// <summary>
    /// 是否在操作區域内
    /// </summary>
    bool InHandleArea(Vector2 curPos)
    {
        if (handleArea == null)
        {
            return curPos.x < Screen.width / 2;
        }
        else
        {
            Vector2 rt = handleArea.anchoredPosition + handleArea.rect.max;
            Vector2 lb = handleArea.anchoredPosition + handleArea.rect.min;
            return curPos.x < rt.x
                && curPos.x > lb.x
                && curPos.y < rt.y
                && curPos.y > lb.y;
        }
    }

    #endregion
}