在Unity中通过Camera实现类似地图拉拽缩放的功能

这篇具有很好参考价值的文章主要介绍了在Unity中通过Camera实现类似地图拉拽缩放的功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在最近的工作中任务是制作一个导览图系统,需要用到的一个需求就是可以拖动和放大地图,参考网上有很多UI描点大法的实现,我想尝试在摄像机上去实现。

在Unity中通过Camera实现类似地图拉拽缩放的功能

由于地图偏平面,我使用的是用2D模式下的摄像机,将摄像机的Projection(投影)属性设置成,Orthographic。

我首先想到的是通过直接改变摄像机Size实现缩放效果,通过 Input.GetAxis("Mouse ScrollWheel")获取鼠标滚轮的滚动量来改变Size的大小


    public Camera me_camera;     // 参与变换的摄像机
    public Vector2 range_size = new Vector2(1, 5);     // 通过这个来控制Size缩放量
    // 位置缩放
    public void ScreenZoom()
    {
        float v = Input.GetAxis("Mouse ScrollWheel");   //获取鼠标滚轮方向
        float old_size = me_camera.orthographicSize;         // 计算摄像机原来的大小
        // 计算移动后的大小
        float size = Mathf.Clamp(old_size - v, range_size.x, range_size.y);
        me_camera.orthographicSize = size; 
    }

 不过这个效果emmm怎么说吧,通过和别人的地图作比较发现,还是差一些意思。

在Unity中通过Camera实现类似地图拉拽缩放的功能

 文章来源地址https://www.toymoban.com/news/detail-492711.html

最后还是找到一个贴子参考,看了他人的文章一下子悟了,参考文章如下。

根据观察,我发现一个规律,别人的缩放是在视点缩放,在摄像机size缩小时位置会无限接近视点位置,而且的移动的长度(相对摄像机到视点的位置)和摄像机size缩放的倍数是相同的,比如摄像机size比原来缩小了 1/2 摄像机就会向视点位置移动原位置的 1/2 。

在Unity中通过Camera实现类似地图拉拽缩放的功能

假设摄像机原来大小是oldSize、位置是pos,缩小后的大小是size、位置是newPos, 视点使用鼠标位置为mousePos,所以得到如下公式:

 其中因为视点到摄像机的位置是在坐标系上的,要排除掉原点到摄像机的距离,因为其他条件是已知的,将公式简化则可以得到 newPos。

代码修改如下:

    public Camera me_camera;     // 参与变换的摄像机
    public Vector2 range_size = new Vector2(1, 5);     // 通过这个来控制Size缩放量

    /// <summary>
    /// 根据视点缩放
    /// </summary>
    public void AnchorZoom()
    {
        float v = Input.GetAxis("Mouse ScrollWheel");
        // 计算摄像机原来的大小
        float old_size = me_camera.orthographicSize;
        // 计算移动后的大小
        float size = Mathf.Clamp(old_size - v, range_size.x, range_size.y);
        // 计算摄像机的缩放倍数 
        float pro = (old_size - size) / old_size;        
        // 公式
        Vector3 position = me_camera.transform.position + (me_camera.ScreenToWorldPoint(Input.mousePosition) - me_camera.transform.position) * pro;
        // 应用大小缩放
        me_camera.orthographicSize = size;
        //位置缩放
        me_camera.transform.position = new Vector3(position.x, position.y, me_camera.transform.position.z);
    }

其中,mousePosition 的值需要经过ScreenToWorldPoint( )  方法来转换成世界坐标去进行运算。

缩放搞定,然后是平移功能。摄像机平移功能比较简单,我直接采用的就是平移的方法。

    // 参与变换的摄像机
    public Camera me_camera;
    // 通过这个来控制画面缩放量
    public Vector2 range_size = new Vector2(2, 5);

    public void ScreenMove()
    {
        // 鼠标 左键
        float x = Input.GetAxis("Mouse X");
        float y = Input.GetAxis("Mouse Y");
        if (Input.GetMouseButton(0))
        {
            // 相机位置的偏移量(Vector3类型,实现原理是:向量的加法)
            Vector3 moveDir = (x * -me_camera.transform.right) + (y * -me_camera.transform.up);
            // 使平移速度被size影响 size 越小移动越慢 
            float speed = (me_camera.orthographicSize / range_size.y) * 0.5f;
            moveDir = moveDir * speed;
            // 限制y轴的偏移量
            me_camera.transform.position += moveDir;
        }
    }

      制作一个将摄像机的可移动画面划一个范围,超过范围慢慢会回来的效果。于是我将摄像机想象成一个矩形rect,在它的外面有一个更大的矩形rangeRect,然后你只需要判断rect是不是在rangeRect里面。在Unity中直接有Rect可以使用,只需要取分别的顶点在世界坐标里的位置就可以了,这样就可以算出宽和高。

