c# - 如何为可滚动 UI(Unity)设置滚动距离限制?
问题描述
我在 Unity 中开发一个简单的可滚动 UI。
- 我在场景中有一块画布,它小时候是空的。
- Empty 是具有不同按钮的长 UI 面板的父级。
我使用以下脚本(分配给 Empty)使其可滚动:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class PageSwiper : MonoBehaviour, IDragHandler, IEndDragHandler
{
private Vector3 scrollableUILocation;
// Start is called before the first frame update
void Start()
{
scrollableUILocation = transform.position;
}
public void OnDrag(PointerEventData data)
{
float difference = data.pressPosition.x - data.position.x;
transform.position = scrollableUILocation - new Vector3(difference, 0, 0);
}
public void OnEndDrag(PointerEventData data)
{
scrollableUILocation = transform.position;
}
}
问题是我可以在屏幕外滚动 UI 面板。所以我需要让它变得不可能,或者让它如果我滚动得太远,它会顺利返回(到 UI 面板的末尾或开头,取决于哪个更近)
我该怎么做?
我尝试实施以下解决方案,但它不起作用:
我在 UI 面板的左侧和右侧添加了两个 Empty 对象。我试图让我的 UI 面板平滑地移动到其中一个空对象的位置,以防我将它移动到离它们足够近的位置。但它不起作用。
public void OnEndDrag(PointerEventData data)
{
if (Vector3.Distance(transform.position, StartPoint.transform.position) < 1.0f)
{
StartCoroutine(SmoothMove(transform.position, StartPoint.transform.position, easing));
}
else if (Vector3.Distance(transform.position, EndPoint.transform.position) < 1.0f)
{
StartCoroutine(SmoothMove(transform.position, EndPoint.transform.position, easing));
}
}
IEnumerator SmoothMove(Vector3 startpos, Vector3 endpos, float seconds)
{
float t = 0f;
while (t <= 1.0)
{
t += Time.deltaTime / seconds;
transform.position = Vector3.Lerp(startpos, endpos, Mathf.SmoothStep(0f, 1f, t));
yield return null;
}
}
解决方案
因此,您最好使用 ScrollRect,因为它已经包含此类功能所需的所有操作。
MovementType 将定义系统在到达容器末端时的反应(来自文档):
- 不受限制 内容可以永远移动。
- 弹性 允许内容暂时移出容器,但弹性拉回。
- Clamped 内容不能移动到其容器之外。
考虑到你有一个长按钮系统,也许它需要是动态的,所以你会研究 ContentSizeFitter。
您添加一个滚动视图对象。这将默认包括:
- 滚动视图
- 视口
- 内容
现在向 Content 对象添加一个 Text 组件,而不是一个文本子组件,它是一个组件。还添加一个 ContentSizeFitter 并将垂直适合设置为首选大小。这是因为我将处理垂直扩展。
确保视口占据了应该用作遮罩的空间。第一次练习时,将 ScrollView 对象放在中间,并将 Viewport 的锚点设置为 0,1,这样它就占据了整个父对象。
你可以做的还有很多,我建议看看免费的Unity UI 扩展库,因为它有一些花哨的手风琴或无尽的滚动效果。
推荐阅读
- ios - 无论如何限制AvAudioEngine的缓冲区大小?
- python - 当我将 displacy.render(doc, style="dep") 的输出保存到 svg 文件时,有一个 TypeError: write() argument must be str, not None
- ethereum - 如何修复监听智能合约事件的golang代码中的'write tcp 127.0.0.1:54917->127.0.0.1:8545: i/o timeout'错误
- c# - 如何通过 RestSharp 在 Alfresco 中上传二进制内容 octetstream?
- c - 将整个输入保存在整数数组中(使用 getchar 读取)
- php - 联系表没有内容
- java - 如何访问 signinform.jsp 中的“idpConfig”值
- python - 在组中取最大值,省略当前行的值
- sql - 按日期分组未按预期工作
- node.js - 使用 https 库在 post 请求中发送表单