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

Unity2D安卓多人射箭游戏双触屏同时拖拽画线实现难题

解决安卓双触摸画线的问题

嘿,我懂你现在的糟心状况——用两个LineRenderer实例做双触摸画线时,先画的那条会突然冻结,只有最后一条能正常拖动,对吧?核心问题其实出在你用Input.touches的索引或者touchIndex来跟踪触摸上,这个数组的顺序是动态变化的,而每个触摸的fingerId才是唯一且稳定的标识,咱们得换个思路来处理。

核心思路调整

每个负责画线的脚本实例,应该只专注于处理自己区域内的触摸(左半屏/右半屏),并且用fingerId来跟踪属于自己的触摸,而不是依赖数组索引。这样两个脚本完全独立,不会互相干扰对方的触摸跟踪逻辑。

修改后的代码示例

先给右侧半屏的画线脚本写个示例,左侧的只需要改一下区域判断就行:

public class RightSideArrowDrawer : MonoBehaviour
{
    [SerializeField] private LineRenderer _lineRenderer;
    // 跟踪属于当前脚本的触摸ID,初始为-1表示未跟踪
    private int _trackingFingerId = -1;
    private Vector3 _dragStartPoint;

    void Update()
    {
        // 遍历所有触摸,只处理右半屏的
        foreach (Touch touch in Input.touches)
        {
            if (touch.position.x > Screen.width / 2)
            {
                switch (touch.phase)
                {
                    case TouchPhase.Began:
                        // 只有当前脚本没跟踪任何触摸时,才接管这个触摸
                        if (_trackingFingerId == -1)
                        {
                            _trackingFingerId = touch.fingerId;
                            _dragStartPoint = Camera.main.ScreenToWorldPoint(touch.position);
                            // 2D游戏里记得把Z轴设为固定值,确保线条在视野内
                            _dragStartPoint.z = 0f;
                            // 初始化线条起点
                            _lineRenderer.positionCount = 2;
                            _lineRenderer.SetPosition(0, _dragStartPoint);
                        }
                        break;

                    case TouchPhase.Moved:
                        // 只处理当前脚本跟踪的那个触摸
                        if (touch.fingerId == _trackingFingerId)
                        {
                            Vector3 currentEndPoint = Camera.main.ScreenToWorldPoint(touch.position);
                            currentEndPoint.z = 0f;
                            _lineRenderer.SetPosition(1, currentEndPoint);
                        }
                        break;

                    case TouchPhase.Ended:
                    case TouchPhase.Canceled:
                        // 如果是当前跟踪的触摸结束,重置状态并清除线条
                        if (touch.fingerId == _trackingFingerId)
                        {
                            _trackingFingerId = -1;
                            _lineRenderer.positionCount = 0;
                            // 这里可以加射箭逻辑:根据_startPoint和最后一次的endPoint计算方向力度
                        }
                        break;
                }
            }
        }
    }
}

左侧的脚本LeftSideArrowDrawer几乎完全一样,只需要把区域判断改成touch.position.x < Screen.width / 2即可。

为什么你的旧代码会出问题?

  1. 触摸跟踪逻辑错误:你用touchIndex记录触摸,但Input.touches的数组索引是动态变化的——比如先触摸左半屏(索引0),再触摸右半屏(索引1),如果左半屏的触摸结束,右半屏的触摸索引会变成0,这时候你的touchIndex就完全失效了。而fingerId是每个触摸的唯一标识,从触摸开始到结束都不会改变。
  2. 脚本互相干扰:两个脚本实例都在遍历所有触摸,并且各自维护touchIndex,很容易出现跟踪逻辑混乱的情况,最后只有最后一个触发的触摸能被正确处理。

额外注意事项

  • 给左右两个LineRenderer设置不同的颜色,方便测试时区分两条线。
  • 确保LineRenderer的Use World Space选项是勾选状态(如果你的游戏使用世界空间坐标的话)。
  • 2D游戏中,ScreenToWorldPoint的Z值要设置成相机焦距对应的数值,或者直接固定为0,避免线条出现在相机视野外。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 06:36:20