You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity 2D游戏中如何实现可点击物体沿点击道路路径移动?

解决方案:基于轨道定位的物体路线切换

根据你的游戏场景(横向平行道路),不需要复杂的NavMesh或样条曲线,核心是让物体切换到选中道路的固定轨道,同时保持原方向移动,以下是具体实现步骤:

1. 道路标记与点击响应

给每条道路添加脚本,存储其轨道的Y坐标,点击时通知选中物体切换轨道:

using UnityEngine;
using UnityEngine.EventSystems;

public class Road : MonoBehaviour, IPointerClickHandler
{
    [Header("道路轨道Y坐标")]
    public float targetY;

    public void OnPointerClick(PointerEventData eventData)
    {
        var selectedObj = ObjectSelector.Instance.SelectedMovingObj;
        if (selectedObj != null)
        {
            selectedObj.SetTargetTrackY(targetY);
        }
    }
}

2. 选中物体管理

用单例管理当前选中的移动物体,避免全局变量混乱:

public class ObjectSelector : MonoBehaviour
{
    public static ObjectSelector Instance { get; private set; }
    public MovingObject SelectedMovingObj { get; private set; }

    void Awake()
    {
        Instance = this;
    }

    public void SelectObject(MovingObject obj)
    {
        SelectedMovingObj = obj;
        // 可选:添加选中视觉反馈,比如改变物体颜色
    }
}

3. 修改移动物体脚本

整合你的点击交互和移动逻辑,实现平滑轨道切换:

using UnityEngine;
using UnityEngine.EventSystems;

public class MovingObject : MonoBehaviour, IPointerClickHandler
{
    public float moveSpeed = 3f;
    public float trackSwitchSpeed = 6f;

    private float _targetY;
    private bool _isSwitchingTrack;

    void Start()
    {
        // 初始化目标Y为物体初始位置
        _targetY = transform.position.y;
    }

    void FixedUpdate()
    {
        Vector3 newPos = transform.position;
        // X方向持续移动
        newPos.x += Time.deltaTime * moveSpeed;

        // Y方向平滑切换轨道
        if (_isSwitchingTrack)
        {
            newPos.y = Mathf.MoveTowards(newPos.y, _targetY, Time.deltaTime * trackSwitchSpeed);
            // 到达目标轨道后停止切换
            if (Mathf.Abs(newPos.y - _targetY) < 0.02f)
            {
                _isSwitchingTrack = false;
            }
        }

        transform.position = newPos;
    }

    public void SetTargetTrackY(float targetY)
    {
        _targetY = targetY;
        _isSwitchingTrack = true;
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        ObjectSelector.Instance.SelectObject(this);
        Debug.Log("已选中:" + gameObject.name);
    }
}

4. 碰撞风险检测补充

如果需要判断切换轨道时的碰撞风险,可以在SetTargetTrackY方法中添加检测逻辑:

public void SetTargetTrackY(float targetY)
{
    // 检测目标轨道上前方的物体(根据移动方向调整射线方向)
    RaycastHit2D hit = Physics2D.Raycast(transform.position + Vector3.right * 0.5f, Vector3.right, 2f, LayerMask.GetMask("MovingObjects"));
    if (hit.collider != null)
    {
        Debug.Log("前方有物体,无法切换轨道");
        return;
    }

    _targetY = targetY;
    _isSwitchingTrack = true;
}

使用说明

  1. 将Road脚本挂载到每条道路上,在Inspector设置对应轨道的targetY值
  2. 将MovingObject脚本挂载到三个移动物体上,设置移动速度和切换速度
  3. 创建空物体挂载ObjectSelector脚本,作为单例管理器
  4. 确保道路和物体都添加了EventSystem需要的组件(比如EventTrigger或者实现IPointerClickHandler,并确保场景中有EventSystem对象)

内容的提问来源于stack exchange,提问作者ttolo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 04:05:37