前段时间需要做到识别屏幕滑动的一个简单识别,甚至搜了一些插件,有FingerGesture什么的。这样的组件功能缺失很强大,但是仅为简单的识别就倒入一个大的资源包太不值得。发现简单的包装下UIScrollView组件就可以实现左右上下滑屏,而且也不会有多余的性能开销。
先上效果图,可以识别上下左右的滑动,左上角的按钮为初始组件,右边的log是添加的回调事件。
我用的NGUI版本是3.7.2,NGUI更新的感觉比较快,更新着可能以前的组件字段就失去意义了。在这里我主要用到了UIScrollView的一个字段:mLastPos,其实记录的是滑动是最后滑动到的坐标点,再增加一个变量mStartPos,记录鼠标落下时的坐标,两个坐标就能简单计算出滑动的方向了。
protected Vector3 mLastPos; protected Vector3 mStartPos; //记录当前点的坐标 public Vector3 MLastPos { get { return mLastPos; } } public Vector3 MStartPos //刚点击的坐标 { get { return mStartPos; } }
其中mStartPos赋值为press事件触发的时候,如图:
好了,定义好UIScrollView必须的变量,可以开始写我们自己的组件了,新建一个文件MyScrollView,预定义移动方向枚举:
public enum MoveDirection { toRight= 1, toLeft = 2, toDown = 3, toUp = 4, none = 5 }
//组件中定义一个回调事件 <span style="line-height: 29.7000007629395px; font-family: 'microsoft yahei'; white-space: pre-wrap;">OnDragFnishDelegate</span>
public class MyScrollView: MonoBehaviour { private UIScrollView _scrollView; public delegate void OnDragFnishDelegate(MoveDirection dirction); public OnDragFnishDelegate onDragFinishCallback; private const float MOVE_MIN = 0.01f; private Vector2 _areaSize; }
添加一个组件初始化接口,传入的回调事件。其中传入的Vector2参数是后来扩充的用来指定滑动区域尺寸的一个参数。
public void InitComponent( Vector2 areaSize,OnDragFnishDelegate onDragFinishcallback = null) { _areaSize = areaSize; _scrollView = this.GetComponent<UIScrollView>(); _scrollView.onDragFinished = OnDragFnish; onDragFinishCallback = onDragFinishcallback; this.GetComponent<UIPanel>().SetRect(0, 0, areaSize.x, areaSize.y); this.transform.FindChild("grid").GetComponent<UIGrid>().cellWidth = areaSize.x; this.transform.FindChild("grid").GetComponent<UIGrid>().cellHeight = areaSize.y; Transform sprTran = this.transform.FindChild("grid/item").transform; sprTran.GetComponent<BoxCollider>().size = new Vector3(areaSize.x, areaSize.y, 0f); sprTran.GetComponent<UISprite>().width = (int)areaSize.x; sprTran.GetComponent<UISprite>().height = (int)areaSize.y; sprTran.GetComponent<UISprite>().alpha = 0.1f; // *= new Color(1, 1, 1, 0.1f); }
onDragFinish的实现就用于计算滑动的方向:
//拖拽的回调 private void OnDragFnish() { Vector3 moveRelative = _scrollView.MLastPos - _scrollView.MStartPos; //移动的相对坐标 MoveDirection curDir = MoveDirection.none; //决定识别水平还是垂直的 if(Mathf.Abs(moveRelative.x) > Mathf.Abs(moveRelative.y)) { if(Mathf.Abs(moveRelative.x) < MOVE_MIN) { return ; } if(moveRelative.x>= MOVE_MIN) { curDir = MoveDirection.toRight; } if(moveRelative.x<=-MOVE_MIN) { curDir = MoveDirection.toLeft; } } else { if(Mathf.Abs(moveRelative.y) < MOVE_MIN) { return; } if(moveRelative.y>=MOVE_MIN) { curDir = MoveDirection.toUp; } if(moveRelative.y <= -MOVE_MIN) { curDir = MoveDirection.toDown; } } //Log("拖拽完毕=" + moveRelative+",dir="+curDir.ToString()); //拖拽完毕的回调 if (onDragFinishCallback != null) { onDragFinishCallback(curDir); } }外部需要引用组件时:先要有个规范的ScrollView滑动节点如场景中:
其中,ScrollArea节点要包含UIpanel、UIScrollView组件,grid节点要包含UIGrid组件,item组件要包含DragScrollView、BoxCollider、UIsprite组件(不放张图不让人滑动,应该被直接过滤掉了。编辑状态下确实很丑,但是我试过,换用一张png透明度调的足够小就可以几乎看不清滑动区域了。)
场景的入口脚本中OnGUI()只需要添加一个简单的组件初始化代码,点击按钮后就调用滑动组件了:
void OnGUI() { if (GUILayout.Button("初始化 滑动组件")) { GameObject scrollObj = GameObject.Find("uiRoot/ScrollArea") as GameObject; MyScrollView scrollViewCom = scrollObj.AddMissingComponent<MyScrollView>(); scrollViewCom.InitComponent(new Vector2(500, 500), ScrollFinishCallback); } }
最后附上附带下载链接:
http://download.csdn.net/detail/stephanie_1/8794169
建一个空项目,import这个资源包打开scrollView场景就可以运行看效果了。