@Wonder3ful

Как реализовать механику поворота?

Создаю 2D игру и не могу реализовать одну из фундаментальных ее механик. У меня есть машинка, при нажатии игроком в какую либо точку, она едет в сторону прикосновения. Камера следует за машинкой, поэтому она остается в центре экрана и, при этом, видно, что она двигается. Проблема в том, что машинка должна еще и вращаться, то есть, поворачиваться в ту сторону, куда едет. Я знаю, что можно было сначала реализовать поворот, а потом через transform.forward ее движение вперед, но я сделал так как сделал. Так вот, я не знаю как заставить машинку поворачиваться, я пробовал искать угол между одной из осей и вектором, по которому двигается машинка, но у меня не вышло. Я возился с кватернионами, многими методами, связанными с углами и прочими вещами, но ничего не получилось, так что, помогите пожалуйста.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class motion : MonoBehaviour
{

    public int speed = 5;
    public GameObject cam;
    public GameObject car;
    void Update()
    {



        Rigidbody2D rb = GetComponent<Rigidbody2D>();
        Vector2 a = GetComponent<Transform>().position;
        Vector2 b = cam.GetComponent<Transform>().position;
        Vector2 c = a - b;
        Rigidbody2D rbc = cam.GetComponent<Rigidbody2D>();
        rbc.velocity = c * 20;

        if (Input.touchCount > 0)
        {
            rb.velocity = new Vector2(0, 0);
            Vector2 o = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position);
            if ((Mathf.Abs(o.x - cam.GetComponent<Transform>().position.x) >= 0.4f) || (Mathf.Abs(o.y - cam.GetComponent<Transform>().position.y) >= 0.4f))
            {
                Vector2 x = GetComponent<Transform>().position;
                Vector2 z = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position);
                Vector2 s = z - x;
                s.Normalize();
                
                rb.velocity = s * speed;
                s = new Vector2(0, 0);
            }

        }    
        
        else if (Input.touchCount < 1)
        {
            rb.velocity = new Vector2(0, 0);
        }
    }
}

628a9d933dd56455849488.png
  • Вопрос задан
  • 166 просмотров
Решения вопроса 1
EveningEugene
@EveningEugene
Unity-разраб
Если вам нужен мгновенный поворот машинки, то вам подойдёт Transform.LookAt
Если нужен плавный во времени поворот, то вдобавок ещё и это Vector3.RotateTowards. Туда можно передавать и Vector2.

UPD: LookAt для 2д не годится, предложил по сути на основании догадки, так как в 3д работало. Но за 2 минуты нагуглил рабочий способ по запросу "unity 2d rotate sprite {принять гугловское автодополнение запроса} towards mouse":
float angle = Mathf.Atan2(target.position.y - transform.position.y, target.position.x - transform.position.x) * Mathf.Rad2Deg;
            transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle));

Лично создал тестовый проект - проверил, работает. Важный нюанс - спрайт машинки должен быть повёрнут по умолчанию вправо,
пример:
628b6652f239e206690280.png

Вывод: учитесь гуглить. Это азы. С плавным, не мгновенным, поворотом разберётесь сами.

UPD2: Хотя, всё же спрайт не обязательно должен быть повёрнут вправо. Просто учитывайте, что приведённый код предназначен для повёрнутых направо. Если ваши спрайты изначально нарисованы передом вверх то просто вычтите 90 из angle. Или прибавьте 90, если спрайт почему-то повёрнут вниз. Но самое главное, если вы используете несколько разных спрайтов - то у них у всех должна быть одинаковая изначальная ориентация.
transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle));// спрайт, повёрнутый вправо
transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle - 90));// спрайт, повёрнутый вверх
transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle + 90));// спрайт, повёрнутый вниз
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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