微信小游戏中拖拽场景位置的限制代码

发布时间 2023-12-19 13:45:06作者: 温暖的海
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(Camera))]
public class CameraControl : MonoBehaviour
{
    public static CameraControl instance;
    public List<string> list_RayName = new List<string>();
    public Camera m_cam;
    private Transform m_selfTrans;
    private bool m_fingerDown = false;
    public RaycastHit hit;
    //当场景显示之前出现UI界面就关闭拖拽
    public bool Boxcoller_bol = true;//判断碰撞框是否激活

    /// <summary>
    /// 单指滑动的手指位置
    /// </summary>
    private Vector3 m_oneFingerDragStartPos;
    /// <summary>
    /// 双指缩放的上一帧的双指距离
    /// </summary>
    private float m_twoFingerLastDistance = -1;


    private void Awake()
    {
        instance = this;
        m_cam = GetComponent<Camera>();
        m_selfTrans = transform;
        list_RayName.Add("Hospital_panel");
        list_RayName.Add("Hospital_panel_1");
        list_RayName.Add("Hoof_repair_rooms");
        list_RayName.Add("Hoof_repair_room_2");
        list_RayName.Add("Pancake_tudio_2");
        list_RayName.Add("Wall");
        list_RayName.Add("Caltha");
        list_RayName.Add("Bar");
        list_RayName.Add("Gaming");
        list_RayName.Add("Guidance_table");
    }

    private void Update()
    {
#if UNITY_EDITOR || UNITY_STANDALONE
        if (Boxcoller_bol)
        {
            if (Input.GetMouseButtonDown(0))
            {
                Ray ray = m_cam.ScreenPointToRay(Input.mousePosition);
                RaycastHit hitInfo;  //射线对象(结构体),存储了相关信息
                                     //发出射线检测碰撞,返回一个布尔值(是否发生碰撞),这里的out下面会详解
                                     //碰到了标签是123的碰撞盒物体
                if (Physics.Raycast(ray, out hitInfo))
                {
                    hit = hitInfo;
                    for (int i = 0; i < list_RayName.Count; i++)
                    {
                        //Debug.Log(hitInfo.transform.gameObject.layer);
                        if (list_RayName.Contains(hitInfo.transform.name))
                        {
                            m_fingerDown = true;
                            m_oneFingerDragStartPos = GetWorldPos(Input.mousePosition);
                        }
                    }
                }
            }

            if (Input.GetMouseButtonUp(0))
            {

                m_fingerDown = false;
                m_twoFingerLastDistance = -1;
            }

            if (m_fingerDown)
            {
                HandleFingerDragMove(Input.mousePosition);
            }
            var distance = Input.GetAxis("Mouse ScrollWheel");
            HandleMouseScrollWheel(distance * 10);
        }
#else
        if(Boxcoller_bol)
        {
            if (2 == Input.touchCount)
            {
                // 双指缩放
                HandleTwoFingerScale();
            }
            else if (1 == Input.touchCount)
            {
                if (TouchPhase.Began == Input.touches[0].phase)
                {   
                    Ray ray = m_cam.ScreenPointToRay(Input.mousePosition);
                    RaycastHit hitInfo;  
                     if (Physics.Raycast(ray, out hitInfo))
                    {
                        if (list_RayName.Contains(hitInfo.transform.name))
                        {
                            m_fingerDown = true;
                            m_oneFingerDragStartPos = GetWorldPos(Input.mousePosition);
                        }
                    }
                }
                else if (TouchPhase.Moved == Input.touches[0].phase)
                {
                    // 单指滑动
                    HandleFingerDragMove(Input.touches[0].position);
                }
                m_twoFingerLastDistance = -1;
            }
            else
            {
                m_fingerDown = false;
                m_twoFingerLastDistance = -1;
            }
        }
#endif
    }


    /// <summary>
    /// 单指滑动
    /// </summary>
    private void HandleFingerDragMove(Vector2 fingerPos)
    {
        //滑动差
        Vector3 cha = m_oneFingerDragStartPos - GetWorldPos(fingerPos);
        Vector3 newP = m_cam.transform.position;
        newP.x = newP.x + cha.x;
        if (newP.x > 16f) { newP.x = 16f; }
        if (newP.x < -16f) { newP.x = -16f; }
        newP.y = newP.y + cha.y;
        if (newP.y > 23.4f) { newP.y = 23.4f; }
        if (newP.y < -23.4f) { newP.y = -23.4f; }

        m_selfTrans.position = newP;
    }

    /// <summary>
    /// 双指缩放
    /// </summary>
    private void HandleTwoFingerScale()
    {
        float distance = Vector2.Distance(Input.touches[0].position, Input.touches[1].position);
        if (-1 == m_twoFingerLastDistance) m_twoFingerLastDistance = distance;
        // 与上一帧比较变化
        float scale = 0.1f * (distance - m_twoFingerLastDistance);
        ScaleCamere(scale);
        m_twoFingerLastDistance = distance;
    }

    /// <summary>
    /// 鼠标滚轮缩放
    /// </summary>
    /// <param name="distance"></param>
    private void HandleMouseScrollWheel(float distance)
    {
        if (0 == distance) return;
        ScaleCamere(distance);
    }

    /// <summary>
    /// 缩放摄像机的视口
    /// </summary>
    /// <param name="scale"></param>
    private void ScaleCamere(float scale)
    {
        m_cam.orthographicSize -= scale * 0.5f;//缩小放大速度
        if (m_cam.orthographicSize < 10)//最小可视距离
        {
            m_cam.orthographicSize = 10;
        }
        if (m_cam.orthographicSize > 20)//最大可视距离
        {
            m_cam.orthographicSize = 20;
        }
    }

    /// <summary>
    /// 屏幕坐标换算成3D坐标
    /// </summary>
    /// <param name="screenPos">屏幕坐标</param>
    /// <returns></returns>
    Vector3 GetWorldPos(Vector2 screenPos)
    {
        return m_cam.ScreenToWorldPoint(new Vector3(screenPos.x, screenPos.y, 0));
    }
}