当前位置: 首页 > article >正文

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;
        }
    }
}

http://www.kler.cn/a/612861.html

相关文章:

  • LabVIEW时间触发协议
  • 3.1.3 MYSQL连接池
  • HarmonyOS:UI布局屏幕适配不同机型
  • Vue3.X项目中包依赖的解析与安装出现问题如何解决?
  • “头”里有什么——HTML 元信息
  • 2025年湖南建筑安全员B证备考资料
  • 数据库基础(聚合函数 分组 排序)
  • 【数据结构】C语言实现并查集:双亲指针映射与动态连通性实现详解
  • Go 语言标准库中sort模块详细功能介绍与示例
  • 【学Rust写CAD】16 零标记类型(zero.rs)
  • LogitsProcessor代码分析
  • 3.28日,NBA,欧篮联全扫盘,太阳VS森林狼
  • 小林coding-10道Java集合面试题
  • 深入理解 dispatchEvent:前端事件触发的艺术
  • DPO介绍+公式推理
  • C++中的智能指针
  • Spring Boot深度解析:从核心原理到最佳实践
  • 美颜SDK架构解析:如何高效处理人脸美型的计算任务?
  • kubernetes》》k8s》》 kubeadm、kubectl、kubelet
  • [原创](Modern C++)现代C++的关键性概念: 如何利用多维数组的指针安全地遍历所有元素