Unity UI 道路线跟随:让图标沿道路轨迹移动

server/2025/2/19 8:35:58/

在 Unity UI 开发中,有时需要让图标沿着一条道路轨迹移动,比如地图上的车辆行驶动画导航路径指示等。本文介绍如何基于 UI 图片中的道路线生成曲线,并使用 Slider 控制图标沿轨迹运动,适用于 UI 导航、路径跟随动画等场景


1. 功能介绍

  • 基于 UI 图片自动解析道路轨迹,生成 AnimationCurve
  • 使用 Slider 控制图标沿道路移动
  • 适用于 UI 地图、导航路径动画等

最终效果👇

2. 代码实现

2.1 解析道路轨迹,生成曲线路径

思路:

  • 读取 UI 图片 (Image) 的 Sprite,获取 Texture2D
  • 遍历像素点,找到道路轨迹的像素
  • 转换为 UI 坐标,存入 AnimationCurve,用于后续运动计算
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using Sirenix.OdinInspector;public class PathGenerator : MonoBehaviour
{public Image roadImage; // 道路线 UI 图片public AnimationCurve pathCurve = new AnimationCurve(); // 道路路径曲线[Button("Generate Path")]public void GeneratePath(){if (roadImage == null || roadImage.sprite == null){Debug.LogError("Road Image or Sprite is not assigned.");return;}Sprite sprite = roadImage.sprite;Texture2D texture = sprite.texture;Rect rect = sprite.rect;List<Vector2> points = new List<Vector2>();// 计算缩放比例RectTransform rectTransform = roadImage.rectTransform;float scaleX = rectTransform.rect.width / rect.width;float scaleY = rectTransform.rect.height / rect.height;// 提取道路轨迹上的点for (int x = 0; x < rect.width; x++){for (int y = 0; y < rect.height; y++){Color pixel = texture.GetPixel((int)rect.x + x, (int)rect.y + y);if (pixel.a > 0.1f) // 透明度判断,找到道路轨迹{Vector2 point = new Vector2((x - rect.width / 2) * scaleX, // UI 坐标转换(y - rect.height / 2) * scaleY);points.Add(point);break;}}}// 生成曲线路径pathCurve = new AnimationCurve();foreach (Vector2 p in points){pathCurve.AddKey(p.x, p.y);}}
}

生成一条与路径相同的Curve,效果如下👇

2.2 让图标沿道路轨迹移动

思路:

  • 监听 Slider 拖动事件,获取 value
  • Slider 值映射到曲线的 X 轴坐标
  • 计算对应 Y 轴坐标,更新图标位置
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;public class FollowPath : MonoBehaviour
{public PathGenerator pathGenerator; // 路径生成器public Slider slider; // 控制 CurrentX 的 Sliderasync void Start(){if (slider != null){slider.onValueChanged.AddListener(OnSliderValueChanged);}await UniTask.WaitForFixedUpdate();OnSliderValueChanged(slider.value);}void OnSliderValueChanged(float value){if (pathGenerator == null || pathGenerator.pathCurve.length == 0 || slider == null) return;// 获取路径的X范围float minX = pathGenerator.pathCurve.keys[0].time;float maxX = pathGenerator.pathCurve.keys[pathGenerator.pathCurve.length - 1].time;// 映射 Slider 的值到 CurrentXfloat currentX = Mathf.Lerp(minX, maxX, value);// 获取对应的Y坐标float y = pathGenerator.pathCurve.Evaluate(currentX);// 更新 UI 位置RectTransform rectTransform = GetComponent<RectTransform>();rectTransform.anchoredPosition = new Vector2(0, y + 4);}
}

3. 运行效果

  1. 点击 Generate Path,从 UI 图片解析道路轨迹
  2. 拖动 Slider,图标沿道路轨迹平滑移动
  3. 可用于 UI 导航、路径动画等场景

4. 适用场景

UI 地图导航(如 GPS 轨迹动画)
车辆行驶路径(如小车沿地图行驶)
手绘路径动画(如绘制道路后小车自动行驶)

如果有更好的优化方案,欢迎讨论! 🚀


最后贴上道路线的图片:


http://www.ppmy.cn/server/167558.html

相关文章

消息中间件:RabbitMQ镜像集群部署配置全流程

目录 1、特点 2、RabbitMQ的消息传递模式 2.1、简单模式&#xff08;Simple Mode&#xff09; 2.2、工作队列模式&#xff08;Work Queue Mode&#xff09; 2.3、发布/订阅模式&#xff08;Publish/Subscribe Mode&#xff09; 2.4、路由模式&#xff08;Routing Mode&am…

Shell 概述

shell简介 echo $SHELL/bin/bash 创建第一个shell脚本 touch helloworld.sh vim helloworld.sh在helloworld.sh 中输入如下内容&#xff1a; #!/bin/bash echo “helloworld” 执行shell文件 bash/sh 文件的相对路径或者绝对路径 bash hellowrold.sh hello,world sh /ro…

【Python】如何在 Linux/Windows 系统中设置 PYTHONPATH 环境变量

什么是 PYTHONPATH&#xff1f; PYTHONPATH 是一个环境变量&#xff0c;它告诉 Python 解释器在哪些目录中查找要导入的模块。这对于包含不在标准目录中的自定义模块非常有用。 Linux 系统中设置 PYTHONPATH 环境变量 在 Python 开发环境中&#xff0c;正确设置 PYTHONPATH …

【JavaScript】异步编程汇总

异步编程解决方案&#xff1a; 回调函数PromiseGeneratorawait / async 回调函数 回调函数是早期处理异步编程的主要方式&#xff0c;虽然它本身存在很多的缺陷&#xff0c;比如那个时候对于复杂的异步处理常常会出现回调地狱。 但是因为 JavaScript 中当时并没有很好的API来帮…

2025年智慧城市解决方案下载:AI-超脑中台,体系架构整体设计

2025年&#xff0c;随着人工智能、物联网、大数据等新兴技术的深度融合&#xff0c;智慧城市解决方案正迈向更高层次的智能化和协同化阶段。其中&#xff0c;AI-超脑中台作为核心架构的一部分&#xff0c;为城市智能化运行提供了强大支撑。 智慧城市最新解决方案&#xff0c;标…

ConcurrentHashMap扩容

目录 一、tryPreSize方法-初始化数组 二、tryPreSize方法-扩容标识戳 三、transfer方法-构建新数组 四、transfer方法-迁移数据 五、transfer方法-lastRun机制 六、helpTransfer方法-协助扩容 三种触发方式 达到了扩容的阈值 一、tryPreSize方法-初始化数组 // 扩容前…

navicat导出表结构到Excel 带字段备注

navicat导出表结构到Excel 带字段备注 SELECTCOLUMN_NAME AS 字段名称,COLUMN_TYPE AS 字段类型, IF( IS_NULLABLE NO, 否, 是 ) AS 是否必填,COLUMN_COMMENT AS 注释 FROMINFORMATION_SCHEMA.COLUMNS WHERE -- 数据库名table_schema vmscenter -- 表名AND table_name y…

redis底层数据结构——整数集合

文章目录 定义内部实现升级升级的好处提升灵活性节约内存 降级总结 定义 整数集合&#xff08;intset&#xff09;是集合键的底层实现之一&#xff0c;当一个集合只包含整数值元素&#xff0c;并且这个集合的元素数量不多时&#xff0c;Redis就会使用整数集合作为集合键的底层…