- Home /
Updating line positions with reflections
Hello. I am creating a radar simulator and my aim is to make a wave which is reflected from any number of objects with specific tag until it reaches the maximal spread distance run out. I have a couple of questions:
1)How can I check if any reflection has been changed and then redraw the whole wave at runtime? (for example: one or more objects appear or disappear from the line of the original ray or of any of the reflected rays and then the wave redraws)
2)How can I safely add and remove hit points depending on number of reflections? (for example: if there are 3 reflections, there are 3 hit points in the list, if 2, then 2 hit points and etc.)
Here's my code and screenshots:
Before:
After:
using UnityEngine;
using System.Collections.Generic;
[RequireComponent(typeof(LineRenderer))]
public class Irradiator : MonoBehaviour
{
LineRenderer m_Line;
public List<Vector3> HitPoints = new List<Vector3>();
[Range(0, 255)] public float maxSL = 100;//maxSpreadLength.
public float curSL = 0;//curSpreadLength.
[Range(1, 50)] public byte density = 20;
public float ampl = 1;
public float dampC = 0.1f;
public float sprdSpeed = 20;
public float freq = 200;
public float step;
public int maxPointsCount;
public int curPointsCount = 0;
public Vector3 origin;
public Vector3 direction;
public const string dispersingTag = "Surfaces/Dispersing";
public const string reflectingTag = "Surfaces/Reflecting";
public int rayCount = 0;
public float deltaZ = 0;
void Start()
{
m_Line = GetComponent<LineRenderer>();
step = 1 / (float)density;
maxPointsCount = Mathf.CeilToInt(maxSL * density);
}
void FixedUpdate()
{
origin = transform.position;
direction = transform.forward;
m_Line.positionCount = maxPointsCount;
RenderWave(origin, direction, ref curPointsCount, ref curSL, ref rayCount);
}
void RenderWave(Vector3 orig, Vector3 dir, ref int _curPointsCount, ref float _curSL, ref int rayCount)
{
if (_curSL >= maxSL)
{
Debug.Log("STOPPED");
//Debug.Break();
return;
}
Ray ray = new Ray(orig, dir);
RaycastHit hit;
++rayCount;
Debug.Log("RayCount: " + rayCount);
int curRayPoints = 0;
float curRaySL = 0;
bool h;
Vector3 pos = orig;
Vector3 ortReflected = Vector3.Cross(transform.right, dir);
Vector3 dirReflected = dir;
if (Physics.Raycast(ray, out hit, maxSL - _curSL) && hit.transform.gameObject.tag == reflectingTag)
{
h = true;
HitPoints.Add(hit.point);
curRaySL = hit.distance;
curRayPoints = Mathf.CeilToInt(curRaySL * density);
ortReflected = Vector3.Cross(hit.transform.right, dir).normalized;
Debug.DrawRay(orig, ortReflected, Color.blue);
Debug.DrawRay(orig, dirReflected, Color.red);
}
else
{
h = false;
curRaySL = maxSL - _curSL;
curRayPoints = maxPointsCount - _curPointsCount;
ortReflected = Vector3.Cross(transform.right, dir).normalized;
}
Debug.Log("curRaySL: " + curRaySL);
Debug.Log("curRayPoints: " + curRayPoints);
Debug.DrawRay(orig, dir * curRaySL, Color.red);
for (int i = _curPointsCount; i < _curPointsCount + curRayPoints; i++)
{
Vector3 p = pos + ampl * Mathf.Exp(-dampC * deltaZ) * Mathf.Sin(Mathf.PI + freq * deltaZ / sprdSpeed) * ortReflected;
Debug.Log("Point [" + i + "] = " + p);
m_Line.SetPosition(i, p);
pos += dirReflected * step;
deltaZ += step;
}
_curSL += curRaySL;
_curPointsCount += curRayPoints;
if (h == true)
{
dirReflected = Vector3.Reflect(dirReflected, hit.normal);
ortReflected = Vector3.Reflect(ortReflected, hit.normal);
Debug.DrawRay(hit.point, dirReflected, Color.magenta);
Debug.DrawRay(hit.point, ortReflected, Color.cyan);
}
Debug.Log("_curPointsCount: " + _curPointsCount);
Debug.Log("_curSL: " + _curSL);
RenderWave(hit.point, dirReflected, ref _curPointsCount, ref _curSL, ref rayCount);
}
}
Im not entirely sure what you mean. Surely if you are casting a ray and using it to calculate the reflection the mere act of doing it at a certain rate will automatically propagate those changes.
I mean that if an obstacle is removed or moved away from raycast, then it doesn't automatically propagate those changes. As you can see, I have a function which calls itself to create a new ray, calculate points and etc.
Answer by sacredgeometry · Aug 25, 2019 at 10:46 AM
Video
public class Laser : MonoBehaviour
{
public Transform Emitter;
void FixedUpdate()
{
CastReflectedRay(Emitter.position, Emitter.forward);
}
void CastReflectedRay(Vector3 position, Vector3 reflection)
{
if (Physics.Raycast(position, reflection, out var hit) && hit.transform.tag == "Mirror")
{
Debug.DrawLine(position, hit.point);
var reflectedVector = Vector3.Reflect(reflection, hit.normal);
CastReflectedRay(hit.point, reflectedVector);
}
}
}
Thank you for this answer, but I have to work with thousands of vectors (points), so anyway I have to recode it somehow, because even the start of program causes stackoverflow exception :((( I just have no idea how is it possible to fix it. The points calculation for each ray is right, the reflection is too, but i just really don't know, how to fix it up. Well, thanks again, I will try a few more times to make it work like it should.
You could probably call that hundreds of thousands of times without it causing a stack overflow. Are you sure you are testing for the mirror properly?
Your answer
Follow this Question
Related Questions
Shoot Laser 0 Answers
Line Renderer not showing 0 Answers
How can I make my player unable to jump up walls? 2 Answers
Why are the reflected bullets in my 2D game acting strange? 1 Answer