unity3d EasyTouch滑动屏幕移动相机观看场景

unity3d相机拖拽移动脚本,结合easyTouch,不提供easyTouch插件,此脚本需easyTouch5支持,下载easyTouch后把脚本放到工程即可,然后按下面的图示例就可以了

相机组件层级设置.gif
using UnityEngine;
using HedgehogTeam.EasyTouch;
/// <summary>
/// 相机拖拽
/// </summary>
public class CameraManager : MonoBehaviour
{
    public static CameraManager Instance;
    public float OriginDistance { get; private set; }
    public Transform CameraRoot
    {
        get
        {
            if (CameraRoot_ == null)
                CameraRoot_ = GameObject.Find("MainCamera").transform;
            return CameraRoot_;
        }
    }

    public GameObject WorldCameraObj
    {
        get
        {
            if (WorldCameraObj_ == null)
                WorldCameraObj_ = GameObject.Find("WorldCamera").gameObject;
            return WorldCameraObj_;
        }
    }
    public Camera WorldCamera
    {
        get
        {
            if (WorldCamera_ == null)
            {
                WorldCamera_ = WorldCameraObj.GetComponent<Camera>();
            }
            return WorldCamera_;
        }
    }


    private Transform CameraRoot_;

    private GameObject WorldCameraObj_;

    private Camera WorldCamera_;


    // 缩放视口边界限制
    private float MinDistance = 20f;
    private float MaxDistance = 110;

    // 边界限制
    private RangeAttribute BoundX;
    private RangeAttribute BoundZ;
    public Vector2 BoundaryX;
    public Vector2 BoundaryZ;
    // 拖拽移动速度
    public float MoveSpeed = 10f;

    private Vector3 TargetPos;
    private Vector3 EulerAngles;


    public delegate void CameraOpreateHandler(Gesture gesture);
    public delegate bool CameraDragHandler(Gesture gesture);
    public delegate void CameraHandler();

    public event CameraOpreateHandler On_SwipeStart;
    public event CameraOpreateHandler On_Swipe;
    public event CameraHandler On_SwipeCamera;
    public event CameraOpreateHandler On_Pinch;
    public event CameraOpreateHandler On_Twist;
    public event CameraOpreateHandler On_SimpleTap;
    public event CameraOpreateHandler On_TouchUp;

    public event CameraOpreateHandler On_LongTapStart;
    public event CameraOpreateHandler On_LongTap;
    public event CameraOpreateHandler On_LongTapEnd;

    public event CameraDragHandler CheckCameraCanDrag;

    private void Awake()
    {
        Instance = this;
        OriginDistance = GetCameraDistance();
        TargetPos = CameraRoot.position;
        EulerAngles = CameraRoot.eulerAngles;

        EasyTouch.On_Pinch += EasyTouch_On_Pinch;
        EasyTouch.On_PinchEnd += EasyTouch_On_PinchEnd;
        EasyTouch.On_PinchIn += EasyTouch_On_PinchIn;
        EasyTouch.On_PinchOut += EasyTouch_On_PinchOut;
        EasyTouch.On_Twist += EasyTouch_On_Twist;
        EasyTouch.On_TwistEnd += EasyTouch_On_TwistEnd;
        EasyTouch.On_DragStart += EasyTouch_On_DragStart;
        EasyTouch.On_SwipeStart += EasyTouch_On_SwipeStart;
        EasyTouch.On_Drag += EasyTouch_On_Drag;
        EasyTouch.On_Swipe += EasyTouch_On_Swipe;
        EasyTouch.On_SimpleTap += EasyTouch_On_SimpleTap;
        EasyTouch.On_TouchUp += EasyTouch_On_TouchUp;
        EasyTouch.On_SimpleTap += OnSimpleTap;
        InitWorldCamera();
    }

    private void OnDestroy()
    {
        EasyTouch.On_PinchEnd -= EasyTouch_On_PinchEnd;

        EasyTouch.On_PinchIn -= EasyTouch_On_PinchIn;
        EasyTouch.On_PinchOut -= EasyTouch_On_PinchOut;

        EasyTouch.On_Twist -= EasyTouch_On_Twist;
        EasyTouch.On_TwistEnd -= EasyTouch_On_TwistEnd;

        EasyTouch.On_DragStart -= EasyTouch_On_DragStart;
        EasyTouch.On_SwipeStart -= EasyTouch_On_SwipeStart;

        EasyTouch.On_Drag -= EasyTouch_On_Drag;
        EasyTouch.On_Swipe -= EasyTouch_On_Swipe;

        EasyTouch.On_SimpleTap -= EasyTouch_On_SimpleTap;
        EasyTouch.On_TouchUp -= EasyTouch_On_TouchUp;
        EasyTouch.On_SimpleTap -= OnSimpleTap;

    }

