Unity UI 道路线跟随:让图标沿道路轨迹移动
在 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 的 Slider
async 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 的值到 CurrentX
float 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. 运行效果
- 点击
Generate Path
,从 UI 图片解析道路轨迹 - 拖动
Slider
,图标沿道路轨迹平滑移动 - 可用于 UI 导航、路径动画等场景
4. 适用场景
✅ UI 地图导航(如 GPS 轨迹动画)
✅ 车辆行驶路径(如小车沿地图行驶)
✅ 手绘路径动画(如绘制道路后小车自动行驶)
如果有更好的优化方案,欢迎讨论! 🚀
最后贴上道路线的图片: