easytouch 之 相机操作-移动端

我们可能会经常遇到一个这样的需求, 再3d场景里实现运行时的 相机移动,旋转,缩放拉近等。game下模拟scene里的效果。

对于pc端,或者是unity编辑器,我们可以手写几行代码实现  左键,右键来操作,但是对于移动端,是没有右键的概念的,就没法使用了。这时候可以使用touch类,获取出点,然后计算,触点个数,位移偏差,然后驱动相机实现效果,逻辑也不是很难,关键在于怎么区分双指的滑动,缩放等,双指的单个移动等,这些不是很好处理,当然,对于大佬还是简单的。

南无除此之外还有一种方法,就是找插件。移动端触屏相关的插件还是挺多的,就拿普遍使用的easytouch来讲解,这个知名度,使用度还是不低的

首先呢,这个easytouch有众多版本,unity 2018之后的版本建议使用easytouch1.8以上的版本,2017 及以下可以使用老版本,不然会有很多奇怪的错误。我这里是用2019unity 配合easytouch1.9

easytouch其实并不完善,有很多bug,也有很多坑。  但是它还是很强大,做触屏,遥感很快(前提没遇到坑)

首先,新建场景,create-easytouch -add easytouch 添加一个easytouch控制器,如图:

    

这里有很多配置,注意,如果你不需要使用3D物体的交互,如拖拽,点击等,吧上图取消勾选不然那影响相机操作

接下来先说一下遇到的坑

1,新版本的easytouch是通过注册事件监听的方式获取信息的 详细可以打开easytouch类查看,我们选择自己要使用的事件进行监听,如 单指滑动,双指滑动,缩放

2,如果有场景跳转等再运行时会导致你的相机控制或者某个其他easytouch功能再一定条件下不使用,需要将事件移除

3,如果同时监听了单指和双指,比如单指点击,双指点击,即只要单双指都有监听事件,那么恭喜你,你只能收到单指的信息,双指呗覆盖了!

4,编辑器下测试:alt键加鼠标模拟 缩放  Ctrl加鼠标模拟双指滑动 但是,如果你想获取touch的个数,返回是0!!!因为touch是只要真机上才能生效!!!

 

然后关于相机:

我采取将相机挂在一个空物体下,作为子物体的方式,这样的好处可以快速还原,旋转的时候和移动效果更佳!

移动 没什么好说,xy轴的移动就行了

缩放  相机自身向前移动

旋转  相机围绕自身轴旋转即可

接下来上脚本“、

using HedgehogTeam.EasyTouch;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Assertions.Must;
using UnityEngine.UI;

public enum State
{
    None,
    //单指
    Single,
    //缩放
    Pinch,
    //滑动
    Swipe
}
public class CameraTouchCtr : MonoBehaviour
{
    public float moveSpeed = 1;
    public float rotateSpeed = 60;
    public float zoomSpeed = 1;

    public Transform Camera;
    public State state;

    Vector2 offset;
    Touch[] touches;
    int activeCount;
    // Start is called before the first frame update
    void Start()
    {
        //OnOneTouch();
        OnTwoTouch();
    }

    // Update is called once per frame
    void Update()
    {
        if(state == State.None)
        {
            activeCount = 0;
            if (Input.touchCount > 0)
            {
                touches = Input.touches;
                for (int i = 0; i < touches.Length; i++)
                {
                    if (touches[i].phase == TouchPhase.Ended || touches[i].phase == TouchPhase.Canceled)
                        continue;
                    activeCount++;
                }
            }
            if(activeCount == 1)
            {
                state = State.Swipe;
                OnOneTouch();
            }else
            {
                OnOneTouch(false);
            }
        }

        if (activeCount <= 0 && state != State.None)
        {
            Reset();

            //if (state == State.Pinch)
            //    Reset();
            //else
            //    state = State.None;
        }
        //tex.text = state.ToString();
    }
    //单指
    private void OnOneTouch(bool regiest=true )
    {
        if(regiest)
        {
            EasyTouch.On_Swipe += On_Swipe;
            EasyTouch.On_SwipeEnd += On_SwipeEnd;
        }
        else
        {
            EasyTouch.On_Swipe -= On_Swipe;
            EasyTouch.On_SwipeEnd -= On_SwipeEnd;

        }
    }

    private void On_SwipeEnd(Gesture gesture)
    {
        state = State.None;
    }

    //双指
    private void OnTwoTouch(bool regiest = true)
    {
        if (regiest)
        {
            EasyTouch.On_Swipe2Fingers  += On_Swipe2Fingers;
            EasyTouch.On_SwipeEnd2Fingers += On_SwipeEnd;
            EasyTouch.On_Pinch += On_Pinch;
            EasyTouch.On_PinchEnd += On_SwipeEnd;
        }
        else
        {
            EasyTouch.On_Pinch -= On_Pinch;
            EasyTouch.On_Swipe2Fingers -= On_Swipe2Fingers;
            EasyTouch.On_SwipeEnd2Fingers -= On_SwipeEnd;
            EasyTouch.On_PinchEnd -= On_SwipeEnd;
        }
    }

    private void Reset()
    {
        state = State.None;
        Camera.transform.eulerAngles = Vector3.zero;
        Camera.transform.localPosition = Vector3.zero; ;
    }

    /// <summary>  
    ///  缩放
    /// </summary>  
    /// <param name="ges"></param>  
    void On_Pinch(Gesture ges)
    {
        if(state == State.Pinch)
        {
            int dir = ges.deltaPinch < 0 ? -1 : 1;//如果同时监听单个手指的事件,返回值将获取为0
            Camera.transform.position += Camera.transform.forward * zoomSpeed * dir*Time .deltaTime ;
        }else
        {
            //缩放
            if (Mathf.Abs(ges.deltaPinch) > 10)
            {
                state = State.Pinch;
                int dir = ges.deltaPinch < 0 ? -1 : 1;
                Camera.transform.position += Camera.transform.forward * zoomSpeed * dir * Time.deltaTime;
            }
            else
            {
                On_Swipe2Fingers(ges);
            }
        }
      
    }

    /// <summary>  
    /// 双指滑动 
    /// </summary>  
    /// <param name="ges"></param>  
    void On_Swipe2Fingers(Gesture ges)
    {
        state = State.Swipe;
        if(Mathf .Abs ( ges .deltaPosition .x) > 10)
        {
            Camera.transform.Rotate(-Vector3 .up *rotateSpeed * ges .deltaPosition.normalized  .x * Time.deltaTime);
        }else
        {
            Camera.transform.Rotate(-Vector3 .right * rotateSpeed * ges.deltaPosition.normalized .y * Time.deltaTime);
        }
        

    }

    /// <summary>  
    /// 单指滑动
    /// </summary>  
    /// <param name="ges"></param>  
    void On_Swipe(Gesture ges)
    {
        state = State.Swipe;
        transform.Translate(-ges.deltaPosition.normalized * moveSpeed * Time.deltaTime);
    }

}

为了规避单指覆盖问题等,我采取update获取touch个数,进行动态单指监听

然后放一下使用图:

 

 

插件和源码

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值