先放参考文章:

Unity3d UGUI以鼠标位置点为中心缩放图片(含项目源码)https://blog.csdn.net/qq_33789001/article/details/117749837

再放实现效果:


说说事情缘由,项目需要用到这个效果,所以上网找了个参考文章,后来不知道为什么失效了,所以想着自己改改,看看是什么毛病。

贴原码:

    //ZoomObj是需要缩放的UIprivate void ZoomImgByMousePos(GameObject ZoomObj){//判断鼠标滚轮是否滚动if (Input.GetAxis("Mouse ScrollWheel") == 0)return;//一些变量的声明RectTransform RectTran = ZoomObj.GetComponent<RectTransform>();float PivotX = RectTran.pivot.x;float PivotY = RectTran.pivot.y;float OffsetX = 0f;float OffsetY = 0f;Vector2 addOffset;//获取轴心点在屏幕的坐标previewPosition = Camera.main.WorldToScreenPoint(RectTran.position);//获取鼠标坐标newPosition = Input.mousePosition;//计算偏差值addOffset = newPosition - previewPosition;//计算轴心点偏移量if (RectTran.rect.width != 0 && ZoomObj.transform.localScale.x != 0)OffsetX = addOffset.x / RectTran.rect.width / RectTran.localScale.x;if (RectTran.rect.height != 0 && ZoomObj.transform.localScale.y != 0)OffsetY = addOffset.y / RectTran.rect.height / RectTran.localScale.y;//计算轴心点新值RectTran.pivot += new Vector2(OffsetX, OffsetY);//计算UI新位置RectTran.anchoredPosition += addOffset;//放大UIif (Input.GetAxis("Mouse ScrollWheel") > 0)ZoomObj.localScale += (ZoomObj.localScale.x >= MaxScale - 0.1f ? Vector3.zero : Vector3.one * 0.1f);else if (Input.GetAxis("Mouse ScrollWheel") < 0)ZoomObj.localScale += (ZoomObj.localScale.x < MinScale + 0.1f ? Vector3.zero : Vector3.one * -0.1f);}

对比一下原文章可以发现改动了一下地方,改了些Bug和实现原理。原文章其实我不太能看懂,省了太多说明内容,把我一个数学苦手和Unity新手看哭了。

解释一下关键的代码内容,先说明某些变量需要在脚本类内赋值,请自行修改。

获取轴心点在屏幕的坐标

//获取轴心点在屏幕的坐标
previewPosition = Camera.main.WorldToScreenPoint(RectTran.position);

通过UI的世界坐标转换为屏幕坐标,UI的世界坐标好像是UI的轴心点位于世界坐标的位置,因为轴心点不会离开屏幕,所以可以放心转换获取值。

之所以要放在开头,是因为后面缩放UI后轴心点就会偏移。这个偏移不会在UI缩放的代码块结束后就更改,会有一段延迟,如果放在最后,很有可能不会捕捉到更改的值。

计算偏差值

//计算偏差值
addOffset = newPosition - previewPosition;

计算鼠标位置和轴心点位于屏幕位置的差

计算轴心点偏移量

//计算轴心点偏移量
if (RectTran.rect.width != 0 && ZoomObj.transform.localScale.x != 0)OffsetX = addOffset.x / RectTran.rect.width / RectTran.localScale.x;
if (RectTran.rect.height != 0 && ZoomObj.transform.localScale.y != 0)OffsetY = addOffset.y / RectTran.rect.height / RectTran.localScale.y;

通过偏移值计算出缩放后UI轴心点的偏移距离,这个偏移距离是就鼠标位置而言的,因为轴心点的位置是默认和鼠标位于同一位置。屏幕坐标的单位距离和锚定坐标系的单位距离是一致的,所以可以直接用偏移值除以放大后的UI宽高获得轴心点的偏移距离。

计算轴心点位置

//计算轴心点新值
RectTran.pivot += new Vector2(OffsetX, OffsetY);

移动轴心点到鼠标位置

计算UI位置

//计算UI新位置
RectTran.anchoredPosition += addOffset;

UI的位置必须要加上偏移值,这个位置可以是当地坐标或者是锚定坐标。似乎是UI的轴心点移动会伴随着UI位置的移动。如果不加会发现UI会在缩放后偏移预定坐标一段距离,这个多偏移的距离就是上面计算的偏移值。具体逻辑不太清楚 ,应该是Unity底层设定的。


总结

说来惭愧,这篇文章是有初版的,我列举了一些可能会有问题的地方,结果我转头就踩坑了。初版是因为屏幕大小和UI大小相同才能侥幸拿到想要的效果,实际上如果改改UI的大小就出错了。然后多花了几小时来修Bug,重新修订了这篇文章,这一版的内容应该是正确的。

其实这个效果还不够还,感觉一卡一卡的,实际上可以再改良一下,减小滚轮数值,用协程循环进行几次缩放来达到同样的效果,我想这会更流畅些,当然也会更吃配置。不过我太懒了,这里就留给大家自己优化吧。

