【Unity3d基础】Unity3d中利用NGUI实现虚拟摇杆

引言

最近的项目中需要开发虚拟摇杆功能,由于历史原因对于FingerGesture较为熟悉,故没有采用EasyTouch。

NGUI中的UIDragObject

NGUI中有一个UIDragObject.cs组件,添加到GameObject,即可实现简单的拖拽动作。


其中的Target需要设置被拖拽的对象,代码注释如下:

	/// <summary>
	/// Target object that will be dragged.
	/// </summary>

	public Transform target;

仅仅添加该组件是不够的,想要捕获鼠标事件还需要在对象上添加Box Collider组件。

运行项目,就可以拖拽对象了。

分析虚拟摇杆需求

首先要虚拟摇杆分为两部分,中间一小部分为中间的滑块,周围一圈是背景层。(资源是EasyTouch里的)


操作同时也分为两种情况:

1.拖拽中间的滑块;

2.直接点击周围的背景部分,滑块直接跳转到对应位置。

返回什么?

操作虚拟摇杆只需返回一个Vector3向量即可(从原点指向滑块被拖拽位置,其实是一个二维向量,z值没有用到。)

代码实现

对于滑块部分的操作可以借鉴NGUI中的UIDragObject的实现,只需保留最基本的功能,只用到了NGUI中的OnPress和OnDrag事件。

滑块部分代码如下:

using UnityEngine;
using System.Collections;

public class JoyStickDragObject : MonoBehaviour
{
    public Transform target;

    Vector3 mTargetPos;                                         // 目标当前位置
    Vector3 mLastPos;

    int mTouchID = 0;

    bool mStarted = false;
    bool mPressed = false;

    [SerializeField]
    protected Vector3 scale = new Vector3(1f, 1f, 0f);
    protected Vector3 originPos = Vector3.zero;                 
    protected Vector3 offsetFromOrigin = Vector3.zero;          // 原点到拖拽位置的向量

    public Vector3 OffsetFromOrigin
    {
        set { offsetFromOrigin = value; }
        get { return offsetFromOrigin; }
    }

	// Use this for initialization
	void Start () {
	}
	
	// Update is called once per frame
	void Update () {
	    
	}

    void OnPress(bool pressed)
    {
        if (enabled && NGUITools.GetActive(gameObject) && target != null)
        {
            if (pressed)
            {
                if (!mPressed)
                {
                    mTouchID = UICamera.currentTouchID;
                    mPressed = true;
                    mStarted = false;
                    CancelMovement();
                }
            }
            else if (mPressed && mTouchID == UICamera.currentTouchID)
            {
                mPressed = false;
                target.position = Vector3.zero;
            }
        }

    }
    void OnDrag(Vector2 delta)
    {
        Ray ray = UICamera.currentCamera.ScreenPointToRay(UICamera.currentTouch.pos);
        float dist = 0f;

        Vector3 currentPos = ray.GetPoint(dist);
        ///< 更新当前坐标到上一时刻坐标的向量
        Vector3 offset = currentPos - mLastPos;
        ///< 更新当前坐标到原点的向量
        UpdateVector3FromOrigin(currentPos);
        mLastPos = currentPos;

        if (!mStarted)
        {
            mStarted = true;
            offset = Vector3.zero;
        }

        Debug.LogWarning("offset: " + offset + " OffsetFromOrigin: " + OffsetFromOrigin);
        Move(offset);
    }

    void Move(Vector3 moveDelta)
    {
        mTargetPos += moveDelta;
        target.position = mTargetPos;
    }

    void CancelMovement()
    {
        if (target != null)
        {      
            Vector3 pos = target.localPosition;
            target.localPosition = pos;
        }
        mTargetPos = (target != null) ? target.position : Vector3.zero;
    }

    ///< 更新当前坐标到原点的向量
    void UpdateVector3FromOrigin(Vector3 pos)
    {
        OffsetFromOrigin = pos - originPos;
    }
}
背景层的处理与滑块部分略有不同,主要在于点击背景层,滑块需要直接移动到点击位置

背景层代码如下:

using UnityEngine;
using System.Collections;

public class JoyStickBackground : MonoBehaviour
{

    public Transform thumb;

    private bool isReset = true;
    [SerializeField]
    protected Vector3 originPos = Vector3.zero;                 // 原点
    protected Vector3 offsetFromOrigin = Vector3.zero;          // 原点到拖拽位置的向量
    public Vector3 OffsetFromOrigin
    {
        set { offsetFromOrigin = value; }
        get { return offsetFromOrigin; }
    }
    // Use this for initialization
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
    }

    void OnPress(bool pressed)
    {
        if (pressed)
        {
            Ray ray = UICamera.currentCamera.ScreenPointToRay(UICamera.currentTouch.pos);
            float dist = 0f;
            Vector3 currentPos = ray.GetPoint(dist);

            thumb.position = currentPos;
            isReset = false;
            ///< 更新当前坐标到原点的向量
            UpdateVector3FromOrigin(currentPos);
        }
        else
        {
            thumb.position = Vector3.zero;
            isReset = true;
        }
    }

    void OnDrag(Vector2 delta)
    {
        Ray ray = UICamera.currentCamera.ScreenPointToRay(UICamera.currentTouch.pos);
        float dist = 0f;

        Vector3 currentPos = ray.GetPoint(dist);
        thumb.position = currentPos;

    }

    ///< 更新当前坐标到原点的向量
    void UpdateVector3FromOrigin(Vector3 pos)
    {
        OffsetFromOrigin = pos - originPos;
    }
}
效果图:

拖拽滑块:

点击背景:


猜你喜欢

转载自blog.csdn.net/u010832643/article/details/53414117