Monday, 10 November 2014

2# Twisted lasers - Reflecting laser beam

For the last couple of evenings (after daily job as developer) I was working on Twisted lasers game, exactly on laser reflection. As a player you have ability to rotate mirror and depends on mirror rotation laser beam will be reflected. 
For laser beam I used line renderer. 
To find out if an object is placed on laser beam I used Physics.LineCast.
If object is mirror we want to instantiate new line renderer where initial position is hit point and destination position depends on laser beam origin direction. 



I know the code is a bit dirty, not optimized and refactored, but this is just initial mock up and hopefully find better solution.

LateUpdate function:

if(myhit.transform.tag == "Mirror")
   {
    // depends on X rotation of mirror object, manipulate laser beam

    this.lineRenderer.SetPosition(1, myhit.transform.position);
    myhit.transform.tag = "OnLaser";
    GameObject lr = Instantiate(this.gameObject, originBeam, transform.rotation) as GameObject;

    Vector3 reflectVector = CalculateReflectVector(myhit.transform, originBeam);

    lr.GetComponent<linerenderer>().SetPosition(0, myhit.transform.position);
    lr.GetComponent<linerenderer>().SetPosition(1, reflectVector);

    lr.GetComponent<laserbeamtriggered>().originBeam = myhit.transform.position;
    lr.GetComponent<laserbeamtriggered>().directionBeam = reflectVector;

    laserBeamAdded = true;

   }

public Vector3 CalculateReflectVector(Transform hitBeam, Vector3 originBeam)
 {
  // Calculate second line renderer Vector 3
  if (originBeam.y < hitBeam.position.y) {
    Debug.Log ("Laser under");
    Debug.Log (hitBeam.transform.eulerAngles.z);
    // origin laser under target
    if ((int)hitBeam.transform.eulerAngles.z == 45) {
      return new Vector3 (hitBeam.transform.position.x + laserOffset, hitBeam.transform.position.y, hitBeam.transform.position.z);
    } else {
      return new Vector3 (hitBeam.transform.position.x - laserOffset, hitBeam.transform.position.y, hitBeam.transform.position.z);
    }
  } else if (originBeam.y > hitBeam.position.y) {
    Debug.Log ("Laser top");
    // origin laser at the top of the target
    if ((int)hitBeam.transform.eulerAngles.z == 45) {
      return new Vector3 (hitBeam.transform.position.x - laserOffset, hitBeam.transform.position.y, hitBeam.transform.position.z);
    } else {
      return new Vector3 (hitBeam.transform.position.x + laserOffset, hitBeam.transform.position.y, hitBeam.transform.position.z);
    }
  } else if (originBeam.x < hitBeam.position.x) {
    // origin laser at right
    if ((int)hitBeam.transform.eulerAngles.z == 45) {
     return new Vector3 (hitBeam.transform.position.x, hitBeam.transform.position.y + laserOffset, hitBeam.transform.position.z);
    } else {
    return new Vector3 (hitBeam.transform.position.x, hitBeam.transform.position.y - laserOffset, hitBeam.transform.position.z);
    }
  }

  else if (originBeam.x > hitBeam.position.x) {
   // origin laser at right
   if ((int)hitBeam.transform.eulerAngles.z == 45) {
    return new Vector3 (hitBeam.transform.position.x, hitBeam.transform.position.y - laserOffset, hitBeam.transform.position.z);
   } else {
    return new Vector3 (hitBeam.transform.position.x, hitBeam.transform.position.y + laserOffset, hitBeam.transform.position.z);
   }
  }
  
  
  // if fails
  return originBeam;
 }