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

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

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

img_e9a12032cec6710c99614419e3227818.gif
相机组件层级设置.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;
    }
}
相关文章
|
4月前
|
图形学
Unity 不同Scene场景转换(简)
本文提供了Unity中实现场景转换的基本方法,包括编写传送脚本、创建传送门和玩家对象,并通过触发器实现玩家触碰传送门时切换到另一个场景的功能。
Unity 不同Scene场景转换(简)
|
4月前
|
图形学
小功能⭐️Unity获取场景中所有物体
小功能⭐️Unity获取场景中所有物体
小功能⭐️Unity获取场景中所有物体
|
3月前
|
图形学 开发者
透视与正交之外的奇妙视界:深入解析Unity游戏开发中的相机与视角控制艺术,探索打造沉浸式玩家体验的奥秘与技巧
【8月更文挑战第31天】在Unity中,相机不仅是玩家观察游戏世界的窗口,更是塑造氛围和引导注意力的关键工具。通过灵活运用相机系统,开发者能大幅提升游戏的艺术表现力和沉浸感。本文将探讨如何实现多种相机控制,包括第三人称跟随和第一人称视角,并提供实用代码示例。
169 0
|
6月前
|
图形学
【unity小技巧】FPS游戏实现相机的偏移震动、武器射击后退和后坐力效果
【unity小技巧】FPS游戏实现相机的偏移震动、武器射击后退和后坐力效果
62 1
|
6月前
|
图形学
初识Unity——基本模型、场景操作、世界坐标系和局部坐标系
初识Unity——基本模型、场景操作、世界坐标系和局部坐标系
167 1
|
6月前
|
定位技术 图形学 开发者
【Unity实战】切换场景加载进度和如何在后台异步加载具有庞大世界的游戏场景,实现无缝衔接(附项目源码)
【Unity实战】切换场景加载进度和如何在后台异步加载具有庞大世界的游戏场景,实现无缝衔接(附项目源码)
462 0
|
6月前
|
JavaScript 前端开发 C#
初识Unity——创建代码、场景以及五个常用面板(创建C#代码、打开代码文件、场景的创建、Project、Hierarchy、Inspector、Scene、Game )
初识Unity——创建代码、场景以及五个常用面板(创建C#代码、打开代码文件、场景的创建、Project、Hierarchy、Inspector、Scene、Game )
401 0
|
7月前
|
前端开发 C# 图形学
unity按钮绑定与场景切换
unity按钮绑定与场景切换
73 0
|
图形学
Unity重置场景
Unity重置场景
102 0
|
编解码 监控 vr&ar
Unity3D下如何采集camera场景数据并推送RTMP服务?
Unity3D是非常流行的游戏开发引擎,可以创建各种类型的3D和2D游戏或其他互动应用程序。常见使用场景如下:
150 1