unity实现图片查看器有限制的移动缩放功能
需求
unity实现键盘wasd键控制图片的移动,图片长度未超出屏幕不能移动,宽度未超出屏幕不能移动。jk键控制图片的缩放,缩放有限制
using UnityEngine;
public class ImageController : MonoBehaviour
{
[Header("移动设置")]
public float moveSpeed = 5f; // 移动速度
private RectTransform rectTransform;
private Vector2 originalSize; // 原始尺寸
private Vector2 minPosition; // 最小位置限制
private Vector2 maxPosition; // 最大位置限制
[Header("缩放设置")]
public float scaleSpeed = 0.1f; // 缩放速度
public float minScale = 0.5f; // 最小缩放比例
public float maxScale = 2f; // 最大缩放比例
private Vector3 currentScale; // 当前缩放值
private void Start()
{
rectTransform = GetComponent<RectTransform>();
originalSize = rectTransform.sizeDelta;
currentScale = rectTransform.localScale;
// 计算初始位置限制
CalculatePositionLimits();
}
private void Update()
{
HandleMovement();
HandleScaling();
}
private void HandleMovement()
{
Vector2 moveInput = Vector2.zero;
// 获取WASD输入
if (Input.GetKey(KeyCode.W)) moveInput.y = 1f;
if (Input.GetKey(KeyCode.S)) moveInput.y = -1f;
if (Input.GetKey(KeyCode.A)) moveInput.x = -1f;
if (Input.GetKey(KeyCode.D)) moveInput.x = 1f;
// 归一化并应用速度
if (moveInput.magnitude > 0)
{
moveInput.Normalize();
Vector2 newPosition = rectTransform.anchoredPosition + moveInput * moveSpeed * Time.deltaTime;
// 应用位置限制
newPosition.x = Mathf.Clamp(newPosition.x, minPosition.x, maxPosition.x);
newPosition.y = Mathf.Clamp(newPosition.y, minPosition.y, maxPosition.y);
rectTransform.anchoredPosition = newPosition;
}
}
private void HandleScaling()
{
float scaleInput = 0f;
// 获取JK输入
if (Input.GetKey(KeyCode.J)) scaleInput = -1f;
if (Input.GetKey(KeyCode.K)) scaleInput = 1f;
if (scaleInput != 0f)
{
// 计算新缩放值
float newScale = currentScale.x + scaleInput * scaleSpeed * Time.deltaTime;
newScale = Mathf.Clamp(newScale, minScale, maxScale);
currentScale = new Vector3(newScale, newScale, 1f);
rectTransform.localScale = currentScale;
// 缩放后重新计算位置限制
CalculatePositionLimits();
// 确保缩放后图片不会超出边界
Vector2 clampedPosition = rectTransform.anchoredPosition;
clampedPosition.x = Mathf.Clamp(clampedPosition.x, minPosition.x, maxPosition.x);
clampedPosition.y = Mathf.Clamp(clampedPosition.y, minPosition.y, maxPosition.y);
rectTransform.anchoredPosition = clampedPosition;
}
}
private void CalculatePositionLimits()
{
// 获取Canvas的尺寸
RectTransform canvasRect = GetComponentInParent<Canvas>().GetComponent<RectTransform>();
Vector2 canvasSize = canvasRect.sizeDelta;
// 计算当前图片的实际尺寸(考虑缩放)
Vector2 scaledSize = new Vector2(
originalSize.x * currentScale.x,
originalSize.y * currentScale.y
);
// 计算位置限制
// 当图片尺寸小于等于屏幕尺寸时,不能移动
if (scaledSize.x <= canvasSize.x)
{
minPosition.x = 0;
maxPosition.x = 0;
}
else
{
float halfImageWidth = scaledSize.x / 2f;
float halfCanvasWidth = canvasSize.x / 2f;
minPosition.x = halfCanvasWidth - halfImageWidth;
maxPosition.x = halfImageWidth - halfCanvasWidth;
}
if (scaledSize.y <= canvasSize.y)
{
minPosition.y = 0;
maxPosition.y = 0;
}
else
{
float halfImageHeight = scaledSize.y / 2f;
float halfCanvasHeight = canvasSize.y / 2f;
minPosition.y = halfCanvasHeight - halfImageHeight;
maxPosition.y = halfImageHeight - halfCanvasHeight;
}
}
}