本文原创,转载请注明出处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. 使用box-shadow 实现水波、音波的效果

    用到的工具 animation box-shadow html: <div class="watersource"> </div> css: .waters ...

  2. 完美解决:"library not found for - "

    分析原因,解决问题 在Xcode编译的时候,可能会遇到报这个错误"library not found for - ",这是为什么呢? 由于我们在项目中使用了一些第三方的库,如百度的静态库.当Xcode ...

  3. Mybatis学习笔记(六) —— 动态sql

    通过mybatis提供的各种标签方法实现动态拼接sql. 需求:根据性别和名字查询用户 查询sql: SELECT id, username, birthday, sex, address FROM ...

  4. redis常用数据类型与命令

    注意:LPUSH 和LPOP按照栈进行操作,RPUSH和RPOP按照队列进行操作 zremrangebyscore key score开始  score结束//根据score删除 zremrangeb ...

  5. window 系统 修改服务器远程登录端口

    window 系统 [ 默认3389远程端口 ] 快捷键:Ctrl+R  然后输入“regedit”,打开注册表 或者 单击左下角[开始]——[运行],然后在输入框输入 regedit,点击确定,打开 ...

  6. C语言中typedef的解释_2

    typedef工具是一个高级数据特性.利用typedef可以为某一类型自定义一个新的名称.这样可以提高程序的可读性,可移植性,向用户表明特定用途. typedef没有创建任何新的类型,它只是为某个已存 ...

  7. Educational Codeforces Round 3 C

    C. Load Balancing time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  8. 关于form组件的补充-------formChoice

    form组件的Choice字段 还是基于出版社和书的模型来详解 models.py(模型) from django.db import models # Create your models here ...

  9. Go语言基础之14--Waitgroup和原子操作

    一.Waitgroup介绍 1.1 背景 package main import ( "fmt" "time" ) func main() { ch := ma ...

  10. CPU的CAS操作

    https://blog.csdn.net/qq_35492857/article/details/78471032 https://www.cnblogs.com/gdjdsjh/p/5076815 ...