【NGUI】限制UIDargObject的拖拽区域(技能双摇杆的实现)

53 篇文章 1 订阅
12 篇文章 2 订阅

引言
最近在开发项目中的双摇杆功能,即利用摇杆释放指向性或者区域性的技能。之前介绍过利用NGUI开发的虚拟摇杆功能Unity3d中利用NGUI实现虚拟摇杆,本次在上文的基础上介绍一下如何限制滑块的移动区域。

需求分析
在拖拽滑块的基础上,增加区域限制。拖拽到限制区域边缘时,滑块会有被拉回的动作。

先看效果图
这里写图片描述
黑色区域为panel的区域,可以看到拖拽滑块基本被限制在panel区域内。

如何实现
UIPanel.cs中ConstrainTargetToBounds中实际裁剪的区域是如何确定的呢?
ConstrainTargetToBounds()
|__CalculateConstrainOffset()
|__finalClipRegion
finalClipRegion的实现如下,可以看出是依据Clipping的类型而进行不同的裁剪区域计算。
这里写图片描述
进而可以查看Clipping相关的属性
这里写图片描述
mclipping默认为UIDrawCall.clipping.None,mClipRange默认区域为300f*200f的矩形区域。
可以通过修改这两项参数来改变finalClipRegion的最终结果。
设置方式:
第一种可以在代码中进行设置
这里写图片描述
第二种方法也可以直接在编辑器中设置
这里写图片描述

这里写图片描述

最后,上代码:
代码在Unity3d中利用NGUI实现虚拟摇杆的基础上扩展了panel,并调用了panel.ConstrainTargetToBounds接口,其他并无二致。

using UnityEngine;
using System.Collections;

public class JoyStickDragObject : MonoBehaviour
{
    public Transform target;
    public UIPanel panel;                                       // 用于限制拖拽区域

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

        if (panel.ConstrainTargetToBounds(target, false))         //限制拖拽区域
        {
            //Debug.Log("OnDrag: ConstrainTargetToBounds");
            CancelMovement();
        }

        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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值