本文原创,转载请注明出处http://www.cnblogs.com/AdvancePikachu/p/7908754.html

前段时间在做一个类似AnimationCurve的可视化编辑器,其中在做内部缩放的时候略有所感,把利用滚轮+焦点的缩放分享一下。

其中一个脚本处理内部逻辑

public class ResizeScrollEvent : UnityEvent<float> { }

public class UIScroll : MonoBehaviour, IScrollHandler
{
public float minFactor = 1;
public float maxFactor = 3;
public bool wholeSizeFactor = true; private ResizeScrollEvent _onResize = new ResizeScrollEvent();
private float _sizeFactor = 1f; public ResizeScrollEvent OnResize { get { return _onResize; } }
public float SizeFactor
{
get
{
if (wholeSizeFactor)
return Mathf.Round(_sizeFactor);
return _sizeFactor;
}
set
{
SetFactor(value);
}
} [SerializeField]
RectTransform content;
[SerializeField]
RectTransform viewport; Rect _rect;
Vector2 _focusPos; void Start()
{
_rect = GetWorldRect(viewport);
_focusPos = _rect.center;
} public static Rect GetWorldRect(RectTransform rt)
{
Vector3[] cors_ = new Vector3[4];
rt.GetWorldCorners(cors_);
Vector2 center = cors_[0];
float width = Mathf.Abs(cors_[0].x - cors_[2].x);
float height = Mathf.Abs(cors_[0].y - cors_[2].y);
Rect rect_ = new Rect(center.x, center.y, width, height);
return rect_;
} private void SetFactor(float value)
{
value = ClampFactorValue(value); if (value != _sizeFactor)
{
_sizeFactor = value;
ChangeSizeFactor(_sizeFactor);
_onResize.Invoke(_sizeFactor);
}
} private void ChangeSizeFactor(float v)
{
     Vector2 viewportSize_ = _rect.size; //缩放过程中的焦点位置(此处为中心位置)
//_focusPos = _rect.center; Rect contentRect_ = GetWorldRect(content);
Vector2 contentSize_ = contentRect_.size;
Vector2 contentCenter_ = contentRect_.center; Vector2 contentCenter2ViewportCenter_ = _focusPos - contentCenter_;
float centerPosPercentX_ = contentCenter2ViewportCenter_.x / contentSize_.x;
float centerPosPercentY_ = contentCenter2ViewportCenter_.y / contentSize_.y; Vector2 scorllSize_ = viewportSize_ + (v - 1) * viewportSize_ / 5;
content.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scorllSize_.x);
content.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, scorllSize_.y); Vector2 sizeDelta_ = scorllSize_ - contentSize_;
Vector2 posOffset_ = new Vector2(sizeDelta_.x * -centerPosPercentX_, sizeDelta_.y * -centerPosPercentY_);
content.anchoredPosition += posOffset_; Vector3[] viewCorner_ = new Vector3[4];
Vector3[] contentCorner_ = new Vector3[4];
viewport.GetWorldCorners(viewCorner_);
content.GetWorldCorners(contentCorner_); float xFixDelta_ = 0;
float yFixDelta_ = 0; if (viewCorner_[0].x < contentCorner_[0].x) xFixDelta_ = viewCorner_[0].x - contentCorner_[0].x;
if (viewCorner_[0].y < contentCorner_[0].y) yFixDelta_ = viewCorner_[0].y - contentCorner_[0].y;
if (viewCorner_[2].x > contentCorner_[2].x) xFixDelta_ = viewCorner_[2].x - contentCorner_[2].x;
if (viewCorner_[2].y > contentCorner_[2].y) yFixDelta_ = viewCorner_[2].y - contentCorner_[2].y; content.anchoredPosition += new Vector2(xFixDelta_, yFixDelta_);
} private float ClampFactorValue(float value)
{
float factor_ = Mathf.Clamp(value, minFactor, maxFactor); if (wholeSizeFactor) factor_ = Mathf.Round(factor_); return factor_;
} public void OnScroll(PointerEventData eventData)
{
if (!isActiveAndEnabled) return;
        _focusPos = eventData.position;//焦点为鼠标所在位置
float delta_ = 0;
if (Mathf.Abs(eventData.scrollDelta.x) > Mathf.Abs(eventData.scrollDelta.y))
delta_ = eventData.scrollDelta.x;
else delta_ = eventData.scrollDelta.y; SetFactor(_sizeFactor + delta_);
}
}

  另一个脚本做触发

public class NewBehaviourScript : MonoBehaviour
{
[SerializeField]
Slider scaleSlider;
[SerializeField]
Text sliderValue;
[SerializeField]
UIScroll scrollView; void Start ()
{
scaleSlider.wholeNumbers = true;
scaleSlider.minValue = 1;
scaleSlider.maxValue = 10;
scaleSlider.onValueChanged.AddListener(OnSliderValueChange); scrollView.minFactor = scaleSlider.minValue;
scrollView.maxFactor = scaleSlider.maxValue;
scrollView.wholeSizeFactor = true;
scrollView.OnResize.AddListener(OnScrollResized);
scrollView.SizeFactor = 1;
} private void OnScrollResized(float value)
{
scaleSlider.value = value;
} private void OnSliderValueChange(float value)
{
scrollView.SizeFactor = value;
sliderValue.text = value.ToString();
}
}

 

