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

⭐ Unity 实现UI视差滚动效果(Parallax)鼠标控制、可拓展陀螺仪与脚本控制

✨ 效果如下

在许多游戏、APP 或动效页面中,我们常见的一种视觉效果是 视差滚动(Parallax Scrolling):前景、中景、背景在鼠标或设备移动时以不同速率轻微移动,从而营造出一种空间感和深度感。

目前遇到这样一个需求 所以在 Unity 中实现一个支持鼠标控制、陀螺仪控制和脚本控制的 UI 视差脚本,并提供完整源码、注释及使用方法,适合用于启动页、主菜单、信息卡片界面等多种场景。


🧠 实现原理

核心思想是:

  • 每个 UI 图层记录起始位置;

  • 根据输入设备(鼠标或陀螺仪),获取目标参考位置(通常是屏幕坐标归一化到 [0,1]);

  • Lerp 缓动插值方式移动 UI 图层,使其偏移方向和输入方向一致;

  • 每个图层的移动速度和最大移动范围可以独立配置。


📦 脚本结构概述

我们将视差系统封装为一个 MonoBehaviour 脚本,名为 MMParallaxUI,结构清晰、易于扩展:

名称说明
ParallaxLayer子类,表示每一层的参数设置(RectTransform、速度、幅度、是否启用等)
Modes视差控制模式(鼠标 / 陀螺仪 / 脚本)
ParallaxLayers图层列表,可在 Inspector 中直接配置
AmplitudeMultiplier所有图层的幅度乘数
SpeedMultiplier所有图层的速度乘数


🧩 完整源码(含中文注释)

using System;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// 用于实现UI视差滚动效果的组件(Parallax)
/// 支持鼠标控制、陀螺仪控制(移动端)、或通过代码控制
/// </summary>
public class MMParallaxUI : MonoBehaviour
{/// <summary>/// 用于存储每个视差图层的设置/// </summary>[Serializable]public class ParallaxLayer{[Tooltip("该图层的 RectTransform 组件")]public RectTransform Rect;[Tooltip("该图层移动的速度")]public float Speed = 2f;[Tooltip("该图层相对初始位置最大移动距离(幅度)")]public float Amplitude = 50f;[HideInInspector]public Vector2 StartPosition;  // 图层的初始位置(运行时记录)[Tooltip("是否启用该图层的视差效果")]public bool Active = true;}/// <summary>/// 控制视差输入的模式类型/// </summary>public enum Modes{Mouse,      // 使用鼠标位置控制(适用于PC)Gyroscope,  // 使用陀螺仪控制(适用于移动设备)Script      // 外部脚本通过 SetReferencePosition 控制}[Header("基础设置")][Tooltip("当前使用的控制模式")]public Modes Mode = Modes.Mouse;[Tooltip("控制所有图层振幅的倍率")]public float AmplitudeMultiplier = 1f;[Tooltip("控制所有图层速度的倍率")]public float SpeedMultiplier = 1f;[Tooltip("参与视差移动的图层列表")]public List<ParallaxLayer> ParallaxLayers;// 内部变量protected Vector2 _referencePosition;   // 当前输入参考位置(归一化)protected Vector3 _newPosition;         // 图层的新位置protected Vector2 _mousePosition;       // 鼠标当前位置(屏幕坐标)/// <summary>/// Start 时初始化所有图层的起始位置/// </summary>protected virtual void Start(){Initialization();}/// <summary>/// 初始化:记录每个图层的起始位置/// </summary>public virtual void Initialization(){foreach (ParallaxLayer layer in ParallaxLayers){if (layer.Rect != null){layer.StartPosition = layer.Rect.position;}}}/// <summary>/// 每帧更新:移动所有图层/// </summary>protected virtual void Update(){MoveLayers();}/// <summary>/// 根据控制模式更新 _referencePosition 并移动图层/// </summary>protected virtual void MoveLayers(){// 根据控制模式获取输入switch (Mode){case Modes.Gyroscope:// 示例:你可以接入 Input.gyro.rotationRate 或 attitude(仅限移动设备)// _referencePosition = new Vector2(Input.gyro.rotationRate.x, Input.gyro.rotationRate.y);break;case Modes.Mouse:
#if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER_mousePosition = UnityEngine.InputSystem.Mouse.current.position.ReadValue(); // 新输入系统
#else_mousePosition = Input.mousePosition; // 旧输入系统
#endif// 将鼠标屏幕坐标转为归一化视口坐标(0~1)_referencePosition = Camera.main.ScreenToViewportPoint(_mousePosition);break;case Modes.Script:// 由外部通过 SetReferencePosition() 设置break;}// 遍历每个图层并移动位置foreach (ParallaxLayer layer in ParallaxLayers){if (layer.Active && layer.Rect != null){// X轴移动(缓动)_newPosition.x = Mathf.Lerp(layer.Rect.position.x,layer.StartPosition.x + _referencePosition.x * layer.Amplitude * AmplitudeMultiplier,layer.Speed * SpeedMultiplier * Time.deltaTime);// Y轴移动(缓动)_newPosition.y = Mathf.Lerp(layer.Rect.position.y,layer.StartPosition.y + _referencePosition.y * layer.Amplitude * AmplitudeMultiplier,layer.Speed * SpeedMultiplier * Time.deltaTime);_newPosition.z = 0f;// 更新图层位置layer.Rect.position = _newPosition;}}}/// <summary>/// 设置一个新的输入参考位置(仅在 Script 模式下使用)/// 值通常在 (0,0) 到 (1,1) 之间/// </summary>public virtual void SetReferencePosition(Vector3 newReferencePosition){_referencePosition = newReferencePosition;}
}


