天天看點

【Unity3d基礎】Unity3d中利用NGUI實作虛拟搖杆

引言

最近的項目中需要開發虛拟搖杆功能,由于曆史原因對于FingerGesture較為熟悉,故沒有采用EasyTouch。

NGUI中的UIDragObject

NGUI中有一個UIDragObject.cs元件,添加到GameObject,即可實作簡單的拖拽動作。

【Unity3d基礎】Unity3d中利用NGUI實作虛拟搖杆

其中的Target需要設定被拖拽的對象,代碼注釋如下:

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

	public Transform target;
           

僅僅添加該元件是不夠的,想要捕獲滑鼠事件還需要在對象上添加Box Collider元件。

運作項目,就可以拖拽對象了。

分析虛拟搖杆需求

首先要虛拟搖杆分為兩部分,中間一小部分為中間的滑塊,周圍一圈是背景層。(資源是EasyTouch裡的)

【Unity3d基礎】Unity3d中利用NGUI實作虛拟搖杆

操作同時也分為兩種情況:

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;
    }
}
           

效果圖:

拖拽滑塊:

【Unity3d基礎】Unity3d中利用NGUI實作虛拟搖杆

點選背景:

【Unity3d基礎】Unity3d中利用NGUI實作虛拟搖杆

繼續閱讀