• Unity实现放大缩小以及相机位置平移实现拖拽效果


    放大缩小功能是游戏开发中用到的功能,今天就来讲一下Unity中放大缩小怎么实现。

    1.IDragHandler, IBeginDragHandler, IEndDragHandler这三个接口是Unity常用的接口,分别对应于拖拽,开始拖拽,可结束拖拽(需要注意的是,这三个接口只能运用在UGUI(无需添加Collider),Sprite不能使用(Sprite可以使用OnMouseDown,OnMouseDrag,OnMouseUp)),并且拖拽物体需要是Cavas下面的子元素。

    先看一下简单的拖拽开始和拖拽结束,拖拽开始只有简单的判断是不是单点点击,记录点击的位置,标记拖拽状态为true。结束拖拽里面标记拖拽状态为flase。

        public void OnBeginDrag(PointerEventData eventData)
        {
            if (Input.touchCount <= 1)
            {
                isDrag = true;
                lastPoint = Input.mousePosition;
            }
        }
    
        public void OnEndDrag(PointerEventData eventData)
        {
            isDrag = false;
        }

    重点看一下拖拽中这个方法:这个方法是在你按下的过程中一直在执行,基本上每一行都有注释,应该都很好懂的

        public void OnDrag(PointerEventData eventData)
        {
    
            if (isDrag && Input.touchCount <= 1)
            {
                //记录当前鼠标位置
                currentPoint = Input.mousePosition;
                //记录移动的距离 -号是因为我们要移动的是因为相机来显示物体的移动
                //如果自己移动物体可以不加上-,原理是一样的,直接移动物体会造成重构,特别的有大量物体(比如地图的时候就会出现这种情况),性能上会消耗巨大
                moveDir = -(currentPoint - lastPoint);
                //规整z轴方向
                moveDir = new Vector3(moveDir.x, moveDir.y, 0);
                
                //如果移动的距离为0那么说明没有进行拖拽,直接返回
                if (moveDir == Vector3.zero)
                {
                    return;
                }
    
                //这一段可以参考 https://www.jianshu.com/p/148725feecfa
                //主要用于做到屏幕移动距离和相机移动距离保持一致,不随着缩放而改变
                float aspect = eyeCamera.aspect;
                float halfFOVTan = Mathf.Tan((eyeCamera.fieldOfView * 0.5f) * Mathf.Deg2Rad);
                float hight = Mathf.Abs(eyeCamera.transform.position.z) * halfFOVTan * 2;// 参照图片(计算透视相机视口宽高示意图)
                float width = hight * aspect;
                //计算实际上相机需要移动的距离
                moveDir.x = moveDir.x / Screen.width * width;
                moveDir.y = moveDir.y / Screen.height * hight;
                
                //相机移动距离:moveDir后面乘上的是一个下面我们要说的一个缩放系数,如果不加上的话会导致缩小之后移动比较慢一点,放大之后移动比较快速
                eyeCamera.transform.Translate(moveDir * scale/6.6f);
    
                if (lastPoint != currentPoint)
                {
                    lastPoint = currentPoint;
                }
            }
        }

    2.放大缩小

     
        //这里是因为我用的正交相机,而正交相机的默认size等于6.6    
       private float scale = 6.6f;
    public void ScaleView()
    {
    //多点触摸, 放大缩小(记录两个新的触摸点)
    Touch newTouch1 = Input.GetTouch(0);
    Touch newTouch2 = Input.GetTouch(1);
         //判断是不是取消了,或者是新的点点击了或者抬起了直接退出ScaleView方法
    for (int i = 0; i < Input.touchCount; ++i)
    {
    if (Input.GetTouch(i).phase == TouchPhase.Began || Input.GetTouch(i).phase == TouchPhase.Canceled ||
    Input.GetTouch(i).phase == TouchPhase.Ended)
    {
    //取消之后当前点变成了上一个记录点
    lastTouch2 = newTouch2;
    lastTouch1 = newTouch1;
    return;
    }
    }

    //计算老的两点距离和新的两点间距离,变大要放大模型,变小要缩放模型
    float lastDistance = Vector2.Distance(lastTouch1.position, lastTouch2.position);
    float newDistance = Vector2.Distance(newTouch1.position, newTouch2.position);

    //两个距离之差,为正表示放大手势, 为负表示缩小手势
    float offset = lastDistance - newDistance;
    //放大因子, 一个像素按 0.01倍来算(100可调整)
    float scaleFactor = offset / zoomFactor;
    //当前的相机size
    float localScale = eyeCamera.orthographicSize;
    //计算整体的放大倍数
    scale = localScale + scaleFactor;
    if (scale < minScale)
    {
    scale = minScale;
    }
    else if (scale > maxScale)
    {
    scale = maxScale;
    }
    //调整相机的尺寸
    Scale2D.SetCameraOrthographicSize(scale, eyeCamera);
    //记住最新的触摸点,下次使用
    lastTouch1 = newTouch1;
    lastTouch2 = newTouch2;
    }
  • 相关阅读:
    C/C++多文件之间的变量定义
    PKU POJ 2186 Popular Cows 强连通分量
    重载函数
    ZOJ 2763 Prison Break
    201357 训练赛总结
    hdu 4467 Graph 构造
    201356 训练赛总结
    201353 NEERC 2012, Eastern subregional contest
    2013512 CF 183 总结
    一道动态规划
  • 原文地址:https://www.cnblogs.com/txfd/p/11323734.html
Copyright © 2020-2023  润新知