在Unity中通过Camera实现类似地图拉拽缩放的功能

 加上限制的平移代码如下:


    // 参与变换的摄像机
    public Camera me_camera;
    // 通过这个来控制画面缩放量
    public Vector2 range_size = new Vector2(2, 5);
    // 限制运动范围矩形
    Rect rect, rangeRect;

    void Start()
    {
        Camera.main.orthographicSize = range_size.y;

        // 在这里定义矩形限制的范围
        var Start_leftTop = Camera.main.ScreenToWorldPoint(new Vector3(0, Screen.height, 0));
        var Start_rightButtom = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, 0, 0));
        rangeRect = new Rect(Start_leftTop.x, Start_leftTop.y, Mathf.Abs(Start_rightButtom.x - Start_leftTop.x), Mathf.Abs(Start_rightButtom.y - Start_leftTop.y));

        Camera.main.orthographicSize = range_size.x;
    }

    void Update()
    {
        ScreenMove();
    }

    public void ScreenMove()
    {
        // 鼠标 左键
        float x = Input.GetAxis("Mouse X");
        float y = Input.GetAxis("Mouse Y");
        if (Input.GetMouseButton(0))
        {
            // 相机位置的偏移量(Vector3类型,实现原理是:向量的加法)
            Vector3 moveDir = (x * -me_camera.transform.right) + (y * -me_camera.transform.up);
            // 使平移速度被size影响 size 越小移动越慢 
            float speed = (me_camera.orthographicSize / range_size.y) * 0.5f;
            moveDir = moveDir * speed;
            // 限制y轴的偏移量
            me_camera.transform.position += moveDir;
        }
        else //限制摄像机运动范围   
        {         
            UpdateNowCameraRect();
            //是否出顶
            if (rect.y > rangeRect.y) 
            {
                float d = rect.y - rangeRect.y;
                me_camera.transform.position -= new Vector3(0, d * 0.05f, 0);
            }
            // 底低于底部
            if (rect.y - rect.height < rangeRect.y - rangeRect.height)
            {
                float d = (rangeRect.y - rangeRect.height) - (rect.y - rect.height);
                me_camera.transform.position -= new Vector3(0, -d * 0.05f, 0);
            }
            // 低于最左边
            if (rect.x < rangeRect.x)
            {
                float d = rangeRect.x - rect.x;
                me_camera.transform.position -= new Vector3(-d * 0.05f, 0, 0);
            }
            // 高于最右边
            if (rect.x + rect.width > rangeRect.x + rangeRect.width)
            {
                float d = (rect.x + rect.width) - (rangeRect.x + rangeRect.width);
                me_camera.transform.position -= new Vector3(d * 0.05f, 0, 0);
            }
        }
    }

    /// <summary>
    /// 更新当前摄像机的矩形
    /// </summary>
    void UpdateNowCameraRect()
    {
        var Now_leftTop = Camera.main.ScreenToWorldPoint(new Vector3(0, Screen.height, 0));
        var Now_rightButtom = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, 0, 0));
        rect.Set(Now_leftTop.x, Now_leftTop.y, Mathf.Abs(Now_rightButtom.x - Now_leftTop.x), Mathf.Abs(Now_rightButtom.y - Now_leftTop.y));
    }

 平移和缩放都完成,最终效果如下。

在Unity中通过Camera实现类似地图拉拽缩放的功能

 最后附上所有代码,里面有触控屏上的移动方法,直接下载用就行,因为太长我就不再这里展示啦。

https://download.csdn.net/download/HunagJingLiao/87267232

 

