Всем привет. Эта статья будет посвящена написанию предугадывания траектории мяча в Unity. Версия Unity 2019.0.6f

Для отрисовки линии мы будем использовать LineRenderer.

Для начала подготовим LineRenderer:



Что нужно изменить:

  1. Толщина линии
  2. Цвет линии
  3. Материал

Для отрисовки LineRenderer в 2D необходимо создать материал с «Sprite/Default» шэйдером:



Создадим скрипт BallTrajectory и определим необходимые поля.

Определение полей
public class TrajectoryRenderer : MonoBehaviour
{
      [SerializeField] LineRenderer lineRenderer; //Ссылка на LineRenderer
      [SerializeField] int lineCount; //Количество линий, чем больше, тем более гладкая получиться линия
      [SerializeField] float lineLenght; //Длинна линии
      [SerializeField] Ball ball; //Ссылка на класс мяча
}


На старте зададим необходимое количество точек для LineRenderer.

private void Start()
{
      lineRenderer.positionCount = lineCount;
}

В дальнейшем будем писать код в функции Update.

Для начала нужно определить позицию мыши в текущем кадре в мировых координатах, для этого будем использовать метод ScreenToWorldPoint класса камера.

Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

После необходимо найти вектор-нормаль, исходящий из центра мяча, и направленный к позиции мыши.
Vector2 direction = mousePos - (Vector2)transform.position;
direction.Normalize();

Дальше нужно определить вертикальную и горизонтальную составляющую скорости мяча.

Создадим класс мяча. В нем определим его скорость, и по отжатию правой кнопки мыши будет запускать мяч в сторону позиции мыши с заданной скоростью.

Скрипт мяча
public class Ball : MonoBehaviour
{
    Rigidbody2D rb;
    [SerializeField] float velocityScaler;
    public float velocity;
 
    Vector2 mousePos;
 
    private void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }
 
    private void Update()
    {
        mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        velocity = Vector2.Distance(transform.position, mousePos) * velocityScaler;
 
        if (Input.GetMouseButtonUp(0))
        {
            Vector2 direction = (mousePos - (Vector2)rb.transform.position);
            direction.Normalize();
            rb.velocity = direction * velocity;
        }
    }
}


Определение скоростей мяча
var vx = ball.velocity * direction.x;
var vy = ball.velocity * direction.y;


И в завершение, нам нужно пройтись по всем точкам нашего LineRenderer и определить их положение в соответствии с полученными данными.

Определение позиций точек
for (int i = 0; i < lineCount; i++)
{
      float t = i * lineLenght;
      var nextPos = new Vector2(vx * t, vy * t - (-Physics2D.gravity.y * t*t) / 2);
      lineRenderer.SetPosition(i, (Vector2)transform.position + nextPos);
}


Полный код можно посмотреть

здесь
public class BallTrajectory : MonoBehaviour
{
      [SerializeField] LineRenderer lineRenderer;
      [SerializeField] int lineCount;
      [SerializeField] float lineLenght;
      Ball ball;
 
      private void Start()
      {
            ball = GetComponent<BallController>();
            lineRenderer.positionCount = lineCount;
      }
 
      private void Update()
      {
            Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            Vector2 direction = mousePos - (Vector2)transform.position;
            direction.Normalize();
 
            var vx = ball.velocity * direction.x;
            var vy = ball.velocity * direction.y;
 
            for (int i = 0; i < lineCount; i++)
            {
                  float t = i * 0.1f;
                  var nextPos = new Vector2(vx * t, vy * t - (-Physics2D.gravity.y * t*t) / 2);
                  lineRenderer.SetPosition(i, (Vector2)transform.position + nextPos);
            }
      }
 
}


Скриншоты



За спрайты скажем спасибо looneybits.