- Home /
Help with reflecting in 2D.
I've been trying to create a little lasers and mirrors with the goal being get a laser past obstacles to a receiver and have been trying to get the reflecting down. To help I put a line gizmo to help me visualize things so i can just slap on a line renderer once I iron it out. I've been trying to do it recursively and i'm sure i'm close but i'm struggling to figure it out. Here is what i got:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyLaser3 : MonoBehaviour
{
public int maxReflectionCount = 5;
public float maxStepDistance = 200;
private void OnDrawGizmos()
{
drawPredictedReflection(this.transform.position, this.transform.up, maxReflectionCount);
}
void drawPredictedReflection(Vector2 position, Vector2 direction, int reflectionsRemaining)
{
if (reflectionsRemaining <= 0)
{
return;
}
Vector2 startingPos = position;
RaycastHit2D hit2D = Physics2D.Raycast(startingPos, this.transform.up, maxStepDistance);
if (hit2D) //if we hit somthing reflect, else just keep going
{
direction = Vector2.Reflect(direction, hit2D.normal);
position = hit2D.point;
Debug.Log(direction);
}
else
{
position += direction * maxStepDistance;
}
Gizmos.color = Color.yellow;
Gizmos.DrawLine(startingPos, position);
drawPredictedReflection(position, direction, reflectionsRemaining - 1);
}
}
Let me know your thoughts/improvements or if i'm way off and to try a different way.
Answer by TreyH · Jan 11, 2020 at 02:27 PM
Your math looks and ended up being fine. One issue you might've bumped into was your use of:
position = hit2D.point;
for assigning the next ray source. This seems fine and it's right geometrically, but you end up with weird behavior from firing a new ray from the surface of a collider that it's also allowed to strike. You'll get a weird floating point situation where sometimes it will hit it and sometimes it won't.
In your case, you'd expect that you won't. To adjust for that, I added a portion of the next ray's direction to its starting position. This fixed the clipping issue and got the expected behavior:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RayReflect : MonoBehaviour
{
public int maxReflectionCount = 5;
public float maxStepDistance = 200;
void OnDrawGizmos()
{
if (!Application.isPlaying)
return;
var source = this.transform.position;
var xyPlane = new Plane(Vector3.forward, source);
var cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition);
if (xyPlane.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out float enter))
{
var worldCursor = cameraRay.GetPoint(enter);
var direction = (worldCursor - source).normalized;
this.DrawPredictedReflection(source, direction, this.maxReflectionCount);
}
}
void DrawPredictedReflection (Vector2 position, Vector2 direction, int reflectionsRemaining)
{
var gizmoHue = (reflectionsRemaining / (this.maxReflectionCount + 1f);
Gizmos.color = Color.HSVToRGB(gizmoHue, 1, 1);
RaycastHit2D hit2D = Physics2D.Raycast (position, direction, maxStepDistance);
if (hit2D && hit2D.collider) //if we hit somthing reflect, else just keep going
{
Gizmos.DrawLine (position, hit2D.point);
Gizmos.DrawWireSphere(hit2D.point, 0.25f);
direction = Vector2.Reflect (direction, hit2D.normal);
position = hit2D.point + direction * 0.01f;
}
else
{
Gizmos.DrawLine (position, position + direction * maxStepDistance);
position += direction * maxStepDistance;
}
Gizmos.color = Color.white;
if (reflectionsRemaining > 0)
DrawPredictedReflection (position, direction, --reflectionsRemaining);
}
}
Thank you for this! Your assumption was absolutely correct and and now its working as intended.
Your answer
![](https://koobas.hobune.stream/wayback/20220612221354im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
How can i normalize 2d Vectors? 2 Answers
Destroy script turns objects into ghosts 2 Answers
Cannot change the value of this integer that I use for array,Cannot change the value of this one. 0 Answers
Use the line renderer for simulate shotgun shoot 1 Answer
How to check if BoxCollider2D collided with another BoxCollider2D? 2 Answers