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
相关产品推荐
相关产品推荐

