- Home /
Stop LineRenderer if it collides with something
I'm making a angry birds style game, and i want to stop the line renderer if it hits or collides with another game objects at run time. is it possible by any way? i don't that the line renderer doesn't pass any game object like the example shown right now it passes throughout the wall i want to stop as it touches the wall like the second image shown, any help would be appreciated, TIA.
Answer by tsnyder321 · Aug 03, 2017 at 02:52 PM
Hello @ddk4113!
If I were to try what you are asking, I would use the line renderer in tandem with a raycast. First raycast along the path your line renderer will travel. If it collides with an object, store the hit point to use as the end of your line renderer. Then draw your line renderer.
Edit: After discussing this with @ddk4113 in the comments, here is a simple solution using the linecast instead of a raycast. I created the simple script below (it needs a good deal of work done to it to refine it to what you will need) but it gives you the basic idea of what I am suggesting. I was able to achieve the desired result as shown in the pictures below.
You will see some initialization code in the Start function because I used 4 transforms under a parent object as my starting points for the line renderer.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(LineRenderer))]
public class LineRenderWithCollisionDetection : MonoBehaviour
{
LineRenderer lineRenderer = null;
Vector3[] startingLineRendererPoints = null;
// Use this for initialization
void Start () {
//get the attacked line renderer
lineRenderer = GetComponent<LineRenderer>();
//set the max points in the line renderer. This will be custom as you need it
lineRenderer.positionCount = 4;
//setup the array to store the starting positions of the line renderer points. May need updated as you apply rotation, gravity, etc.
startingLineRendererPoints = new Vector3[4];
//This gets 4 transform points under the parent object that I use to first create the shape of the line renderer
lineRenderer.SetPosition(0, transform.Find("S").position);
lineRenderer.SetPosition(1, transform.Find("M1").position);
lineRenderer.SetPosition(2, transform.Find("M2").position);
lineRenderer.SetPosition(3, transform.Find("E").position);
//store the starting points in the array
lineRenderer.GetPositions(startingLineRendererPoints);
}
// Fixed update is used for physics
void FixedUpdate ()
{
bool hitSomething = false;
if(lineRenderer)
{
RaycastHit hitInfo;
//create an array to hold the line renderer points
Vector3[] newPointsInLine = null;
for (int i = 0; i < startingLineRendererPoints.Length - 1; i++)
{
if(Physics.Linecast(startingLineRendererPoints[i], startingLineRendererPoints[i + 1], out hitInfo))
{
Debug.Log("Line cast between " + i + " " + startingLineRendererPoints[i] + " and " + i + 1 + " " + startingLineRendererPoints[i + 1]);
//initialize the new array to the furthest point + 1 since the array is 0-based
newPointsInLine = new Vector3[(i + 1) + 1];
//transfer the points we need to the new array
for(int i2 = 0; i2 < newPointsInLine.Length; i2++)
{
newPointsInLine[i2] = startingLineRendererPoints[i2];
}
//set the current point to the raycast hit point (the end of the line renderer)
newPointsInLine[i + 1] = hitInfo.point;
//flag that we hit something
hitSomething = true;
break;
}
}
if(hitSomething)
{
//use new points for the line renderer
lineRenderer.positionCount = newPointsInLine.Length;
lineRenderer.SetPositions(newPointsInLine);
}
else
{
//use old points for the line renderer
lineRenderer.positionCount = startingLineRendererPoints.Length;
lineRenderer.SetPositions(startingLineRendererPoints);
}
}
}
}
@ddk4113 I am not sure I understand the question you are asking. Have you ever dealt with Raycasting before? If not, there are some great Unity resources to help you with that.
https://unity3d.com/learn/tutorials/topics/physics/raycasting
https://docs.unity3d.com/ScriptReference/Physics.Raycast.html
@tsnyder321 yes, i did cast a ray in a straight direction, the question I'm asking is how to cast a ray in a parabolic path like if i throw an object at an angle of 45 degrees which will be using gravity and all the other physics, now to make a ray cast in that same path as that object which will use gravity and all the other effects.
Ah! I see. When I first saw the pictures (not sure if I miss it or you updated the images) I thought it was straight lines and not curved. So my first thought is to use the positions of your line renderer as points to linecast between ins$$anonymous$$d of raycast. If a linecast finds a contact point, make that the end of your line renderer and discard the extra points.
https://docs.unity3d.com/ScriptReference/Physics.Linecast.html
@ddk4113 I just wanted to make sure you saw my edited answer with the linecast code I used to achieve the result you were asking for? Was this what you wanted?
@tsnyder321 thank you. it worked in a separate 3D project ill implement in my 2D game and get back to you until then I'm accepting your answer.
[edited]
@tsnyder321 Hey, Thanks for this piece of code but somehow it's now forking in 2D i tried everything it is not blocking the objects in the 2D physics, if you could help me out here man.