Страница 1 из 1

Вращение объекта на определенный угол

СообщениеДобавлено: 24 сен 2020, 13:36
egorych8
Суть моей задачи в следующем:

Как заставить объект повернуться по оси Y четыре раза относительно какого изначального положения ( -180 до +180).
Думал это просто - добавлять по 90 градусов к изначальному углу и проверять текущий угол. Как только текущий угол станет больше - далее по коду.
Текущий угол < изначальный угол +90
Оказалось, если изначальный угол 91, то 91+90=181, а такого текущего угла не может быть и условие получается вечное.

Есть ли какой-то способ в unity?
Поворачивать с определенной скоростью, но отслеживать время поворота не хочу.

Синтаксис:
Используется csharp
private void Search()
    {
        myAgent.SetDestination(playerPos);
        if (transform.position.x - playerPos.x == 0f)
        {
            if (transform.position.z - playerPos.z == 0f)
            {
                angleSet = transform.eulerAngles.y;
                IsSearch = false;
                IsScan = true;
            }
        }
    }
    private void Scan()
    {
        angle = transform.eulerAngles.y;
        Debug.Log(angle);
        Debug.Log(angleSet);

        if (timeout1 < waitTime)
        {
            timeout1 += Time.fixedDeltaTime;
        }
        else
        {
            if (angle < angleSet + 90)
            {
                transform.Rotate(0, 1f, 0);
            }
            else
            {
                if (timeout2 < waitTime)
                {
                    timeout2 += Time.fixedDeltaTime;
                }
                else
                {
                    if (angle < angleSet + 180)
                    {
                        transform.Rotate(0, 1f, 0);
                    }
                    else
                    {
                        if (timeout3 < waitTime)
                        {
                            timeout3 += Time.fixedDeltaTime;
                        }
                        else
                        {
                            if (angle < angleSet + 270)
                            {
                                transform.Rotate(0, 1f, 0);
                            }
                            else
                            {
                                if (timeout4 < waitTime)
                                {
                                    timeout4 += Time.fixedDeltaTime;
                                }
                                else
                                {
                                    if (angle < angleSet)
                                    {
                                        transform.Rotate(0, 1f, 0);
                                    }
                                    else
                                    {
                                        if (timeout5 < waitTime)
                                        {
                                            timeout5 += Time.fixedDeltaTime;
                                        }
                                        else
                                        {
                                            IsWayPoints = true;
                                            IsScan = false;
                                        }

Re: Вращение объекта на определенный угол

СообщениеДобавлено: 24 сен 2020, 14:28
samana
Ваша цепочка из if else была просто восхитительна, я даже не уверен до сих пор, что это не прикол. :-o

Уточните задачу, вы ведь хотите поворачивать объект постепенно? Например за три секунды он должен повернуться четыре раза вокруг некой оси?
Просто в вашем коде совершенно не видно Update метода. Подозреваю, что под прессингом лестницы, состоящей из if else, метод Update был опущен до глубин ада, откуда не смог выбраться.

Re: Вращение объекта на определенный угол

СообщениеДобавлено: 24 сен 2020, 14:39
egorych8
Объект должен повернуться плавно вокруг оси Y (скажем за 1 секунду) на 90 градусов, потом остановиться на 1 секунду и так четыре раза, что вернёт его в изначальное положение.

Re: Вращение объекта на определенный угол

СообщениеДобавлено: 24 сен 2020, 15:37
Friend123
Самый прикол, что этот код ни разу не сработает. Разница позиций ну очень редко бывает = 0f, что практически нереально.

Ну и цепочка из if'ов - это и правда феноменально )) Почитайте мануальчик, там был пример про поворот, элементарнейший. Накрутить на этот поворот таймер - еще проще.

Re: Вращение объекта на определенный угол

СообщениеДобавлено: 24 сен 2020, 18:07
egorych8
Не могу разобраться почему я задаю - повернуться на 90, а вращение происходит чуть меньше или больше (например 89,99972197; 90,0000597 ) и проверка повернулся ли объект на 90 не работает.
Как обойти эту проблему?


Синтаксис:
Используется csharp
private void Search()
    {
        myAgent.SetDestination(playerPos);
        if (transform.position.x - playerPos.x == 0f)
        {
            if (transform.position.z - playerPos.z == 0f)
            {
                angleSet = transform.rotation.y;
                IsSearch = false;
                IsScan = true;
            }
        }
    }
    private void Scan()
    {
        if (timeout1 < waitTime1)
        {
            timeout1 += Time.fixedDeltaTime;
 
        }
        else
        {
            if (povorot < 5)
            {  
                    Quaternion target = Quaternion.Euler(transform.rotation.x, angleSet + 90, transform.rotation.z);
                    transform.rotation = Quaternion.RotateTowards(transform.rotation, target, Time.fixedDeltaTime * 10);
                   
                    if (transform.rotation.y == angleSet+90)
                    {
                        angleSet = transform.rotation.y;
                        timeout1 = 0;
                        povorot++;
                    }
                           
               
            }
                    Debug.Log(povorot);
                    Debug.Log(angleSet);
        }
    }

Re: Вращение объекта на определенный угол

СообщениеДобавлено: 26 сен 2020, 16:36
egorych8
Никто не знает?

Re: Вращение объекта на определенный угол

СообщениеДобавлено: 26 сен 2020, 16:39
waruiyume
Потому, что float.
Никак.
Флоты на равно не сравнивают, делают что-то в духе Mathf.Abs(a-b)<0.0000001

Re: Вращение объекта на определенный угол

СообщениеДобавлено: 28 сен 2020, 00:36
Friend123
waruiyume писал(а):Потому, что float.
Никак.
Флоты на равно не сравнивают, делают что-то в духе Mathf.Abs(a-b)<0.0000001

Я это написал ему раньше. Собственно, там вообще нужно весь код переписывать.

Re: Вращение объекта на определенный угол

СообщениеДобавлено: 28 сен 2020, 09:11
samana
Да, код конечно лучше сделать более удобным.
Например поворачивать с помощью корутины. Этот скрипт поворачивает объект на 90 градусов 4 раза, то-есть делает полный оборот.
Время поворота и время паузы между поворотами можно настроить.
В данный момент, объект поворачивается вокруг своей локальной оси Y, при нажатии ЛКМ по сцене.
Синтаксис:
Используется csharp
using System.Collections;
using UnityEngine;

public class SomeObject : MonoBehaviour
{
    public float rotationTimeInSec = 1; // время поворота на 90 градусов
    public float pauseTimeInSec = 1; // время паузы между поворотами


    private void Update()
    {
        // при нажатии ЛКМ начинаем круговое вращение
        if (Input.GetMouseButtonDown(0))
        {
            StopAllCoroutines();
            StartCoroutine(turnAroundAxisCoroutine(transform.up));
        }
    }

    private IEnumerator turnAroundAxisCoroutine(Vector3 axis)
    {
        for (int i = 0; i < 4; i++)
        {
            float angle = 90f;
            Quaternion startRotation = transform.rotation;
            Quaternion endRotation = Quaternion.AngleAxis(angle, axis) * startRotation;

            float progress = 0;
            float progressTime = 1f / rotationTimeInSec;

            while (progress < 1)
            {
                transform.rotation = Quaternion.Lerp(startRotation, endRotation, progress);
                progress += progressTime * Time.deltaTime;
                yield return null;
            }

            transform.rotation = endRotation;

            yield return new WaitForSeconds(pauseTimeInSec);
        }
    }

}