温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Unity用UGUI做虚拟摇杆

发布时间:2020-07-24 06:47:22 来源:网络 阅读:3004 作者:一直都在a 栏目:编程语言

          一.首先点击UI创建两个Image,将Image的Source Image改成自己想要的Texture即可,然后在Canvas下创建一空物体,将两个Image放在空物体下作为他的子对象;

然后为可以拖动的Image编写脚本,脚本如下:(有注释,就不多说了)

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class JoyStick : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler//需要注意继承的接口,接口内的方法需要实现
{

    /// <summary>
    /// 摇杆最大半径
    /// 以像素为单位
    /// </summary>
    public float JoyStickRadius = 50;

    /// <summary>
    /// 摇杆重置所诉
    /// </summary>
    public float JoyStickResetSpeed = 5.0f;

    /// <summary>
    /// 当前物体的Transform组件
    /// </summary>
    private RectTransform selfTransform;

    /// <summary>
    /// 是否触摸了虚拟摇杆
    /// </summary>
    private bool isTouched = false;

    /// <summary>
    /// 虚拟摇杆的默认位置
    /// </summary>
    private Vector2 originPosition;

    /// <summary>
    /// 虚拟摇杆的移动方向
    /// </summary>
    private Vector2 touchedAxis;
    public Vector2 TouchedAxis
    {
        get
        {
            if (touchedAxis.magnitude < JoyStickRadius)
                return touchedAxis.normalized / JoyStickRadius;
            return touchedAxis.normalized;
        }
    }

    /// <summary>
    /// 定义触摸开始事件委托 
    /// </summary>
    public delegate void JoyStickTouchBegin(Vector2 vec);

    /// <summary>
    /// 定义触摸过程事件委托 
    /// </summary>
    /// <param name="vec">虚拟摇杆的移动方向</param>
    public delegate void JoyStickTouchMove(Vector2 vec);

    /// <summary>
    /// 定义触摸结束事件委托
    /// </summary>
    public delegate void JoyStickTouchEnd();

    /// <summary>
    /// 注册触摸开始事件
    /// </summary>
    public event JoyStickTouchBegin OnJoyStickTouchBegin;

    /// <summary>
    /// 注册触摸过程事件
    /// </summary>
    public event JoyStickTouchMove OnJoyStickTouchMove;

    /// <summary>
    /// 注册触摸结束事件
    /// </summary>
    public event JoyStickTouchEnd OnJoyStickTouchEnd;

    void Start()
    {
        //初始化虚拟摇杆的默认方向
        selfTransform = this.GetComponent<RectTransform>();
        originPosition = selfTransform.anchoredPosition;
    }


    public void OnPointerDown(PointerEventData eventData)
    {
        isTouched = true;
        touchedAxis = GetJoyStickAxis(eventData);
        if (this.OnJoyStickTouchBegin != null)
            this.OnJoyStickTouchBegin(TouchedAxis);
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        isTouched = false;
        selfTransform.anchoredPosition = originPosition;
        touchedAxis = Vector2.zero;
        if (this.OnJoyStickTouchEnd != null)
            this.OnJoyStickTouchEnd();
    }

    public void OnDrag(PointerEventData eventData)
    {
        touchedAxis = GetJoyStickAxis(eventData);
        if (this.OnJoyStickTouchMove != null)
            this.OnJoyStickTouchMove(TouchedAxis);
    }


    void Update()
    {
        //当虚拟摇杆移动到最大半径时摇杆无法拖动
        //为了确保被控制物体可以继续移动
        //在这里手动触发OnJoyStickTouchMove事件
        if (isTouched && touchedAxis.magnitude >= JoyStickRadius)
        {
            if (this.OnJoyStickTouchMove != null)
                this.OnJoyStickTouchMove(TouchedAxis);
        }

        //松开虚拟摇杆后让虚拟摇杆回到默认位置
        if (selfTransform.anchoredPosition.magnitude > originPosition.magnitude)
            selfTransform.anchoredPosition -= TouchedAxis * Time.deltaTime * JoyStickResetSpeed;
    }

    /// <summary>
    /// 返回虚拟摇杆的偏移量
    /// </summary>
    /// <returns>The joy stick axis.</returns>
    /// <param name="eventData">Event data.</param>
    private Vector2 GetJoyStickAxis(PointerEventData eventData)
    {
        //获取手指位置的世界坐标
        Vector3 worldPosition;
        if (RectTransformUtility.ScreenPointToWorldPointInRectangle(selfTransform,
                 eventData.position, eventData.pressEventCamera, out worldPosition))
            selfTransform.position = worldPosition;
        //获取摇杆的偏移量
        Vector2 touchAxis = selfTransform.anchoredPosition - originPosition;
        //摇杆偏移量限制
        if (touchAxis.magnitude >= JoyStickRadius)
        {
            touchAxis = touchAxis.normalized * JoyStickRadius;
            selfTransform.anchoredPosition = touchAxis;
        }
        return touchAxis;
    }


}

二.接下来,就是拖拽p_w_picpath使物体能够移动了;

为该物体添加脚本:

using UnityEngine;
using System.Collections;

public class JoyStick3D : MonoBehaviour
{

    private JoyStick js;

    void Start()
    {
        js = GameObject.FindObjectOfType<JoyStick>();
        js.OnJoyStickTouchBegin += OnJoyStickBegin;
        js.OnJoyStickTouchMove += OnJoyStickMove;
        js.OnJoyStickTouchEnd += OnJoyStickEnd;
    }


    void OnJoyStickBegin(Vector2 vec)
    {
        Debug.Log("开始触摸虚拟摇杆");
    }

    void OnJoyStickMove(Vector2 vec)
    {
        Debug.Log("正在移动虚拟摇杆");

        //设置角色朝向
        Quaternion q = Quaternion.LookRotation(new Vector3(vec.x, 0, vec.y));
        transform.rotation = q;

        //移动角色
        transform.Translate(Vector3.forward * 75f * Time.deltaTime);
    }

    void OnJoyStickEnd()
    {
        Debug.Log("触摸移动摇杆结束");

     
    }

    void OnGUI()
    {
        GUI.Label(new Rect(30, 30, 200, 30), "3D模式下的虚拟摇杆测试");
    }
}

三.接着可以试着运行,可以看到物体可以随着p_w_picpath的拖动而移动,但是有不好的地方,就是拖拽的p_w_picpath超过半径所设置的半径JoyStickRadius时,p_w_picpath的位置就会固定在一个位置不动,

而且当在半径范围内时,物体不会持续移动,这个就不好了,不知道有那位大神能够邦杰呢?


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI