Как я могу повернуть капсулу, чтобы посмотреть на следующее положение, достигнув текущего положения?

#c# #unity3d

Вопрос:

 using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class WaypointsFollower : MonoBehaviour
{
    public float speed;
    public Waypoints waypoints;
    public Transform capsule;
    public bool go;
    public bool goForward;
    public float rotationSpeed;

    private int index = 0;
    private int counter = 0;
    private int c = 0;
    private List<GameObject> curvedLinePoints = new List<GameObject>();

    public int numofposbetweenpoints;

    private bool getonce;
    private bool getBackwardIndexOnce = true;

    private void Start()
    {
        waypoints = GameObject.Find("Waypoints").GetComponent<Waypoints>();

        curvedLinePoints = GameObject.FindGameObjectsWithTag("Curved Line Point").ToList();

        if(waypoints.moveInReverse == false)
        {
            goForward = true;
        }
        else
        {
            goForward = false;
        }

        if(goForward)
        {
            index = 0;
        }
    }

    private void Update()
    {
        if (getonce == false)
        {
            numofposbetweenpoints = curvedLinePoints.Count;

            getonce = true;
        }

        if (go == true amp;amp; waypoints.lineRendererPositions.Count > 0)
        {
            if(goForward == false amp;amp; getBackwardIndexOnce)
            {
                index = waypoints.lineRendererPositions.Count - 1;

                getBackwardIndexOnce = false;
            }

            Move();
        }
    }

    private void Move()
    {
        Vector3 newPos = transform.position;
        float distanceToTravel = speed * Time.deltaTime;

        bool stillTraveling = true;
        while (stillTraveling)
        {
            Vector3 oldPos = newPos;

            // error exception out of bound on line 55 to check !!!!!
            newPos = Vector3.MoveTowards(oldPos, waypoints.lineRendererPositions[index], distanceToTravel);

            distanceToTravel -= Vector3.Distance(newPos, oldPos);

            if (newPos == waypoints.lineRendererPositions[index]) // Vector3 comparison is approximate so this is ok
            {
                // when you hit a waypoint:
                if (goForward)
                {
                    bool atLastOne = index >= waypoints.lineRendererPositions.Count - 1;
                    if (!atLastOne)
                    {
                        index  ;
                        counter  ;
                        if (counter == numofposbetweenpoints)
                        {
                            c  ;

                            counter = 0;
                        }
                        if (c == curvedLinePoints.Count - 1)
                        {
                            c = 0;
                        }
                    }
                    else { index--; goForward = false; }
                }
                else
                { // going backwards:
                    bool atFirstOne = index <= 0;
                    if (!atFirstOne)
                    {
                        index--;

                        counter  ;
                        if (counter == numofposbetweenpoints)
                        {
                            c  ;

                            counter = 0;
                        }
                        if (c == curvedLinePoints.Count - 1)
                        {
                            c = 0;
                        }
                    }
                    else { index  ; goForward = true; }
                }
            }
            else
            {
                stillTraveling = false;
            }
        }

        transform.position = newPos;
    }

    private void RotateTo()
    {
        // Determine which direction to rotate towards
        Vector3 targetDirection = -capsule.position;

        // The step size is equal to speed times frame time.
        float singleStep = rotationSpeed * Time.deltaTime;

        // Rotate the forward vector towards the target direction by one step
        Vector3 newDirection = Vector3.RotateTowards(capsule.forward, targetDirection, singleStep, 0.0f);

        // Draw a ray pointing at our target in
        Debug.DrawRay(capsule.position, newDirection, Color.red);

        // Calculate a rotation a step closer to the target and applies rotation to this object
        capsule.rotation = Quaternion.LookRotation(newDirection);
    }
}
 

Преобразование движется вдоль путевых точек, но я хочу, чтобы капсула поворачивалась лицом к каждой из промежуточных точек.

Существует множество путевых точек, более или менее 4000, но есть только 10 промежуточных точек. Этот снимок экрана очистит его. Путевые точки-это позиции отправителя строк, а точки numofposbetween-это кубы, которые соединяют каждую линию линий средства визуализации строк.

Четкое изображение

На снимке экрана большой куб-это преобразование в сценарии, в котором преобразование перемещается по линиям ping, которые являются позициями отправителя строк. Маленькие кубики на заднем плане-это точки, в которых соединяются линии отправителя строк.

Я хочу, чтобы капсула плавно вращалась, глядя на точки numofposbetween(маленькие кубики) каждый раз, когда преобразование перемещается, капсула должна плавно вращаться, глядя на следующие точки numofposbetween. есть только 10 точек numofposbetween.

Это часть вращения внизу :

 private void RotateTo()
        {
            // Determine which direction to rotate towards
            Vector3 targetDirection = -capsule.position;
    
            // The step size is equal to speed times frame time.
            float singleStep = rotationSpeed * Time.deltaTime;
    
            // Rotate the forward vector towards the target direction by one step
            Vector3 newDirection = Vector3.RotateTowards(capsule.forward, targetDirection, singleStep, 0.0f);
    
            // Draw a ray pointing at our target in
            Debug.DrawRay(capsule.position, newDirection, Color.red);
    
            // Calculate a rotation a step closer to the target and applies rotation to this object
            capsule.rotation = Quaternion.LookRotation(newDirection);
        }
 