到了这里,关于在Unity中通过Camera实现类似地图拉拽缩放的功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【学习笔记】Unity基础(七)【uGUI基础、利用render Texture实现小地图功能】

    转载请注明出处:🔗https://blog.csdn.net/weixin_44013533/article/details/130808689 本篇基本是大纲性质,参考价值不大,只有最后一小节“利用render Texture实现小地图功能”花了点时间,可以看看,不过也用到了上面的canvas、UI image等知识、以及input等脚本功能,也算一个小练手吧 倒是

    2024年02月08日
    浏览(47)
  • 19. Unity - 2D游戏开发小记02 --- 伪透视图、2D物体碰撞、瓦片地图碰撞、素材缩放平铺

    1. 伪视图 在2D游戏开发当中,当角色移动时,会发生物体与物体之间的前后遮挡。2D视图中的前后关系是由 Y 轴决定,y 值越小物体越靠前。unity的渲染应开启根据 y 值的大小进行渲染才能保证正确的遮挡效果,在菜单栏 Editor–project setting -- Graphic 中按照下图方式进行设置:

    2024年02月02日
    浏览(94)
  • 【学习笔记】Unity基础(八)【镜头camera组件属性(clear flag、target texture、occlusion culling、镜面效果、小地图等)】

    转载请注明出处:🔗https://blog.csdn.net/weixin_44013533/article/details/131071235 参考: 官网手册 Graphics 本人使用的unity版本是2021.3.25f 摄像机所看到的内容由它的Transform和 Camera component来定义。Transform position 定义了视点,其向前的 (Z) 轴定义视图方向。Camera 组件的设置还定义了视图中

    2024年02月13日
    浏览(45)
  • Unity- 控制物体旋转、移动、缩放的功能

    本文章主要介绍Unity中控制物体旋转、移动、缩放的方法~ 旋转: (一)控制物体自转 (二)控制物体A绕着物体B转 脚本放在物体A上,再将物体B拖到脚本相应位置上 移动: 物体不断向前移动  扩展:使用键盘(上下左右箭头)控制物体前后左右移动 缩放: ① 物体放大一倍

    2024年02月08日
    浏览(49)
  • Unity控制相机旋转、移动、缩放等功能

    提示: 该脚本允许你以指定的速度和角度围绕模型进行相机旋转,并可以控制相机的移动和缩放 将该脚本添加到一个游戏对象上,并将其作为主摄像机。 1、在Unity编辑器中,你可以在脚本的参数变量部分调整相机的速度、缩放和移动等设置。根据需求,修改各个参数的值。

    2024年02月04日
    浏览(57)
  • 微信小程序 MapContext.includePoints实现自动缩放地图大小

    记录一下微信小程序实现自动缩放地图大小的过程 官方文档地址: MapContext.includePoints 最近做了个功能,根据用户和商家之间的距离画出导航线,然后根据距离自动缩放地图的scale 然鹅!官方文档又是一笔带过,没办法,查资料查的一肚子火,好在最后还是实现了,直接贴代

    2024年02月16日
    浏览(46)
  • web前端在vue中通过海康插件嵌入视频,实现实时预览以及视频回放功能

      首先第一步,在海康官网下海康视频插件下载到电脑中海康开放平台    然后新建一个组件,下面我直接把我封装好的组件代码拿出来,重要的地方我在代码中添加了注释   以上是封装的组件,下面是调用的方法   

    2024年02月03日
    浏览(57)
  • vue+echart实现3d地图可拖拽、缩放、区域填充颜色(geo3D)

    功能背景 一个略微比2d地图炫酷一些的3d地图, 1、可对区域进行不同颜色填充。 2、可拖拽缩放地图 3、鼠标悬停高亮某区域。 (注意:当开启了鼠标悬停series,并高亮某个数据的时候,会导致地图的拖拽缩放出现卡顿,因为相当于是事件重叠了。。。目前还没想到好的解决方

    2024年02月13日
    浏览(49)
  • 类似微信预览缩放保存插件previewImage.js

    很好用的预览缩放保存插件。 插件源码如下:     (function(){         let insideObject = {             // \\\'inputId\\\' : \\\'\\\'    //  用于页面多图片预览时绑定相应预览图片             \\\'inputName\\\':\\\'plantIconPath\\\',  // 用于表单提交             \\\'imageId\\\':\\\'preview_img\\\',    // 用于预览图

    2024年02月11日
    浏览(46)
  • Mysql 实现类似于 ElasticSearch 的全文检索功能

    ​ 一、前言 今天一个同事问我,如何使用 Mysql 实现类似于 ElasticSearch 的全文检索功能,并且对检索跑分?我当时脑子里立马产生了疑问?为啥不直接用es呢?简单好用还贼快。但是听他说,数据量不多,客户给的时间非常有限,根本没时间去搭建es,所以还是看一下

    2024年02月03日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包