建议自己去实验一下,改改不同的地方,看看效果怎么样,只看代码的话是很难理解的。如果是一直做Unity2D项目的话或早或晚都会遇到这个问题,早点搞懂可以加深自己对Unity组件的了解,反正我没做到就是了。

最好是Unity内置缩放功能,为什么不内置呢?

最后,希望能帮到有困难的小伙伴吧,祝各位好运。

Unity2D 实现UGUI滚动鼠标滑轮以鼠标位置点为中心缩放图片相关推荐

  1. js 以鼠标为中心缩放图片

    原理 使用的绘制方法 void ctx.drawImage(image, dx, dy, dWidth, dHeight); 参数说明: dx image的左上角在目标canvas上 X 轴坐标. d ...

  2. html怎么做到滚动鼠标转换,横向的网页如何实现鼠标滑轮横向移动?_html/css_WEB-ITnose...

    横向的网页如何实现鼠标滑轮横向移动? 我做一个学校的点餐网页,想横向的形式,网页已经做出来了,如何实现鼠标滚轮是横向来移动滚动条的? 还有有没可能添加一个按钮,按一下制定滚动条向右移动某些个像素点?我 ...

  3. 更改Windows鼠标滑轮滚动方向

    经常在Mac和Windows PC切换的人往往会遇到这样一个问题,那就是鼠标滑轮的方向恰好相反.改变Mac的鼠标滑轮滚动方向很简单,系统偏好设置-鼠标-滚动方向,把"自然"的对勾勾 ...

  4. 鼠标滑轮控制Div水平滚动

    <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8" ...

  5. 图片随鼠标滑轮滚动变大变小

    * 图片随鼠标滑轮滚动变大变小,最大不超过屏幕宽度-360 */ <HTML> <HEAD> <meta http-equiv="Content-Type&qu ...

  6. 鼠标滑轮一滚动Excel就停止工作

    鼠标滑轮一滚动Excel就停止工作 问题签名: 问题事件名称:APPCRASH 应用程序名:EXCEL.EXE 应用程序版本:15.0.4420.1017 应用程序时间戳:50673286 故障模块名 ...

  7. HTML 鼠标绑定滚动条,js鼠标滑轮滚动事件绑定(兼容主流浏览器)

    今天尝试写基于jquery的滚动条,遇到了滚轮事件的兼容性问题,在firefox下和在IE下以及其它浏览器下,监听的事件有区别,查了下相关资料总结一下不同浏览器下鼠标滚轮事件兼容性的处理方式: 在 f ...

  8. vue 组件封装 | s-fullpage 全屏滚动 (内含绑定鼠标滑轮滚动事件、避免鼠标滑轮连续滚动、滑动过渡动画等实用技巧)

    目录 目标 实现原理(要点) 完整代码 s-fullpage 和 s-fullpageItem s-fullpage.vue s-fullpageItem.vue 使用范例 范例效果 目标 实现类似插 ...

  9. java控制鼠标滑轮的滚动速度来滚动滚动面板和鼠标滑轮滚动事件

    //虽然比较短,但还是分享下吧....就当是个随笔吧- //设置滚动面板的滚动速度 JScrollPane.getVerticalScrollBar().setUnitIncrement(10); / ...

最新文章

  1. CIO无法忽视的三大云角色
  2. docker 常用操作
  3. Http 面试知识点
  4. CloudNative时代践行DevOps躲坑指南
  5. MYSQL-创建事件
  6. 云服务下的安全特点及基础防护
  7. cad2023三维立体图形图纸工程设计绘图软件Autodesk AutoCAD 2023 中文
  8. 莫名其妙的解决了MagicDraw中文问题
  9. 【ASO优化】产品ASO优化的流程分解
  10. 考研数学基础 之线性代数通法——Chapter6:合同对角化与二次型
  11. 超强的ChatGPT会成为下一代搜索引擎吗?
  12. moto Z2 Force Sprint版 刷魔趣8.1和root教程
  13. 认真学习jdk1.8下ConcurrentHashMap的扩容机制
  14. 三推形态,一种常用的K线形态
  15. Lemon静态链接库
  16. 网站title已经更新,百度快照未更新的解决方法
  17. ICP备案和ICP许可证的区别
  18. ViewPager循环滑动和靠按钮来控制循环滑动
  19. 高校严查学位论文复制比!降至10%!博士论文需打印40份!
  20. oracle 去当前年,Oracle获取当前年、月、日的方法

热门文章

  1. 第一单元 用python学习微积分(五) 隐函数微分法和逆函数导数(上)- 隐函数微分
  2. Vue源码流程图(函数名与源码对应)
  3. UEstudio 17打开中文乱码的处理解决
  4. python课堂教学_初中生初学python课堂教学感悟
  5. 用JS做一个简易的时间显示动态效果
  6. android 窗口圆角
  7. 口红机 抖音口红机 女神赢口红系统源码 全开源可二次开发 微信游戏,公众号游戏,口红机源码安装部署、调试...
  8. 全新圣诞节头像框制作生成微信小程序源码下载支持多模板
  9. 计算机网络练习3|河工|周老师
  10. dm服务器未能启动,DM 达梦数据库 创建服务 无法创建目录_REPLACE_SELF_DM_HOME 错误解决方法...