- Home /
Laser Reflection in C#, bouncing the laser from one collider to another with a line renderer.
I am having trouble getting my lasers to react properly, I want them to reflect off the normals of my wedges like a mirror. I adapted a script that created a laser with line renderer points to show it , but I cannot get the direction to change at each collision.
Please help me solve this issue, and understand the solution. thanks.
First here's what it's like while running, then code after. Code Below:
using UnityEngine;
using System.Collections;
[RequireComponent (typeof(LineRenderer))]
public class LaserEmitter : MonoBehaviour {
public Transform EmmissionLocation;
public float laserWidth = 1.0f;
public float noise = 1.0f;
public float maxLength = 50.0f;
public Color color = Color.red;
public LineRenderer lineRenderer;
public Vector3 direction;
int length;
Vector3[] position;
//Cache any transforms here
Transform myTransform;
Transform endEffectTransform;
//The particle system, in this case sparks which will be created by the Laser
public ParticleSystem endEffect;
Vector3 offset;
// Use this for initialization
void Start () {
lineRenderer = GetComponent<LineRenderer>();
lineRenderer.SetWidth(laserWidth, laserWidth);
myTransform = EmmissionLocation.transform;
offset = new Vector3(0,0,0);
endEffect = GetComponentInChildren<ParticleSystem>();
if(endEffect)
endEffectTransform = endEffect.transform;
}
// Update is called once per frame
void Update () {
RenderLaser();
}
void RenderLaser(){
//Shoot our laserbeam forwards!
UpdateLength();
lineRenderer.SetColors(color,color);
//Move through the Array
for(int i = 0; i<length; i++){
//Set the position here to the current location and project it in the forward direction of the object it is attached to
offset.x =myTransform.position.x+i*myTransform.forward.x+Random.Range(-noise,noise);
offset.z =i*myTransform.forward.z+Random.Range(-noise,noise)+myTransform.position.z;
position[i] = offset;
position[0] = myTransform.position;
lineRenderer.SetPosition(i, position[i]);
}
}
void UpdateLength(){
//Raycast from the location of the cube forwards
RaycastHit[] hit;
direction = myTransform.forward;
hit = Physics.RaycastAll(myTransform.position, direction, maxLength);
int i = 0;
while(i < hit.Length){
//Check to make sure we aren't hitting triggers but colliders
if(!hit[i].collider.isTrigger)
{
length = (int)Mathf.Round(hit[i].distance)+2;
position = new Vector3[length];
direction = Vector3.Reflect(direction,hit[i].normal);
//Move our End Effect particle system to the hit point and start playing it
if(endEffect){
endEffectTransform.position = hit[i].point;
if(!endEffect.isPlaying)
endEffect.Play();
}
lineRenderer.SetVertexCount(length);
return;
}
i++;
}
//If we're not hitting anything, don't play the particle effects
if(endEffect){
if(endEffect.isPlaying)
endEffect.Stop();
}
length = (int)maxLength;
position = new Vector3[length];
lineRenderer.SetVertexCount(length);
}
}
I haven't deciphered your code, but I might be able to help you on your way anyway.
You need to do your raycasts in a loop, preferably only when you change the rotation of one of the mirrors. Then raycast to the first mirror (forwards), see if it hits anything (it should, no matter what.)
If it hits something, store the hit.point in a list. Get the new direction of the beam by using Vector3.Reflect() ((hit.point - StartingPoint).normalized, hit.normal). Do this until the Reflect returns back on itself or it reaches it's target.
Now use your stored list of points to create a line renderer :)
check out my q/a for similar topic: http://answers.unity3d.com/questions/350431/vector3reflect-wrong-direction.html
it is unityscript, but if you find it working, you shouldnt have too much problems to make it cs.. its very simple.
I actually borrowed that Reflect-stuff from your answer without even knowing it, chelnok :D
Was doing the same thing a while back and fixed it by doing what you did.