一:演示视频

Unity中实现虚拟摇杆_# Unity相关技术


二:使用方法

——Camera的渲染模式必须设置为

面板上设置一些属性,比如摇杆拖拽的距离,是否始终可视,是否限制虚拟摇杆的位置,是否限制拖拽距离等
使用GetDir或GetDirAndDis方法获得方向和长度进行移动
Unity中实现虚拟摇杆_# Unity相关技术_02

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
}