@Jrtq

Из-за чего ломается скрипт?

Если добавить 1 строку, то скрипт не будет выполняться, хотя ошибок нет.
Этот скрипт создаёт луч, который может отражаться от поверхностей.

Надеюсь на вашу помощь, бьюсь над этим 2 дня. Готов послушать предложения, как дать лучам общий коллайдер другим способом, либо уточнить, что не понятно.

public class Light : MonoBehaviour
{
    public int DefaultLenght = 10;  // длина луча, если он никуда не попал
    public int MaxReflectionCount = 5;  // сколько раз луч может отражаться

    private List<Vector3> _hitPoints = new List<Vector3>(); // массив точек, между которыми будет линия
    private LineRenderer _lineRenderer;
    void Awake()
    {
        _lineRenderer = GetComponent<LineRenderer>(); 
    }

    void Update()
    {
        RaycastWithReflection();
    }

    private void RaycastWithReflection()
    {
        _hitPoints.Clear(); // очищение точек, чтобы на новый кадр можно было переместить линию
        _hitPoints.Add(transform.position); // добавление стартовой точки в массив

        Ray2D ray2D = new Ray2D(transform.position, transform.right);

        while (_hitPoints.Count <= MaxReflectionCount) // линия будет отражаться, пока не достигнет максимального значения отражений
        {
            RaycastHit2D hitInfo = Physics2D.Raycast(ray2D.origin, ray2D.direction, 10); // информацию  о коллайдерах, с которыми столкнулся RayCast, в переменную


            if (hitInfo.collider.CompareTag("Mirror")) // если луч столкнулся с зеркалом, то линия отразится
            {
                _hitPoints.Add(hitInfo.point);
                LightCollider.colliderPositions.Add(hitInfo.point); // та самая стока, из-за которой скрипт не выполняется, зачем она нужна - под кодом

                ray2D.origin = hitInfo.point - ray2D.direction * 0.01f;
                ray2D.direction = Vector2.Reflect(ray2D.direction, hitInfo.normal);
            }
            else if (hitInfo.collider.CompareTag("Untagged")) // если столкнулся с обычной стеной, то луч прерывается
            {
                _hitPoints.Add(hitInfo.point);
                LightCollider.colliderPositions.Add(hitInfo.point);
            }
            else // если луч никуда не попал, то его длина равняется DefaultLenght
            {
                _hitPoints.Add(ray2D.origin + ray2D.direction * DefaultLenght);
                LightCollider.colliderPositions.Add(ray2D.origin + ray2D.direction * DefaultLenght);
            }
        }

        _lineRenderer.positionCount = _hitPoints.Count;
        _lineRenderer.SetPositions(_hitPoints.ToArray()); // наконец, отрисовка самого луча
    }
}


Помимо самих лучей (их несколько) мне нужен коллайдер на них, при чём общий
Поэтому я в отдельном скрипте рисую PolygonCollider2D:

public class LightCollider : MonoBehaviour
{
    public static List<Vector2> colliderPositions; // вершины коллайдера, они помещаются сюда из прошлого скрипта
    private PolygonCollider2D _collider;

    private void Awake()
    {
        _collider = GetComponent<PolygonCollider2D>();
    }

    private void Update()
    {
        colliderPositions.Clear();
        colliderPositions.Add(transform.position);

        _collider.SetPath(0, colliderPositions); // отрисовка коллайдера
    }
}


Вот для этого и нужна ломающая всё строка LightCollider.colliderPositions.Add(hitInfo.point), она помещает точку в переменную из другого скрипта, чтобы отрисовать коллайдер
Я пробовал убирать скрипт LightCollider, чтобы он не влиял на результат, и удалять 37 строку. В первом случае ничего не поменялось, а во втором скрипт заработал.
  • Вопрос задан
  • 182 просмотра
Пригласить эксперта
Ответы на вопрос 1
@Ezekiel4
Охотник на пиратов и сборщик монолитов
Ошибка в использовании пустой ссылки:
// вместо
public static List<Vector2> colliderPositions;

// напишите
public static List<Vector2> colliderPositions = new List<Vector2>();


Это не связано с вашим вопросом, но есть ещё одна ошибка. Перед тем как проверять "с чем луч столкнулся", стоит проверить, а столкнулся ли он вообще хоть с чем-то.
if (hitInfo.collider == null) {
	// то же как в блоке else
} else if (hitInfo.collider.CompareTag("Mirror")) {
// ... ну и так далее
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы