Unity 滚轮实现UGUI ScrollView的缩放
本文原创,转载请注明出处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的缩放的更多相关文章
- 在Unity中使用UGUI修改Mesh绘制几何图形
在商店看到这样一个例子,表示很有兴趣,他们说是用UGUI做的.我想,像这种可以随便变形的图形,我第一个就想到了网格变形. 做法1: 细心的朋友应该会发现,每个UGUI可见元素,都有一个‘Canvas ...
- iOS开发-ScrollView图片缩放
智能手机一般常用常用的操作触摸,滑动,缩放,感觉对于生活而言就是手机在手,天下我有,看网页的时候字体太小,缩放一下,看美女的看的不爽,缩放一下,地图看的不清,缩放一下.缩放是一个很常见的操作,不论是从 ...
- 关于Unity中的UGUI优化,你可能遇到这些问题
https://blog.uwa4d.com/archives/QA_UGUI-1.html 关于Unity中的UGUI优化,你可能遇到这些问题 作者:admin / 时间:2016年11月08日 / ...
- unity鼠标滚轮控制摄像机视野的缩放和按住鼠标控制摄像机移动
//摄像机前进后退的速率 private float view_value=20f; private float maximum = 100; private float minmum = 30; / ...
- Unity关于一个UGUI优化效率的方法
无意间发现了一个小技巧.如下图所示,可以发现UGUI的Image组件的RaycastTarget勾选以后会消耗一些效率,为了节省效率就不要勾选它了,不仅Image组件Text组件也有这样的问题. 一般 ...
- Unity NGUI和UGUI与模型、特效的层级关系
目录 1.介绍两大UI插件NGUI和UGUI 2.unity渲染顺序控制方式 3.NGUI的控制 4.UGUI的控制 5.模型深度的控制 6.粒子特效深度控制 7.NGUI与模型和粒子特效穿插层级管理 ...
- Unity 4.6 uGUI的点击事件
因为Unity 4.6刚刚发布,自带的uGUI功能的相关资料还不是很完善,今天刚装的Unity 4.6,想看一下uGUI是否好用,那么开始就今天的学习吧啊! 1,新建一个空的工程.
- Unity教程之-UGUI美术字体的制作与使用
文章转载自:http://www.unity.5helpyou.com/3211.html 游戏制作中,经常需要使用各种花哨的文字或者数字,而字体库往往不能达到我们需要的效果,因此需要一种用图片替代文 ...
- Unity琐碎(3) UGUI 图文混排解决方案和优化
感觉使用Unity之后总能看到各种各样解决混排的方案,只能说明Unity不够体恤下情啊.这篇文章主要讲一下个人在使用过程中方案选择和优化过程,已做记录.顺便提下,开源很多意味着坑,还是要开实际需求. ...
随机推荐
- 常用SQL语句及在node中使用MySQL
摘要:一些重要的SQL命令 SELECT - 从数据库中提取数据 UPDATE - 更新数据库中的数据 DELETE - 从数据库中删除数据 INSERT INTO - 向数据库中插入新数据 CREA ...
- Unity Fps示例
https://mp.weixin.qq.com/s/JGnU6TW1V0BCrz0mCRswig
- Scrapy 中 Request 对象和 Response 对象的各参数及属性介绍
Request 对象 Request构造器方法的参数列表: Request(url [, callback=None, method='GET', headers=None, body=None,co ...
- 【谁知道C#字段为什么用属性封装?】
源地址:https://zhidao.baidu.com/question/1174413218458798139.html 我们知道,类成员包括变量和方法.如果希望其他类能够访问成员变量的值,就必须 ...
- [BZOJ3337] ORZJRY I --块状链表大毒瘤
link 题目大意:维护一个序列 支持: 1.单点插入 2.单点删除 3.区间翻转 4.区间旋转 5.区间加 6.区间赋值 7.询问区间和 8.询问区间极差 9.询问区间与给定某个数差值绝对值的最小值 ...
- [转]Groovy Goodness
http://mrhaki.blogspot.com/2014/12/gradle-goodness-continue-build-even.html 介绍了不少使用Groovy编写脚本的好例子,可以 ...
- node.js 设置 淘宝 镜像
npm config set registry "https://registry.npm.taobao.org" npm info underscore (如果上面配置正确这个命 ...
- Python语言、编译解释、动态库静态库、编译过程、头文件
学习Python这门语言首先要了解 什么是编译与解释,什么是连接,什么是动态库与静态库, 什么是编译: 编译就是先把高级语言设计的程序翻译成二进制的机器语言,然后CPU直接执行机器码就可以了.一把翻译 ...
- lintcode - 删除数字
class Solution { public: /* * @param A: A positive integer which has N digits, A is a string * @para ...
- ajax加载菊花loading效果
Ajax异步请求的时候,一般都会利用一个动态的gif小图片来制作一个Ajax Loading,以便增加用户体验. 这里我们可以使用Spin.js,该js脚本压缩后5k,可以不用任何图片,任何外部CSS ...