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

Unity 2D手游LineRenderer异常:球运动时触摸以(0,0)为起点

问题描述

在2D Unity移动端游戏中,触摸拖拽小球时,LineRenderer会从小球位置延伸至拖拽方向,功能正常;但当小球处于运动状态(未停止)时触摸屏幕,后续生成的LineRenderer会以(0,0)为起点,而非当前小球所在位置。

  • 正常效果:正常效果
  • 异常效果:异常效果

即便代码中通过!hasMoved限制小球运动时不响应触摸,但若在小球停止前触摸屏幕,后续生成的LineRenderer仍会出现起点错误的问题。

相关代码片段
void Update()
{
    if (Input.touchCount > 0 && !hasMoved)
    {
        touch = Input.GetTouch(0);

        if (touch.phase == TouchPhase.Began)
        {
            dragStart();
        }
        if (touch.phase == TouchPhase.Moved)
        {
            Dragging();
        }
        if (touch.phase == TouchPhase.Ended)
        {
            DragRelease();
        }
    }
}

void dragStart()
{
    dragStartposition = transform.position;
    dragStartposition.z = 0;
    gostergeLine.positionCount = 1;
    gostergeLine.SetPosition(0,transform.position);
}

void Dragging()
{
    Vector3 draggingPos = Camera.main.ScreenToWorldPoint(touch.position);
    draggingPos.z = 0;
    gostergeLine.positionCount = 2;
    gostergeLine.SetPosition(1, draggingPos);
}

void DragRelease()
{
    gostergeLine.positionCount = 0;
    Vector3 dragReleasePos = Camera.main.ScreenToWorldPoint(touch.position);
    dragReleasePos.z = 0;
    Vector3 forceVec = dragStartposition - dragReleasePos;
    forcePower = forceVec.magnitude;

    if(forcePower > 45)
    {
        topRb.velocity = forceVec * 45;
    }
    else
    {
        topRb.velocity = forceVec * forcePower;
    }
}
问题原因

小球运动时hasMoved为true,此时触摸的TouchPhase.Began不会触发dragStart()初始化LineRenderer起点;如果触摸持续到小球停止(hasMoved变为false),后续的TouchPhase.Moved会直接调用Dragging(),此时LineRenderer的position[0]从未被设置,默认使用(0,0)作为起点。同时触摸状态没有被及时重置,导致跨状态的触摸事件残留。

解决方案
  1. 增加运动时的LineRenderer重置逻辑
    在Update开头添加判断,小球运动时直接清空LineRenderer状态,避免残留:
void Update()
{
    // 小球运动时强制清空LineRenderer
    if (hasMoved && gostergeLine.positionCount > 0)
    {
        gostergeLine.positionCount = 0;
    }

    if (Input.touchCount > 0 && !hasMoved)
    {
        touch = Input.GetTouch(0);

        if (touch.phase == TouchPhase.Began)
        {
            dragStart();
        }
        else if (touch.phase == TouchPhase.Moved)
        {
            Dragging();
        }
        else if (touch.phase == TouchPhase.Ended)
        {
            DragRelease();
        }
    }
}
  1. Dragging时校验起点是否初始化
    在Dragging()中增加判断,确保LineRenderer起点已被设置,未设置则自动初始化:
void Dragging()
{
    // 确保起点已初始化
    if (gostergeLine.positionCount == 0)
    {
        dragStart();
    }
    Vector3 draggingPos = Camera.main.ScreenToWorldPoint(touch.position);
    draggingPos.z = 0;
    gostergeLine.positionCount = 2;
    gostergeLine.SetPosition(1, draggingPos);
}
  1. 精准控制hasMoved状态切换
    通过Rigidbody的速度值判断小球是否停止,避免状态切换延迟:
void FixedUpdate()
{
    // 当小球速度趋近于0时标记为停止状态
    hasMoved = topRb.velocity.magnitude >= 0.1f;
}

内容的提问来源于stack exchange,提问作者Fahrettin Özkan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 21:35:16