    // 点击
    private void OnSimpleTap(Gesture gesture)
    {
        if (gesture.pickedObject)
            Debug.LogError(gesture.pickedObject.name);
    }

    private Camera CurCamera;

    private void EasyTouch_On_PinchIn(Gesture gesture)
    {
        EasyTouch.SetEnableTwist(false);
        if (CurCamera == null)
            CurCamera = WorldCameraObj.GetComponent<Camera>();
        if (CurCamera.orthographicSize >= 30)
            return;
        CurCamera.orthographicSize++;
        float v = 5 * (CurCamera.orthographicSize / 10 - 1);
        BoundX = new RangeAttribute(-20 + -v, 20 + v);
        BoundZ = new RangeAttribute(-15 + -v, 15 + v);

    }
    private void EasyTouch_On_PinchOut(Gesture gesture)
    {
        EasyTouch.SetEnableTwist(false);
        if (CurCamera == null)
            CurCamera = WorldCameraObj.GetComponent<Camera>();
        if (CurCamera.orthographicSize <= 10)
            return;
        CurCamera.orthographicSize--;
    }
    /// <summary>
    /// 缩放
    /// </summary>
    /// <param name="gesture"></param>
    private void EasyTouch_On_Pinch(Gesture gesture)
    {
        EasyTouch.SetEnableTwist(false);
        // 直接改变视口来缩放
        //Camera.main.fieldOfView += gesture.deltaPinch * Time.deltaTime;
        // 考虑到视口变太大 画面扭曲的关系,所以改成根据朝向修改坐标来完成缩放
        Vector3 pos = WorldCameraObj.transform.position + WorldCameraObj.transform.forward * (gesture.deltaPinch * Time.deltaTime * 10f / ((float)Screen.width / (float)Screen.height));
        // 缩放距离限制
        float distance = Vector3.Distance(CameraRoot_.position, pos);
        if (distance < MinDistance || distance > MaxDistance)
            return;
        WorldCameraObj.GetComponent<Camera>().orthographicSize = distance;
        WorldCameraObj.transform.position = pos;
        WorldCameraObj.transform.position = new Vector3(WorldCameraObj.transform.position.x, pos.y, WorldCameraObj.transform.position.z);
        if (On_Pinch != null)
            On_Pinch(gesture);
    }

    private void EasyTouch_On_PinchEnd(Gesture gesture)
    {
        EasyTouch.SetEnableTwist(true);
    }

    /// <summary>
    /// 旋转
    /// </summary>
    /// <param name="gesture"></param>
    private void EasyTouch_On_Twist(Gesture gesture)
    {
        EasyTouch.SetEnablePinch(false);
        CameraRoot.Rotate(Vector3.up * gesture.twistAngle);
        if (On_Twist != null)
            On_Twist(gesture);
    }

    void EasyTouch_On_TwistEnd(Gesture gesture)
    {
        //EasyTouch.SetEnablePinch( true );
    }

    /// <summary>
    /// 开始拖
    /// </summary>
    /// <param name="gesture"></param>
    private void EasyTouch_On_DragStart(Gesture gesture)
    {
        EasyTouch_On_SwipeStart(gesture);
    }

    /// <summary>
    /// 开始划
    /// </summary>
    /// <param name="gesture"></param>
    private void EasyTouch_On_SwipeStart(Gesture gesture)
    {
        if (On_SwipeStart != null)
            On_SwipeStart(gesture);
    }

    /// <summary>
    /// 拖
    /// </summary>
    /// <param name="gesture"></param>
    private void EasyTouch_On_Drag(Gesture gesture)
    {
        // Debug.LogError( "moveing" );

        EasyTouch_On_Swipe(gesture);
    }

    /// <summary>
    /// 划
    /// </summary>
    /// <param name="gesture"></param>
    private void EasyTouch_On_Swipe(Gesture gesture)
    {
        if (CheckCameraCanDrag != null)
        {
            if (!CheckCameraCanDrag(gesture))
            {
                // 如果不能拖相机,那么触发该回调,通知其它模块触发了拖动
                if (On_Swipe != null)
                    On_Swipe(gesture);
                return;
            }
        }
        float rate = Vector3.Distance(WorldCameraObj.transform.position, CameraRoot.transform.position);
        Vector3 pos = CameraRoot.transform.position;
        pos -= (CameraRoot.transform.right * gesture.deltaPosition.x / (float)Screen.width * rate * MoveSpeed);
        pos -= (CameraRoot.transform.forward * gesture.deltaPosition.y / (float)Screen.height * rate * MoveSpeed);

        // 边界限制
        if (pos.x <= (BoundX.min) || pos.x >= (BoundX.max))
        {
            return;
        }

        if (pos.z <= (BoundZ.min) || pos.z >= (BoundZ.max))
        {
            return;
        }
        TargetPos = pos;
    }

