当前位置: 首页 > 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.dtcms.com/a/309434.html

相关文章:

  • Java设计模式之行为型模式(解释器模式)实现方式详解
  • golang的函数
  • Hutool 的完整 JSON 工具类示例
  • 计算机(电脑)是什么?零基础硬件软件详解
  • FreeSWITCH与Java交互实战:从EslEvent解析到Spring Boot生态整合的全指南
  • WPF中使用iconfont图标
  • 【股票数据API接口02】如何获取股票最新分时交易数据之Python、Java等多种主流语言实例代码演示通过股票数据接口获取数据
  • VR 博物馆:开启文化探索新旅程
  • Python深度解析与爬虫进阶:从理论到企业级实践
  • 自建rustdesk服务器过程记录
  • 宝塔服务器挂载数据盘
  • 在vscode 如何运行a.nut 程序(Squirrel语言)
  • spring boot + mybatis + mysql 只有一个实体类的demo
  • 飞算 JavaAI 中 SQL 另存为脚本功能详解
  • 24 SAP CPI 调用SAP HTTP接口
  • nacos升级tomcat
  • 《C++初阶之STL》【stack/queue/priority_queue容器适配器:详解 + 实现】(附加:deque容器介绍)
  • Eclipse中导入新项目,右键项目没有Run on Server,Tomcat的add and remove找不到项目
  • LangChain框架入门03:PromptTemplate 提示词模板
  • YOLO---04YOLOv3
  • 如何撰写专业的面试邀请函(含模板)
  • PyTorch 应用于3D 点云数据处理汇总和点云配准示例演示
  • 一套视频快速入门并精通PostgreSQL
  • 【PHP】接入百度AI开放平台人脸识别API,实现人脸对比
  • 如何填写PDF表格的例子
  • SQL中的GROUP BY用法
  • vue3使用vue-pdf-embed实现前端PDF在线预览
  • EasyExcel 格式设置大全
  • Qt-----初识
  • Qt 跨平台应用开发经验分享