Search Unity

Trail with collision behind the cars

Discussion in 'Scripting' started by n3eQQ, Jul 2, 2020.

  1. n3eQQ

    n3eQQ

    Joined:
    Jun 22, 2020
    Posts:
    2
    Hi,
    I want to ask you what is the best and most efficient way of make a trail with collision behind the cars (with 5 cars per game). The time of round will be 2/3 min and all trails life must be keeped to end of the round.
    I read smth about solution for this and I found multiple approach:
    1. In first I can use "Line Renderer" Component in Unity and set the points of this line based on my car position.
    After that read the values from array of positon in Line Renderer and create a "Physic.LineCast" from point to point and check that smth intersect that line. But this approach is not too good for efficient in game.
    I must check list of object and send line cast for every point to point. Moreover "LineCast" is create in Update
    (terrible for otymalization) but I think that I could use Coroutines to make that physic line at intervals e.g 0.5s.
    I wrote basic script based on that but the problem is that the line dont fit exacly the LineRenderer with width e.g 1.0f. I thought about made 2 "LineCast" on the left and right of "LineRenderer" but the calls is multiple in this case 2x. Script and screen from game below.

    2. I have read that I can simply set points in "LineRenderer" like in 1 approach. After set edge collider verticies to verticies from "LineRenderer" but it works only for 2d and my game is 3d.

    3. I can use "LineRenderer" and base on his verticies create a mash and set mesh collider.

    Code for point 1:

    TrailRenderer Setup

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using System.Linq;
    3. using UnityEngine;
    4.  
    5. [RequireComponent(typeof(LineRenderer))]
    6. //[RequireComponent(typeof(EdgeCollider2D))]
    7. public class Trail : MonoBehaviour
    8. {
    9.     public float pointSpacing = 0.5f;
    10.     private List<Vector3> points;
    11.     public LineRenderer line;
    12.     //private EdgeCollider2D collider;
    13.  
    14.     void Start()
    15.     {
    16.         line = GetComponent<LineRenderer>();
    17.         //collider = GetComponent<EdgeCollider2D>();
    18.  
    19.         points = new List<Vector3>();
    20.  
    21.         SetPoint();
    22.     }
    23.  
    24.     void Update()
    25.     {
    26.         if(Vector3.Distance(points.Last(), transform.position) > pointSpacing)
    27.         {
    28.             SetPoint();
    29.         }
    30.        
    31.     }
    32.  
    33.     void SetPoint()
    34.     {
    35.  
    36.         //Vector3 position = new Vector3(transform.position.x, 0.51f, transform.position.z);
    37.         //Vector2 pointPosition = new Vector2(transform.position.x, transform.position.z);
    38.         points.Add(transform.position);
    39.  
    40.         line.positionCount = points.Count;
    41.         line.SetPosition(points.Count - 1, transform.position);
    42.  
    43.        
    44.  
    45.         //if (points.Count > 1)
    46.             //collider.points = points.ToArray<Vector2>();
    47.     }
    48.  
    49. }
    50.  
    Script that checks collision

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. [RequireComponent(typeof(MeshRenderer))]
    6. [RequireComponent(typeof(MeshFilter))]
    7. public class TrailCollider : MonoBehaviour
    8. {
    9.     public Trail trail;
    10.     List<Vector3> position;
    11.     int verticiesCount = 0;
    12.  
    13.     void Start()
    14.     {
    15.         position = new List<Vector3>();
    16.         position.Add(trail.line.GetPosition(0));
    17.     }
    18.  
    19.     void Update()
    20.     {
    21.         if (trail.line.positionCount > 1)
    22.         {
    23.             if (verticiesCount + 3 < trail.line.positionCount)
    24.             {
    25.                 verticiesCount = trail.line.positionCount;
    26.  
    27.                 Vector3 newPoint = trail.line.GetPosition(trail.line.positionCount - 1);
    28.                 position.Add(newPoint);
    29.  
    30.                 Debug.Log(position.Count);
    31.  
    32.                 if (position.Count > 1)
    33.                 {
    34.                     for (int i = 0; i < position.Count - 2; i++)
    35.                     {
    36.                         Debug.DrawLine(position[i], position[i + 1], Color.blue, 0.1f);
    37.  
    38.                         if (Physics.Linecast(position[i], position[i + 1]))
    39.                         {
    40.                             //Debug.Log("blocked");
    41.  
    42.                         }
    43.                     }
    44.                 }
    45.             }
    46.         }
    47.     }
    48. }
    49.  
    Maybe you have other advice to me or you know what will be the best solution for such project.
    Thanks for help :)
     

    Attached Files:

  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    It might not be necessary to marry the visuals of your line to the colliders created.

    For instance, it might be acceptable to produce your linerender as you are now, and then at each frame emit a fresh SphereCollider behind the car. Or emit a fresh SphereCollider every time the car travels the distance of one SphereCollider's radius times some constant, such as 1.5x for instance.

    I would batch the colliders up on separate non-moving GameObjects you just litter behind you. Perhaps add X SphereColliders to a single GameObject, then make a fresh GameObject for the next X colliders. That will enable to physics system to ignore entire GameObjects if their effective collision bounds fail the check.
     
  3. Zer0Cool

    Zer0Cool

    Joined:
    Oct 24, 2014
    Posts:
    203
    Depends on what kind of colliders you need for your game. A simple and fast prototype solution would be to use quad primitves (and remove the renderer). If you need thicker colliders i would use capsule primitives (you can even combine meshes here and recreate the collider at runtime and throw away the gameobjects after).

    If the quad primitives are working you could decide to create the meshes procedural (for better performance) and create the collider (so also the mesh) each 20 vertex segments for instance ... (so solution 3)
     
    Last edited: Jul 3, 2020