本文原创,转载请注明出处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. javascript 获取iframe元素的方法

    javascript  获取iframe元素的方法 第一种: $("#IframeID").contents().find("div"); 第二种: $(win ...

  2. Python中__call__的用法

    概念: Python中有一个有趣的语法,只要定义类型的时候,实现__call__函数,这个类型就成为可调用的.换句话说,我们可以把这个类型的对象当作函数来使用,相当于 重载了括号运算符.  示例: 所 ...

  3. VisualStudio.Net应用程序制作图标

    前段时间用到了VS自带打包工具,对程序进行打包,但是由于打包完成后,安装后的软件图标甚是难看于是想把图标也给打包进去.于是找到了两个解决方式. 第一种也是最简单的: 在VS中按照下面方式进行即可: 第 ...

  4. 洛谷P5206 [WC2019] 数树(生成函数+容斥+矩阵树)

    题面 传送门 前置芝士 矩阵树,基本容斥原理,生成函数,多项式\(\exp\) 题解 我也想哭了--orz rqy,orz shadowice 我们设\(T1,T2\)为两棵树,并定义一个权值函数\( ...

  5. java插入图片到数据库(可以批量)

    package sundun.zfpt.gg.web; import java.io.File; import java.io.FileInputStream; import java.sql.Con ...

  6. kuangbin专题十六 KMP&&扩展KMP POJ3080 Blue Jeans

    The Genographic Project is a research partnership between IBM and The National Geographic Society th ...

  7. xshell一直连接中断 守护进程

    last指令 重新登录使用last指令查看登录情况 pts的理解 who:查看目前有谁在线 pts是所谓的伪终端或虚拟终端,具体表现就是你打开一个终端,这个终端就叫pts/0,如果你再打开一个终端,这 ...

  8. java中\r ,\n,\t等的含义

    \t 相当于tab,缩进,制表符\n NewLine 换行 \f 换页符 \r 回车 \" 转义 “\\ 转义 \

  9. Go语言基础之6--值类型和引用类型

    一. 引用类型 引用类型理解为(C语言):指针 Golang中只有三种引用类型:slice(切片).map(字典).channel(管道): 实例1-1 package main import &qu ...

  10. python3 continue和break 区别

    for i in range(10): if i==5: continue #跳出当次循环 if i==8: break #跳出整个for循环 print(i)