Hi. So I have been trying to create a laser obstacle for my game. I wanted it to behave like it would in real life; It is blocked by collision. I have no idea how I could create this so I thought someone could help me.
Use a raycast to determine the length and if it has hit anything. You could also use a line renderer for the laser. You can set the line endpoint from the raycast hit point.
Here to back up what @WarmedxMints_1 said… that is the way to do it exactly.
That way it can also be live: you push a blocker into the laser path and it instantly stops at the RaycastHit point, assuming you’re casting each frame.
And you can also use that point to put a little sparkly particle ball, as if the laser is sizzling on the obstacle.
This is probably a very stupid question.
I have now got this script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Laser : MonoBehaviour {
private LineRenderer lr;
public Transform LaserHit;
void Start () {
lr = GetComponent<LineRenderer>();
}
// Update is called once per frame
void Update () {
lr.SetPosition(0, transform.position);
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.up, out hit)) {
if (hit.collider) {
lr.SetPosition(1, hit.point);
}
}
else lr.SetPosition(1, transform.up*5000);
}
}
It works great on 3D objects but how could I get it to collide with 2D objects?
I got the script from here btw.
Has to be reworked to use all the 2D physics equivalents:
Physics.Raycast → Physics2D.Raycast
RaycastHit → RaycastHit2D
There are subtle differences in how the 2D Raycast function works: it doesn’t return a “did I hit anything?” boolean but rather returns a RaycastHit2D object that may or may not contain something it hit.
But in the end it will give you the same values you need for the endpoint.
NOTE: the above script kinda seems wired to only go UP relative to the current object, which is determined by the transform.up expressions.
Addendum: if you are colliding with UnityEngine.UI objects (things under a Canvas) it gets a bit more complicated because those exist in the given Canvas’ coordinate system (Depending on canvas mode and scaling), whereas LineRenderer always exists in 3D space.
If you’re trying to hit good old sprites, you’re fine.
Yes! I got it working!. Here’s the script for anyone that needs it:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Laser : MonoBehaviour {
private LineRenderer lr;
public Transform LaserHit;
void Start () {
lr = GetComponent<LineRenderer>();
}
// Update is called once per frame
void Update () {
lr.SetPosition(0, transform.position);
RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.up);
if (hit.collider != null) {
lr.SetPosition(1, hit.point);
}
else lr.SetPosition(1, transform.up*5000);
}
}
It’s also worth noting that if you have a box collider on the object the line will collide with it and therefore won’t appear.
BAM! Very nice.
One way to deconflict this is to specify layers and layermasks, and to make the hittable things on a different layer than your lasers.
BUT… if you want lasers to be able to hit other lasers, well, that can be addressed by each laser unit disabling its own collider, doing the raycast, then switching its collider back on immediately afterwards.