🛠️ 使用方法

1️⃣ 添加组件

  1. 在 Canvas 下创建一个空 GameObject,命名为 UIParallaxRoot

  2. 挂载 MMParallaxUI 脚本。

  3. 在 Inspector 中配置 ParallaxLayers 列表,添加你希望参与视差效果的图层(Image/Text 等 UI 元素)。

  4. 配置每层的 SpeedAmplitude

2️⃣ 设置控制模式

  • Mouse(默认):使用鼠标位置控制(适用于PC)。

  • Gyroscope:适用于移动端,可扩展为接入 Input.gyro

  • Script:通过代码调用 SetReferencePosition() 控制。

// 示例:手动控制参考位置
parallaxUI.SetReferencePosition(new Vector2(0.5f, 0.5f)); // 回中


🎮 目前我使用的阈值如下

👇 均为透明png实现
按我这个阈值去配置  可以得到首图的效果


这个脚本目前直接挂载使用即可,陀螺仪方面还未拖拽完毕,也可以增加“自动回中”逻辑,在鼠标或输入松开后回归中心位置。如需图片素材做参考,或者你有新的思路和实现方式 可以私信我或在评论区留言。

http://www.lryc.cn/news/606918.html

相关文章:

  • linux81 shell通配符:[list],‘‘ ``““
  • React Refs:直接操作DOM的终极指南
  • flutter——ColorScheme
  • DM8达梦数据库错误码信息汇编-8.1.4.80 20250430-272000-20149 Pack1
  • 【3】交互式图表制作及应用方法
  • 38译码器工作原理
  • 肖特基二极管MBR0540T1G 安森美ON 低电压 高频率 集成电路IC 芯片
  • 三十九、【扩展工具篇】Allpairspy 组合用例生成器:智能设计高效测试集
  • 德国威乐集团亚太中东非洲PMO负责人和继明受邀为PMO大会主持人
  • 【AMD | Docker】超级全面版本:在Docker中验证AMD GPU移动显卡可用性的方法
  • n8n】n8n的基础概念
  • 海外商城 app 系统架构分析
  • CMake Debug/Release配置生成器表达式解析
  • Kafka Streams 并行处理机制深度解析:任务(Task)与流线程(Stream Threads)的协同设计
  • 调试 Rust 生成的 WebAssembly
  • 阻塞队列特性
  • K-Means聚类:当数据没有标签时,如何让计算机自动“物以类聚”?
  • 字符串的高效处理String‘Builder类(高频率的字符串拼接)
  • 每日面试题18:基本数据类型和引用数据类型的区别
  • 转换图(State Transition Diagram)和时序图(Sequence Diagram)画图流程图工具
  • PHP在现代Web开发中的应用与优势分析
  • 汽车EDI:Vitesco EDI 项目案例
  • 在Centos7中安装gitlab
  • flutter-boilerplate-project 学习笔记
  • gitlab+jenkins的ci/cd部署
  • 《R for Data Science (2e)》免费中文翻译 (第3章) --- Data transformation(1)
  • ceph 14.2.22 nautilus Balancer 数据平衡
  • gitlab 开发人员无法创建分支,管理员配置分支权限
  • 「一键召唤 007」:开源多智能体 JoyAgent-JDGenie 如何让你的 AI 产品从 Demo 到 真香 只差 Ctrl+C / Ctrl+V?
  • Linux 内存管理之 Rmap 反向映射