At this line it’s missing the next small cube each time :

 Vector3 targetDirection = -capsule.position;
 

I have the number of small cubes numofposbetweenpoints but how do I get a reference to each small cube and make the numofposbetweenpoints index increase each time?

At line 50 I’m doing :

 numofposbetweenpoints = curvedLinePoints.Count;
 

curvedLinePoints is a List but I’m not sure how to do the rotation to the GameObjects in the List.

This is what I did so far I think the rotation is working but not as I wanted :

At the top I added :

 private int rotationIndex = 0;
 

Затем в повороте я изменяю его на :

 private void RotateTo()
    {
        var distance = Vector3.Distance(capsule.position, curvedLinePoints[rotationIndex].transform.position);
        if(distance < 0.1f)
        {
            rotationIndex  ;
        }

        // Determine which direction to rotate towards
        Vector3 targetDirection = curvedLinePoints[rotationIndex].transform.position -capsule.position;

        // The step size is equal to speed times frame time.
        float singleStep = rotationSpeed * Time.deltaTime;

        // Rotate the forward vector towards the target direction by one step
        Vector3 newDirection = Vector3.RotateTowards(capsule.forward, targetDirection, singleStep, 0.0f);

        // Draw a ray pointing at our target in
        Debug.DrawRay(capsule.position, newDirection, Color.red);

        // Calculate a rotation a step closer to the target and applies rotation to this object
        capsule.rotation = Quaternion.LookRotation(newDirection);
    }
 

Две проблемы :

  1. Даже если я установлю скорость вращения на 30, она все равно будет вращаться довольно медленно. Почему 30 лет-это так медленно ?
  2. Вращение происходит по всей оси, как на этом снимке экрана, но я хочу, чтобы оно вращалось только по оси Y, но поскольку для того, чтобы капсула стояла, я должен установить значение X на -90 при вращении по оси Y, это изменяет масштабирование капсулы, подобное масштабированию. Я хочу, чтобы капсула как бы вращалась сама по себе.

Вращение

Вот как выглядит капсула в оригинале при запуске игры до того, как она начнет вращаться :

Вращение при запуске

Комментарии:

1. Просто для ясности, вы хотите повернуть свой объект в направлении текущего объекта, к которому вы движетесь с той же скоростью? Или хотите сразу перейти к следующему объекту в списке curvedLinePoints , двигаясь к нему?

2. @TEEBQNE, двигаясь к нему. но обратите внимание, что преобразование движется в сторону, но я хочу, чтобы капсула вращалась. Преобразование-это преобразование, которое перемещает капсулу, вращающуюся, к следующему объекту в списке криволинейных точек. Ты понял.

3. @TEEBQNE Обновил мой вопрос тем, что я сделал, каковы результаты и на что я хочу, чтобы это было похоже. У меня две проблемы.

4. Только что вернулся и смог ответить на ваши обновленные вопросы. Дайте мне знать, если вам нужна дополнительная информация/подробности или если второй фрагмент не работает.

Ответ №1:

Чтобы ответить на ваши два недавно добавленных вопроса:

  1. Даже если я установлю скорость вращения на 30, она все равно будет вращаться довольно медленно. Почему 30 лет-это так медленно?

Ваш текущий временной шаг установлен на rotationSpeed * Time.deltaTime . Как вы упомянули, rotationSpeed сейчас 30, но что это Time.deltaTime такое ? Time.deltaTime это количество секунд между кадрами, что означает, что оно составляет 1 / кадровую секунду. Обычно частота кадров составляет ~60, поэтому для примера мы назовем это 1/60 или 0.016666667 . Если умножить на вашу константу 30 , мы получим 30/60 или 0.5 .

Параметр, который вы используете, RotateTowards таков maxRadiansDelta . Из вики этот параметр является:

Максимальный угол в радианах, разрешенный для этого поворота.

Что касается того, почему ваше вращение можно определить как медленное, так это то, что вы движетесь примерно 0.5 со скоростью радиан в секунду. Если вы увеличите это значение с 30 чего-то вроде 60 , вы затем перейдете к 1,0 радианам в секунду и так далее.

  1. Вращение происходит по всей оси, как на этом снимке экрана, но я хочу, чтобы оно вращалось только по оси Y, но поскольку для того, чтобы капсула стояла, я должен установить значение X на -90 при вращении по оси Y, это изменяет масштабирование капсулы, подобное масштабированию. Я хочу, чтобы капсула как бы вращалась сама по себе.

Проблема здесь в том, что RotateTowards ваш объект будет ориентирован по всем осям, чтобы непосредственно принять направление вперед и направить его на преобразование вашей цели. Я верю, что что-то подобное может сработать?

 Vector3 newDirection = Vector3.RotateTowards(capsule.forward, targetDirection, singleStep, 0.0f);

newDirection.z = 0f;

capsule.rotation = Quaternion.LookRotation(newDirection, capsule.Up);
 

Я считаю, что приведенный выше фрагмент должен вращать объект только вокруг оси Y. Дай мне знать, как все пройдет.