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

Unity3d实现线条从屏幕鼠标点击位置起始并松键后延伸的方法

实现鼠标点击起始、松开后延伸的线条绘制方案(Unity 2D)

嘿,针对你这个需求,我整理了一套适配Unity 2D的实现方案,核心是分阶段处理鼠标事件和LineRenderer的状态,完美契合“点击锁起点、松开再延伸”的要求,还能配合游戏里的下落小球。

核心逻辑拆解

要实现这个效果,我们需要把流程拆成三个明确的阶段:

  • 鼠标按下瞬间:立刻记录点击的世界坐标作为线条起点,此时只渲染一个点(相当于锁定起点)
  • 按住鼠标期间:保持线条的起点状态,不做任何延伸操作
  • 鼠标松开后:开启线条延伸模式,让终点跟随下落小球(或者你自定义的延伸逻辑)动态更新

修改后的完整代码

using UnityEngine;

public class TrailCollider : MonoBehaviour
{
    [SerializeField] private LineRenderer line; // 关联LineRenderer组件
    [SerializeField] private PhysicsMaterial2D phys; // 保留你原有的物理材质引用
    [SerializeField] private GameObject fallingBall; // 拖入你的下落小球对象

    private Vector3 startPos; // 线条的固定起点
    private bool canDraw = false; // 标记是否允许线条延伸
    private bool hasSetStart = false; // 标记是否已经记录了起点

    void Awake()
    {
        // 初始化LineRenderer:默认隐藏,设置基础样式
        if (line == null)
            line = GetComponent<LineRenderer>();
        
        line.enabled = false;
        line.startWidth = 0.1f;
        line.endWidth = 0.1f;
    }

    void Update()
    {
        // 处理鼠标按下:锁定起点
        if (Input.GetMouseButtonDown(0))
        {
            // 把鼠标屏幕坐标转成世界坐标,对齐小球的Z轴避免层级问题
            startPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            startPos.z = fallingBall.transform.position.z;
            
            // 只渲染起点,让玩家看到点击的位置
            line.enabled = true;
            line.positionCount = 1;
            line.SetPosition(0, startPos);
            
            hasSetStart = true;
            canDraw = false;
        }

        // 处理鼠标松开:开启延伸模式
        if (Input.GetMouseButtonUp(0) && hasSetStart)
        {
            canDraw = true;
            // 初始化线条的两个点:起点 + 当前小球位置
            line.positionCount = 2;
            line.SetPosition(1, fallingBall.transform.position);
        }

        // 延伸阶段:每一帧更新线条终点
        if (canDraw && hasSetStart)
        {
            line.SetPosition(1, fallingBall.transform.position);
            // 如果需要线条有物理碰撞,就调用这个方法同步碰撞体
            UpdateLineCollider();
        }
    }

    // 同步线条的碰撞体(可选,需要物理交互的话保留)
    private void UpdateLineCollider()
    {
        EdgeCollider2D edgeCollider = GetComponent<EdgeCollider2D>();
        if (edgeCollider == null)
        {
            edgeCollider = gameObject.AddComponent<EdgeCollider2D>();
            edgeCollider.sharedMaterial = phys;
        }

        // 把LineRenderer的两个点赋值给EdgeCollider2D
        Vector2[] colliderPoints = new Vector2[2];
        colliderPoints[0] = line.GetPosition(0);
        colliderPoints[1] = line.GetPosition(1);
        edgeCollider.points = colliderPoints;
    }
}

关键细节说明

  • 状态标记:用hasSetStart和canDraw两个布尔值区分不同阶段,避免误触发延伸逻辑
  • 坐标对齐:转换鼠标坐标时特意对齐小球的Z轴,确保线条和小球在同一渲染层级,不会出现错位
  • LineRenderer状态控制:按下鼠标时只设置1个点(仅显示起点),松开后切换为2个点并开始更新终点,完美匹配需求
  • 碰撞体同步:UpdateLineCollider方法会自动创建/更新EdgeCollider2D,让线条能和小球或其他物体产生物理交互,如果你不需要碰撞可以直接删掉这段

上手注意事项

  1. 把这个脚本挂在带有LineRenderer的GameObject上(如果没有,Awake里会自动添加)
  2. 在Inspector面板把你的下落小球拖到fallingBall字段里
  3. 可以直接在LineRenderer组件上调整线条的颜色、宽度等样式
  4. 如果不需要物理碰撞,直接删除UpdateLineCollider方法和相关调用即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:58:24