Всем привет. Эта статья будет посвящена написанию предугадывания траектории мяча в Unity. Версия Unity 2019.0.6f
Для отрисовки линии мы будем использовать LineRenderer.
Для начала подготовим LineRenderer:
Что нужно изменить:
Для отрисовки LineRenderer в 2D необходимо создать материал с «Sprite/Default» шэйдером:
Создадим скрипт BallTrajectory и определим необходимые поля.
На старте зададим необходимое количество точек для LineRenderer.
В дальнейшем будем писать код в функции Update.
Для начала нужно определить позицию мыши в текущем кадре в мировых координатах, для этого будем использовать метод ScreenToWorldPoint класса камера.
После необходимо найти вектор-нормаль, исходящий из центра мяча, и направленный к позиции мыши.
Дальше нужно определить вертикальную и горизонтальную составляющую скорости мяча.
Создадим класс мяча. В нем определим его скорость, и по отжатию правой кнопки мыши будет запускать мяч в сторону позиции мыши с заданной скоростью.
И в завершение, нам нужно пройтись по всем точкам нашего LineRenderer и определить их положение в соответствии с полученными данными.
Полный код можно посмотреть
За спрайты скажем спасибо looneybits.
Для отрисовки линии мы будем использовать LineRenderer.
Для начала подготовим LineRenderer:
Что нужно изменить:
- Толщина линии
- Цвет линии
- Материал
Для отрисовки 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.