Я пытаюсь создать игру, в которой нужно стрелять лазером по объектам и отражать его от объектов, но кажется, что иногда лазер проходит сквозь объекты. Я заметил, что второй луч будет заканчиваться в начале сцены, а не отражаться от объекта, даже если это означает прохождение через объект.
Вот изображение того, что я имею в виду:Иногда он отражается от объекта, но все равно проходит через начало координат.
Это мой код для размышлений:
if (hit.collider.gameObject.tag == "Reflect"){
hit2 = Physics2D.Raycast(hit.point, -hit.point); //The problem is probably here
Debug.DrawLine(hit.point, hit2.point);
lineRenderer.SetPosition(2, hit2.point);
}
Я пробовал использовать метод Vector2.Reflect, но он делает то же самое. Я пробовал использовать hit.normal, но это тоже не работает. Я также пробовал использовать луч и устанавливать направление, противоположное направлению луча, но это не сработало.





определенно есть более совершенный способ, но я бы это сделал вот как. вам нужно знать, как нарисовать луч. Точка отражения и угол отражения. вы можете снять два других рейкаста с небольшим изменением угла от вашего источника и получить угол по этим точкам.
так по шагам
1- сделайте рейкаст, получите позицию точки попадания и назовите ее P
2- сделайте еще два рейкаста с отклонением примерно на один градус в обоих направлениях и назовите точки попадания A и B.
3- вычислите угол вектора между A и B (используйте Vector2.angle) и выполните лучевой анализ по этому углу из точки P.
Я не уверен, что понимаю, что вы пытаетесь сделать с помощью «hit2». Насколько я понимаю, вы хотите, чтобы ваш лазер отражался от объекта следующим образом:
По сути, вам нужно получить точку попадания и использовать hit.normal, чтобы получить направление отражения луча. Это делается путем передачи их в Vector2.Reflect().
Чтобы получить очки для рендеринга линий, вы назначаете им hit.point и проходите по нему столько раз, сколько вы хотите, чтобы ваш лазер отражал. Я создал его для вас, но рекомендую вам потратить некоторое время на понимание того, что он делает, прежде чем использовать его. Убедитесь, что Line Renderer является дочерним объектом объекта, содержащего скрипт:
[SerializeField] private LineRenderer lineRenderer;
[SerializeField] private float laserMaxLength = 2f;
[SerializeField] private int laserMaxHits = 5;
private void Start()
{
//This is to stop a raycast from inside a collider from hitting said collider
//(risk of happening with the "reflected" raycasts):
Physics2D.queriesStartInColliders = false;
}
void Update()
{
RaycastHit2D[] hits = new RaycastHit2D[laserMaxHits];
Vector3[] linePoints = new Vector3[hits.Length + 1];
float laserLength = laserMaxLength;
Vector2 laserDirection = transform.right;
hits[0] = Physics2D.Raycast(transform.position, laserDirection, laserLength);
linePoints[0] = Vector2.zero;
for (int i = 0; i < hits.Length; i++)
{
if (hits[i])
{
if (hits[i].collider.gameObject.tag == "Reflect")
{
//Part of the max length of the laser is used:
laserLength -= hits[i].distance;
//Get the reflect direction from the hit normal:
laserDirection = Vector2.Reflect(laserDirection, hits[i].normal);
//Assign a point on the linerenderer where the ray hit:
linePoints[i + 1] = transform.InverseTransformPoint(hits[i].point);
//New raycast for evey bounce, except for the last hit
//possible (to avoid running out of array):
if (i != hits.Length-1)
{
hits[i + 1] = Physics2D.Raycast(hits[i].point, laserDirection , laserLength);
}
Debug.DrawRay(hits[i].point, laserDirection, Color.blue);
} else
{
//Hit a collider that is non non-reflective
linePoints[i + 1] = transform.InverseTransformPoint(hits[i].point);
//Make sure the lineRenderer has enough points to draw the entire laser:
lineRenderer.positionCount = i + 2;
break;
}
} else
{
//End of laser did not hit anything
linePoints[i + 1] = (Vector2)linePoints[i] + laserDirection * laserLength;
//Make sure the lineRenderer has enough points to draw the entire laser:
lineRenderer.positionCount = i + 2;
break;
}
}
//Assign the found point to the line renderer:
lineRenderer.SetPositions(linePoints);
}
Удачи, пиу пиу!
@MartinAnderson работать с указаниями - это головная боль. Я изучил это немного больше и обнаружил, что идеальная функция для отражений уже существует, она называется Vector2.Reflect() ! Я отредактировал сообщение выше, приведя пример того, как отображать точки, полученные лучом, и отражать их с помощью средства рендеринга линий.
Мне удалось использовать это в своем сценарии и заставить его работать, установив для параметра lineRenderer.useWorldSpace значение false. Спасибо.
Функция Debug.DrawLine работает так, как я хочу, но как мне заставить средство рендеринга линий соответствовать этому?