PS:刚开始以为是版本问题,后来发现是我的Cavans设置有问题,修改后问题解决!

附5.6.4f1项目文件https://files.cnblogs.com/files/AdvancePikachu/scroll.rar

Unity 滚轮实现UGUI ScrollView的缩放的更多相关文章

  1. 在Unity中使用UGUI修改Mesh绘制几何图形

    在商店看到这样一个例子,表示很有兴趣,他们说是用UGUI做的.我想,像这种可以随便变形的图形,我第一个就想到了网格变形. 做法1: 细心的朋友应该会发现,每个UGUI可见元素,都有一个‘Canvas ...

  2. iOS开发-ScrollView图片缩放

    智能手机一般常用常用的操作触摸,滑动,缩放,感觉对于生活而言就是手机在手,天下我有,看网页的时候字体太小,缩放一下,看美女的看的不爽,缩放一下,地图看的不清,缩放一下.缩放是一个很常见的操作,不论是从 ...

  3. 关于Unity中的UGUI优化,你可能遇到这些问题

    https://blog.uwa4d.com/archives/QA_UGUI-1.html 关于Unity中的UGUI优化,你可能遇到这些问题 作者:admin / 时间:2016年11月08日 / ...

  4. unity鼠标滚轮控制摄像机视野的缩放和按住鼠标控制摄像机移动

    //摄像机前进后退的速率 private float view_value=20f; private float maximum = 100; private float minmum = 30; / ...

  5. Unity关于一个UGUI优化效率的方法

    无意间发现了一个小技巧.如下图所示,可以发现UGUI的Image组件的RaycastTarget勾选以后会消耗一些效率,为了节省效率就不要勾选它了,不仅Image组件Text组件也有这样的问题. 一般 ...

  6. Unity NGUI和UGUI与模型、特效的层级关系

    目录 1.介绍两大UI插件NGUI和UGUI 2.unity渲染顺序控制方式 3.NGUI的控制 4.UGUI的控制 5.模型深度的控制 6.粒子特效深度控制 7.NGUI与模型和粒子特效穿插层级管理 ...

  7. Unity 4.6 uGUI的点击事件

    因为Unity 4.6刚刚发布,自带的uGUI功能的相关资料还不是很完善,今天刚装的Unity 4.6,想看一下uGUI是否好用,那么开始就今天的学习吧啊! 1,新建一个空的工程.

  8. Unity教程之-UGUI美术字体的制作与使用

    文章转载自:http://www.unity.5helpyou.com/3211.html 游戏制作中,经常需要使用各种花哨的文字或者数字,而字体库往往不能达到我们需要的效果,因此需要一种用图片替代文 ...

  9. Unity琐碎(3) UGUI 图文混排解决方案和优化

    感觉使用Unity之后总能看到各种各样解决混排的方案,只能说明Unity不够体恤下情啊.这篇文章主要讲一下个人在使用过程中方案选择和优化过程,已做记录.顺便提下,开源很多意味着坑,还是要开实际需求. ...

随机推荐

  1. clojure.spec库入门学习

    此文已由作者张佃鹏授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. clojure是一门动态类型的语言,在类型检查方面并没有c++/java这种静态类型语言好用,所以多个模块之 ...

  2. 智能合约安全事故回顾(3)-DOS漏洞导致的KotET事件

    现实世界中的网络都是有带宽限制的,想象一下,一个访问量稳定的网站,突然有人利用某种方式爆发式的将网站的访问量提升,这个时候系统会作何反应?如果系统没有合理的防DOS攻击的方式,这种时候往往会造成服务器 ...

  3. P2617 Dynamic Rankings 动态主席树

    \(\color{#0066ff}{ 题目描述 }\) 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i ...

  4. 当我们谈论CloudTable时究竟在谈论什么?

    表格存储服务(CloudTable Service,简称CloudTable)是基于Apache HBase提供的分布式.可伸缩.全托管的毫秒级NoSQL数据存储服务.它提供了毫秒级的随机读写能力,适 ...

  5. 灾后重建 Floyd

    题目背景 BBB地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重建完成的村庄的公路 ...

  6. Blocks poj 区间dp

    Some of you may have played a game called 'Blocks'. There are n blocks in a row, each box has a colo ...

  7. Liunx 发送邮件

    可以使用rpm -qa | grep mailx查看系统自带的mailx版本. 使用wget http://sourceforge.net/projects/heirloom/files/latest ...

  8. git学习---去除版本控制

    本地这样去除文件夹 node_modules 的版本关联:执行:git rm -r --cached "node_modules/"提交: git commit -am 'remo ...

  9. P3970 [TJOI2014]上升子序列

    传送门 DP 十分显然的DP,但是不好写 设 f[ i ] 表示以第 i 个数作结尾时的方案数,原序列为 a 如果不考虑相同的序列: 那么转移就是 Σ f[ j ] (0< j < i & ...

  10. 多线程DP (要一起行动才可以)

    题目描述 Description 设有N*N的方格图(N<=10,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0.如下图所示(见样例): 某人从图的左上角的A 点出发,可以向下行走 ...