Raycast Reflection 2D
Hello, I am working on a 2D game in which I would like to add lasers. I did it and it works very well. But now I would like the laser to be reflected on an inclined object to take another direction but I can not do it. Help !!! xD
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Laser : MonoBehaviour
{
private LineRenderer lineRenderer;
public Transform laserHit;
public Color startColor;
public Color endColor;
public float coolDown;
public float time;
private float timeInitiale;
private void Start()
{
lineRenderer = GetComponent<LineRenderer>();
lineRenderer.enabled = true;
lineRenderer.useWorldSpace = true;
lineRenderer.material = new Material(Shader.Find("Sprites/Default"));
lineRenderer.SetColors(startColor, endColor);
timeInitiale = time;
time = time + coolDown;
}
private void Update()
{
RaycastHit2D hit = Physics2D.Raycast(transform.position, transform.up);
Debug.DrawLine(transform.position, hit.point);
laserHit.position = hit.point;
lineRenderer.SetPosition(0, transform.position);
lineRenderer.SetPosition(1, laserHit.position);
if(hit)
{
PlayerMovement player = hit.transform.GetComponent<PlayerMovement>();
if (player != null && lineRenderer.enabled == true)
{
player.KillPlayer();
}
}
time -= Time.fixedDeltaTime;
if (time <= 0)
{
time = timeInitiale + coolDown;
StartCoroutine(CoolDown());
}
}
IEnumerator CoolDown()
{
lineRenderer.enabled = false;
yield return new WaitForSeconds(coolDown);
lineRenderer.enabled = true;
}
}
Answer by TreyH · Nov 20, 2019 at 10:00 PM
I'll help with the math / rotations then let you handle the incorporation. :-)
So a deflected ray (B) will depend on the ray itself (A) and normal of whatever surface it hits (N). If you know both of those values, then you can find a rotation such that A gets rotated to become N. Conveniently, we can apply that same rotation to N to get our B.
Unity makes this pretty straightforward with how it defines quaternion multiplication on vectors:
public class RayPointer : MonoBehaviour
{
// Update is called once per frame
void Update()
{
// Camera is straight for this example, so this is simple
var mouse = Camera.main.ScreenToWorldPoint(Input.mousePosition);
var delta = mouse - this.transform.position;
var ray = new Ray2D(this.transform.position, delta);
Debug.DrawLine(ray.origin, mouse, Color.red, 0f);
var hit = Physics2D.Raycast(ray.origin, ray.direction);
if (hit)
{
// Get a rotation to go from our ray direction (negative, so coming from the wall),
// to the normal of whatever surface we hit.
var deflectRotation = Quaternion.FromToRotation(-ray.direction, hit.normal);
// We then take that rotation and apply it to the same normal vector to basically
// mirror that angle difference.
var deflectDirection = deflectRotation * hit.normal;
Debug.DrawRay(hit.point, deflectDirection, Color.magenta, 0f);
}
}
}
I added that to the red cube in a scene and pointing my mouse at a large 2D wall nearby, which gives something like:
Okay I see, thank you! I had absolutely not thought of this solution ;)
Your answer
Follow this Question
Related Questions
2d platformer knockback without addforce 1 Answer
Help with Layer mask to not detect player hitbox 0 Answers
Bouncing laser, wierd flickering 0 Answers
2D How to reflect a raycast with a line renderer 0 Answers
Issue with 2D raycast 0 Answers