Как правильно двигать объекты по нарисованным линиям?

Форум для самых маленьких, а так же тех, кому недосуг читать справку самостоятельно.

Как правильно двигать объекты по нарисованным линиям?

Сообщение Sice 19 мар 2023, 21:13

Добрый день. У меня есть 4 переменные-префаба, которые рисуют линии с помощью LineRenderer, я хочу запускать 4 объекта по линиям (по цветам), а вернее по точкам Poistion который создаёт LineRenderer, чтобы каждый объект (цвет), передвигался по своей линии.

Делаю так:
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DrawManager : MonoBehaviour
{
    private Camera _cam;
    [SerializeField] private Line1 LineYellow, LineBlue, LineGreen, LineRed;
    [SerializeField] private GameObject CarYellow, CarBlue, CarGreen, CarRed;
    private List<Vector3> linePointsBlue = new List<Vector3>(), linePointsYellow = new List<Vector3>(), linePointsRed = new List<Vector3>(), linePointsGreen = new List<Vector3>();

    public bool startDrive = false;
    public float speed = 10f, rotationSpeed = 20f;
    private int targetPointIndex;
    private Vector3 targetPoint;
    public const float RESOLUTION = .2f;
    private Line1 _currentLine;
    private bool _isDrawing = false, canDrawBlue = true, canDrawYellow = true, canDrawGreen = true, canDrawRed = true;
    private string carFlag = "";

    void Start()
    {
        _cam = Camera.main;
    }

    void Update()
    {
        Vector2 mousePos = _cam.ScreenToWorldPoint(Input.mousePosition);

        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = _cam.ScreenPointToRay(Input.mousePosition);
            RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction);

            if (hit.collider != null)
            {
                if (hit.collider.name.Contains("Blue") && canDrawBlue)
                {
                    _currentLine = Instantiate(LineBlue, mousePos, Quaternion.identity);
                    _isDrawing = true;
                    carFlag = "Blue";
                }
                else if (hit.collider.name.Contains("Yellow") && canDrawYellow)
                {
                    _currentLine = Instantiate(LineYellow, mousePos, Quaternion.identity);
                    _isDrawing = true;
                    carFlag = "Yellow";
                }
                else if (hit.collider.name.Contains("Green"))
                {
                    Debug.Log("You clicked on a Green car!");
                }
                else if (hit.collider.name.Contains("Red"))
                {
                    Debug.Log("You clicked on a Red car!");
                }
            }
            else
            {
                _isDrawing = false;
            }
        }

        if (Input.GetMouseButtonUp(0) && _isDrawing)
        {
            Ray ray = _cam.ScreenPointToRay(Input.mousePosition);
            RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction);

            if (carFlag == "Blue" && hit.collider != null && hit.collider.name.Contains("Blue") && hit.collider.CompareTag("Parking"))
            {
                Debug.Log("Ok! Blue Parking");
                canDrawBlue = false;

                GameObject lineObject = GameObject.Find("LineBlue [Prefab](Clone)");

                LineRenderer lineRenderer = lineObject.GetComponent<LineRenderer>();

                Vector3[] positions = new Vector3[lineRenderer.positionCount];
                lineRenderer.GetPositions(positions);

                foreach (Vector3 position in positions)
                {
                    // Add the position to the sheet (replace "sheet" with the name of your sheet variable)
                    linePointsBlue.Add(position);
                }
            }
            else if (carFlag == "Yellow" && hit.collider != null && hit.collider.name.Contains("Yellow") && hit.collider.CompareTag("Parking"))
            {
                Debug.Log("Ok! Yellow Parking");
                canDrawYellow = false;
            }
            else
            {
                _currentLine.ClearPositions();
                Destroy(_currentLine.gameObject);
            }

            _isDrawing = false;
        }

        if (Input.GetMouseButton(0) && _isDrawing)
        {
            _currentLine.SetPosition(mousePos);
        }

        if (startDrive) {
            Drive(linePointsBlue, CarBlue);
        }

    }

    private void Drive(List<Vector3> linePoints, GameObject Car) {

        targetPointIndex = 1;      

        targetPoint = linePoints[targetPointIndex];

        Quaternion targetRotation = Quaternion.LookRotation(Vector3.forward, targetPoint - Car.transform.position);
        Car.transform.rotation = targetRotation;

        Car.transform.rotation = Quaternion.Lerp(Car.transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);

        Vector3 direction = (targetPoint - Car.transform.position).normalized;
        Car.transform.position += direction * speed * Time.deltaTime;

        if (Vector3.Distance(Car.transform.position, targetPoint) < 0.1f)
        {
            targetPointIndex++;
            if (targetPointIndex < linePoints.Count)
            {
                targetPoint = linePoints[targetPointIndex];
            }
        }

    }

}
 

И соответственно:
Синтаксис:
Используется csharp
[SerializeField] private Line1 LineYellow, LineBlue, LineGreen, LineRed; // Линии с ЛайнРендерер из скрипта Line 1
[SerializeField] private GameObject CarYellow, CarBlue, CarGreen, CarRed; // Объекты, которые нужно двигать
 

Скрипт Line1.cs:
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Line1 : MonoBehaviour
{
    [SerializeField] private LineRenderer _renderer;

    private readonly List<Vector2> _points = new List<Vector2>();

    public void SetPosition(Vector2 pos)
    {
        if (!CanAppend(pos)) return;

        _points.Add(pos);

        _renderer.positionCount++;
        _renderer.SetPosition(_renderer.positionCount - 1, pos);
    }

    public void ClearPositions()
    {
        _points.Clear();
        _renderer.positionCount = 0;
    }

    private bool CanAppend(Vector2 pos)
    {
        if (_renderer.positionCount == 0) return true;

        return Vector2.Distance(_renderer.GetPosition(_renderer.positionCount - 1), pos) > DrawManager.RESOLUTION;
    }
}
 

В итоге для начала пытаюсь запустить Синий объект он начинает движение по первой точке буквально и на второй останавливается и ничего не происходит. Помогите пожалуйста решить проблему.
Аватара пользователя
Sice
UNIт
 
Сообщения: 87
Зарегистрирован: 25 окт 2014, 13:51

Re: Как правильно двигать объекты по нарисованным линиям?

Сообщение 1max1 20 мар 2023, 01:14

Вполне возможно он он перелетает позицию в этой части:
Синтаксис:
Используется csharp
if (Vector3.Distance(Car.transform.position, targetPoint) < 0.1f)

Попробуй поставить большее число.
Аватара пользователя
1max1
Адепт
 
Сообщения: 5505
Зарегистрирован: 28 июн 2017, 10:51


Вернуться в Почемучка

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 29