    /// <summary>
    /// 点击
    /// </summary>
    /// <param name="gesture"></param>
    private void EasyTouch_On_SimpleTap(Gesture gesture)
    {
        if (On_SimpleTap != null)
            On_SimpleTap(gesture);
    }

    /// <summary>
    /// 释放
    /// </summary>
    /// <param name="gesture"></param>
    private void EasyTouch_On_TouchUp(Gesture gesture)
    {
        if (On_TouchUp != null)
            On_TouchUp(gesture);
    }


    private void FixedUpdate()
    {
        if (Vector3.Distance(CameraRoot.position, TargetPos) > 0.1f)
        {
            CameraRoot.position = Vector3.Lerp(CameraRoot.transform.position, TargetPos, Time.deltaTime * 10f);
            if (On_SwipeCamera != null)
                On_SwipeCamera();
        }
        else
        {
            if (updateCamera != null)
            {
                updateCamera();
                updateCamera = null;
            }
        }

        if (Vector3.Distance(CameraRoot.eulerAngles, EulerAngles) > 0.1f)
        {
            Quaternion temp = new Quaternion();
            temp.eulerAngles = EulerAngles;
            CameraRoot.rotation = Quaternion.RotateTowards(CameraRoot.rotation, temp, Time.deltaTime * 50f);
        }
    }


    /// <summary>
    /// 设置触摸是否可用
    /// </summary>
    /// <param name="b"></param>
    public static void SetTouchActive(bool b)
    {
        EasyTouch.SetEnabled(b);
    }

    public float GetCameraDistance()
    {
        return Vector3.Distance(CameraRoot.position, WorldCameraObj.transform.position);
    }


    public void InitWorldCamera()
    {
        TargetPos = new Vector3(0, 0, 0);
        CameraRoot.position = TargetPos;
        EulerAngles = new Vector3(0, 0, 0);
        CameraRoot_.eulerAngles = EulerAngles;
        WorldCamera.fieldOfView = 30f;
        WorldCamera.farClipPlane = 50000;
        WorldCameraObj.transform.localPosition = new Vector3(0, 25f, 0);
        WorldCameraObj.transform.localEulerAngles = new Vector3(65f, 0, 0);
        BoundX = new RangeAttribute(BoundaryX.x, BoundaryX.y);
        BoundZ = new RangeAttribute(BoundaryZ.x, BoundaryZ.y);
    }

    /// <summary>
    /// 摄像机跳转到指定坐标
    /// </summary>
    /// <param name="pos"></param>
    /// <param name="callback"></param>
    public void MoveCameraToPosition(Vector3 pos, CameraHandler callback = null)
    {
        // 需要注意跳转目标坐标如果超出边界限制的话需要跳转目标坐标的指定方向最大值
        Vector3 temp = pos;
        if (pos.x <= BoundX.min)
            temp.x = BoundX.min;
        if (pos.x >= BoundX.max)
            temp.x = BoundX.max;
        if (pos.z <= BoundZ.min)
            temp.z = BoundZ.min;
        if (pos.z >= BoundZ.max)
            temp.z = BoundZ.max;
        TargetPos.x = temp.x;
        TargetPos.z = temp.z;
        updateCamera += callback;
    }

    private event CameraHandler updateCamera;


    public void SetTargetPOS(Vector3 pos)
    {
        TargetPos.x = pos.x;
        TargetPos.z = pos.z;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,856评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,066评论 4 62
  • 人生的荒唐莫过于 背起行囊去远方 寻找故乡 故乡太多荒唐 荒唐的我只有远走他乡 他乡在何方 海的那头虎门关 未到虎...
    原疯不动阅读 398评论 0 1
  • //DataModel.h //二级列表 #import @interfaceDataModel :NSObjec...
    万万万万万万一阅读 398评论 0 0
  • //说明:测试环境时,如有切换IP的需求,可以打开该宏,同时工程引入Settings.bundle。生产环境请一定...
    大虾咪阅读 1,539评论 0 0