Итак. Имеется ScrollRect, имеется карта, которая является контентом для ScrollRect.
Необходимо было сделать зум этой карты колесиком в то место, куда указывает мышь.
Настройки ScrollRect:
Horizontal/Vertical - вкл.
MovementType = Clamped
Inertia - выкл.
Scroll Sensitivity = 0;
Синтаксис:
Используется csharp
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEngine.EventSystems;
[RequireComponent(typeof(ScrollRect))]
public class ResizeOnMouseWheel : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
[SerializeField] private float startSize = 1f;
[SerializeField] private float minSize = 1f;
[SerializeField] private float maxSize = 2f;
[SerializeField] private float smooth = 5f;
[SerializeField] private float zoomStep = 1f;
private ScrollRect scrollRect;
private RectTransform thisRectTransform;
private bool onObj = false;
private float prevScale;
private float targetScale = 1f;
private Vector2 newCenter = Vector2.zero;
void Start()
{
scrollRect = GetComponent<ScrollRect>();
thisRectTransform = GetComponent<RectTransform>();
targetScale *= startSize;
}
void Update()
{
float scrollWheel = Input.GetAxis("Mouse ScrollWheel"); // Обычно при кручении колесика вперед scrollWheel = 0.1
if (onObj && scrollWheel != 0f)
{
targetScale += zoomStep*scrollWheel;
targetScale = Mathf.Clamp(targetScale, minSize, maxSize);
RectTransformUtility.ScreenPointToLocalPointInRectangle(scrollRect.content, Input.mousePosition, Camera.main, out newCenter);
prevScale = scrollRect.content.localScale.x;
}
if(Mathf.Abs(scrollRect.content.localScale.x - targetScale) > 0.001)
{
scrollRect.content.localScale = Vector3.Lerp(scrollRect.content.localScale, new Vector3(targetScale, targetScale, 1f), smooth*Time.deltaTime);
scrollRect.content.anchoredPosition = Vector2.Lerp(scrollRect.content.anchoredPosition, -1f * newCenter * scrollRect.content.localScale.x, smooth * Time.deltaTime);
var xDelta = scrollRect.content.rect.width/2 * scrollRect.content.localScale.x - thisRectTransform.rect.width/2;
var yDelta = scrollRect.content.rect.height/2 * scrollRect.content.localScale.y - thisRectTransform.rect.height/2;
scrollRect.content.anchoredPosition = new Vector2(
Mathf.Clamp(scrollRect.content.anchoredPosition.x, -xDelta, xDelta),
Mathf.Clamp(scrollRect.content.anchoredPosition.y, -yDelta, yDelta));
}
}
public void OnPointerEnter(PointerEventData eventData)
{
onObj = true;
}
public void OnPointerExit(PointerEventData eventData)
{
onObj = false;
}
void OnDisable()
{
onObj = false;
}
}
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEngine.EventSystems;
[RequireComponent(typeof(ScrollRect))]
public class ResizeOnMouseWheel : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
[SerializeField] private float startSize = 1f;
[SerializeField] private float minSize = 1f;
[SerializeField] private float maxSize = 2f;
[SerializeField] private float smooth = 5f;
[SerializeField] private float zoomStep = 1f;
private ScrollRect scrollRect;
private RectTransform thisRectTransform;
private bool onObj = false;
private float prevScale;
private float targetScale = 1f;
private Vector2 newCenter = Vector2.zero;
void Start()
{
scrollRect = GetComponent<ScrollRect>();
thisRectTransform = GetComponent<RectTransform>();
targetScale *= startSize;
}
void Update()
{
float scrollWheel = Input.GetAxis("Mouse ScrollWheel"); // Обычно при кручении колесика вперед scrollWheel = 0.1
if (onObj && scrollWheel != 0f)
{
targetScale += zoomStep*scrollWheel;
targetScale = Mathf.Clamp(targetScale, minSize, maxSize);
RectTransformUtility.ScreenPointToLocalPointInRectangle(scrollRect.content, Input.mousePosition, Camera.main, out newCenter);
prevScale = scrollRect.content.localScale.x;
}
if(Mathf.Abs(scrollRect.content.localScale.x - targetScale) > 0.001)
{
scrollRect.content.localScale = Vector3.Lerp(scrollRect.content.localScale, new Vector3(targetScale, targetScale, 1f), smooth*Time.deltaTime);
scrollRect.content.anchoredPosition = Vector2.Lerp(scrollRect.content.anchoredPosition, -1f * newCenter * scrollRect.content.localScale.x, smooth * Time.deltaTime);
var xDelta = scrollRect.content.rect.width/2 * scrollRect.content.localScale.x - thisRectTransform.rect.width/2;
var yDelta = scrollRect.content.rect.height/2 * scrollRect.content.localScale.y - thisRectTransform.rect.height/2;
scrollRect.content.anchoredPosition = new Vector2(
Mathf.Clamp(scrollRect.content.anchoredPosition.x, -xDelta, xDelta),
Mathf.Clamp(scrollRect.content.anchoredPosition.y, -yDelta, yDelta));
}
}
public void OnPointerEnter(PointerEventData eventData)
{
onObj = true;
}
public void OnPointerExit(PointerEventData eventData)
{
onObj = false;
}
void OnDisable()
{
onObj = false;
}
}