Unity动态锚点缩放UI实现方案
创作时间:
作者:
@小白创作中心
Unity动态锚点缩放UI实现方案
引用
CSDN
1.
https://blog.csdn.net/weixin_41741510/article/details/144563180
在Unity UGUI开发中,传统的UI元素缩放方式通常以中心点为基准,这在某些场景下可能不够直观。本文将介绍一种以鼠标位置为基准点的动态锚点缩放方案,让缩放效果更加自然和符合用户预期。
一、效果演示(结尾附工程下载地址)
二、制作过程
简言
该功能主要包含三个核心部分:
- 动态修改Pivot(锚点)位置
- 缩放功能实现
- 拖拽功能实现
一、创建一个Image作为背景,并添加Mask组件作为遮罩(防止缩放的图片不会超出此Image的可见范围)
二、创建需要进行缩放和平移的Image,作为背景的子物体并挂载下面完整代码的脚本。
三、完整代码
using UnityEngine;
using UnityEngine.EventSystems;
public class MapScrollerActivePivot : MonoBehaviour, IBeginDragHandler, IDragHandler, IPointerEnterHandler, IPointerExitHandler
{
private Vector3 lastMousePosition;
private RectTransform rectTransform;
bool isHover;
private void Start()
{
rectTransform = GetComponent<RectTransform>();
}
private void Update()
{
if (isHover)
{
SetPivotWithMousePos(rectTransform);
Scale(Input.GetAxis("Mouse ScrollWheel") * 2f);
}
}
public void Scale(float scaleMultiplier, float minScale = -1)
{
if (scaleMultiplier == 0)
{
return;
}
var scale = transform.localScale;
scale *= 1 + scaleMultiplier;
if (minScale != -1 && scale.x < minScale)
{
scale = Vector3.one * minScale;
}
transform.localScale = scale;
}
public void OnBeginDrag(PointerEventData eventData)
{
lastMousePosition = Input.mousePosition;
}
public void OnDrag(PointerEventData eventData)
{
Vector3 delta = Input.mousePosition - lastMousePosition;
Vector3 newPosition = transform.position + delta;
transform.position = newPosition;
lastMousePosition = Input.mousePosition;
}
/// <summary>
/// 设置UI元素的pivot,不改变位置
/// </summary>
/// <param name="rectTransform">需要设置pivot的RectTransform </param>
public void SetPivotWithMousePos(RectTransform rectTransform)
{
Vector3 point = rectTransform.position;
Vector3 sizeDelta = rectTransform.sizeDelta;
Vector3 pivot = rectTransform.pivot;
Vector3 mouseLocalPoint = rectTransform.InverseTransformPoint(Input.mousePosition);
// 计算新的 pivot
float x = (mouseLocalPoint.x + (pivot.x * sizeDelta.x)) / sizeDelta.x;
float y = (mouseLocalPoint.y + (pivot.y * sizeDelta.y)) / sizeDelta.y;
// 设置新的 pivot
rectTransform.pivot = new Vector2(x, y);
// 计算新的 position
point.x += (x - pivot.x) * rectTransform.localScale.x * sizeDelta.x;
point.y += (y - pivot.y) * rectTransform.localScale.y * sizeDelta.y;
// 检查新位置是否有效
if (!float.IsNaN(point.x) && !float.IsNaN(point.y) && !float.IsNaN(point.z))
{
rectTransform.position = point;
}
else
{
Debug.Log("计算的新位置无效: " + point);
}
}
public void OnPointerEnter(PointerEventData eventData)
{
isHover = true;
}
public void OnPointerExit(PointerEventData eventData)
{
isHover = false;
}
}
四、总结
技术要点总结:
- 动态Pivot计算:通过InverseTransformPoint将鼠标世界坐标转换为UI元素本地坐标,实现精确的锚点计算。
- 位置补偿:修改Pivot会导致UI元素位置变化,需要通过计算偏移量来保持位置不变。
- 缩放控制:支持最小缩放限制,防止过度缩小导致的问题。
- 拖拽实现:使用EventSystem的拖拽接口,确保拖拽操作的准确性。
工程下载地址:
点击下载工程—蓝奏云
https://wwya.lanzoue.com/izPrL2j3jp7g
热门推荐
真诚待人:建立深厚人际关系的基石
探讨上海国际物流园区的现代化发展路径
麻粩:传统美食的制作工艺与文化内涵
NEJM:食物即良药!探索蛋白质、脂肪、碳水、膳食纤维“最佳”饮食方案
诡楼回魂海龟汤攻略 诡楼回魂第二章海龟汤流程
哪种水果维生素C含量最高?这场水果界的维C大比拼结果令人惊喜
胃胀气吃什么药比较有效
部队如何带团队工作
骑车对身材的神奇改变:减肥与匀称
手风琴入门难吗?揭秘学习手风琴的秘诀
深入了解显卡性能测试工具:关键工具、性能指标与测试方法
空气净化器对TVOC有用吗?针对TVOC,该如何选购空气净化器
DEI 推动数字化转型成功的四种方式
痛风不能吃海鲜?医生:真正需要忌口的4种食物,需特别留意
邹家华:邹韬奋的儿子,叶剑英元帅的女婿,今年96岁,身体康健
父母的高度,才是孩子的起跑线
继父与继子的抚养义务是怎么规定的
庐山植物园里的雷击木:一棵99岁柳杉的惊蛰劫难
奈克瑟斯奥特曼20周年纪念
安阳旅游景点大全:千年古都的魅力之旅
中国第一大沙漠下暴雨了!铁路人这样应对
C语言代码合法性判断:从语法到编译器检查的全面解析
买到假货怎么办?一文详解假冒伪劣产品举报流程
刘晓庆:永不设限的精神传奇,超绝的精神状态
公司管理如何和客户沟通
厦门春季赏花全攻略:十大花卉打卡地,尽享“海上花园”春日浪漫
易经学习:中老年人的精神滋养与智慧提升
社交媒体成瘾,我们如何应对这一现象?
柳叶刀子刊:中国饮食升糖指数最高,增加糖尿病风险
无锡马拉松直通成绩提升,这是中国马拉松提速的信号