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

Unity中Line Renderer的Edge Collider碰撞检测偶发失效问题

问题:Edge Collider碰撞检测失效,玩家穿过碰撞体

我将Edge Collider附加在带有Line Renderer的父物体上,有时碰撞检测会失效,导致玩家直接穿过该碰撞体,这种情况在拖动Line Renderer时尤为明显。Line Renderer与玩家对象均配置了Dynamic Rigidbody。

线条上带有Circle Collider,当Circle Collider紧密排列时玩家不会穿过,但快速拖动鼠标绘制线条时,Circle Collider之间会出现间隙,即便存在Edge Collider,玩家仍会穿过这些间隙。

绘线代码

using UnityEngine;

public class LinesDrawer : MonoBehaviour 
{
    public GameObject linePrefab;
    public LayerMask cantDrawOverLayer;
    int cantDrawOverLayerIndex;

    [Space ( 30f )]
    public Gradient lineColor;
    public float linePointsMinDistance;
    public float lineWidth;

    Line currentLine;

    Camera cam;


    void Start ( ) {
        cam = Camera.main;
        cantDrawOverLayerIndex = LayerMask.NameToLayer ( "CantDrawOver" );
    }

    void Update ( ) {
        if ( Input.GetMouseButtonDown ( 0 ) )
            BeginDraw ( );

        if ( currentLine != null )
            Draw ( );

        if ( Input.GetMouseButtonUp ( 0 ) )
            EndDraw ( );
    }

    // Begin Draw ----------------------------------------------
    void BeginDraw ( ) {
        currentLine = Instantiate ( linePrefab, this.transform ).GetComponent <Line> ( );

        //Set line properties
        currentLine.UsePhysics ( false );
        currentLine.SetLineColor ( lineColor );
        currentLine.SetPointsMinDistance ( linePointsMinDistance );
        currentLine.SetLineWidth ( lineWidth );

    }
    // Draw ----------------------------------------------------
    void Draw ( ) {
        Vector2 mousePosition = cam.ScreenToWorldPoint ( Input.mousePosition );

        //Check if mousePos hits any collider with layer "CantDrawOver", if true cut the line by calling EndDraw( )
        RaycastHit2D hit = Physics2D.CircleCast ( mousePosition, lineWidth / 3f, Vector2.zero, 1f, cantDrawOverLayer );

        if ( hit )
            EndDraw ( );
        else
            currentLine.AddPoint ( mousePosition );
    }
    // End Draw ------------------------------------------------
    void EndDraw ( ) {
        if ( currentLine != null ) {
            if ( currentLine.pointsCount < 2 ) {
                //If line has one point
                Destroy ( currentLine.gameObject );
            } else {
                //Add the line to "CantDrawOver" layer
                currentLine.gameObject.layer = cantDrawOverLayerIndex;

                //Activate Physics on the line
                currentLine.UsePhysics ( true );

                currentLine = null;
            }
        }
    }
}

线条属性代码

using UnityEngine;
using System.Collections.Generic;

public class Line : MonoBehaviour
{

    public LineRenderer lineRenderer;
    public EdgeCollider2D edgeCollider;
    public Rigidbody2D rigidBody;

    [HideInInspector] public List<Vector2> points = new List<Vector2> ( );
    [HideInInspector] public int pointsCount = 0;

    //The minimum distance between line's points.
    private float pointsMinDistance = 0.1f;

    //Circle collider added to each line's point
    private float circleColliderRadius;

    public void AddPoint ( Vector2 newPoint ) {
        //If distance between last point and new point is less than pointsMinDistance do nothing (return)
        if ( pointsCount >= 1 && Vector2.Distance ( newPoint, GetLastPoint ( ) ) < pointsMinDistance )
            return;

        points.Add ( newPoint );
        pointsCount++;

        //Add Circle Collider to the Point
        CircleCollider2D circleCollider = this.gameObject.AddComponent <CircleCollider2D> ( );
        circleCollider.offset = newPoint;
        circleCollider.radius = circleColliderRadius;

        //Line Renderer
        lineRenderer.positionCount = pointsCount;
        lineRenderer.SetPosition ( pointsCount - 1, newPoint );

        //Edge Collider
        //Edge colliders accept only 2 points or more (we can't create an edge with one point :D )
        if ( pointsCount > 1 )
            edgeCollider.points = points.ToArray ( );
    }

    public Vector2 GetLastPoint ( ) {
        return ( Vector2 )lineRenderer.GetPosition ( pointsCount - 1 );
    }

    public void UsePhysics ( bool usePhysics ) {
        // isKinematic = true  means that this rigidbody is not affected by Unity's physics engine
        rigidBody.isKinematic = !usePhysics;
    }

    public void SetLineColor ( Gradient colorGradient ) {
        lineRenderer.colorGradient = colorGradient;
    }

    public void SetPointsMinDistance ( float distance ) {
        pointsMinDistance = distance;
    }

    public void SetLineWidth ( float width ) {
        lineRenderer.startWidth = width;
        lineRenderer.endWidth = width;

        circleColliderRadius = width / 2f;

        edgeCollider.edgeRadius = circleColliderRadius;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 01:10:19