Вращение по оси Y Кватернион

Я управляю вращением объекта с помощью функции Quaternion.FromToRotation. Но, к сожалению, он вращается по всем трем осям. Может ли кто-нибудь помочь мне, чтобы я мог вращаться только по оси Y, а x и z не должны быть затронуты?

private Quaternion currentRot;
private Vector3 startPos;
private bool offsetSet;

public GameObject Ball;

void Update()
{
        SetOffsets();
 
        Vector3 closestPoint = Vector3.Normalize(transform.position - Ball.transform.position);
        robot.transform.rotation = Quaternion.FromToRotation(startPos, closestPoint) * currentRot;
    
}

void SetOffsets()
    {
        if (offsetSet)
            return;
 
        startPos = Vector3.Normalize(transform.position - Ball.transform.position);
        currentRot = Ball.transform.rotation;
 
        offsetSet = true;
    }

Вы можете изменить вращение.x или .y или .z с помощью Lerp и a и просто изменить значение

Leoverload 14.12.2020 18:51

глобальная ось Y или локальная ось Y?

Ruzihm 14.12.2020 22:19

локальная ось Y. Просто x и z моего объекта не должны быть затронуты. Прямо сейчас я использую функцию LateUpdate(), чтобы не затрагивать x и z, но я ищу лучшие решения.

Soxehe 15.12.2020 09:14

Вы нашли решение этой проблемы? Если мой ответ помог, пожалуйста, примите его.

Ruzihm 05.01.2021 22:07
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
270
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Нужен другой подход. Вместо того, чтобы сохранять направление, указывающее ваше начальное смещение, сохраняйте угол со знаком к локальному форварду от определенного направления, связанного с мячом, повернутого вокруг локального вверх. Это конкретное направление является направлением мяча, спроецированного на плоскость, перпендикулярную роботу вверх, или, другими словами, «сплющенную», так что он больше не находится локально выше или ниже робота.

private Quaternion startRot; // currentRot is a misleading name
private float startAngleOffset;
private bool offsetSet;

[SerializeField] GameObject Ball;

void SetOffsets()
{
    if (offsetSet)
        return;
 
    Vector3 thisToBall = Ball.transform.position - transform.position;
    Vector3 robotUp = robot.transform.up;
    Vector3 flattenedToBall = Vector3.ProjectOnPlane(thisToBall, robotUp);
    Vector3 startAngleOffset = Vector3.SignedAngle(flattenedToBall, 
            robot.transform.forward, robotUp);
        
    currentRot = Ball.transform.rotation;
 
    offsetSet = true;
}

Затем, когда придет время установить вращение, сделайте еще одну проекцию направления мяча, затем используйте этот угол со знаком, чтобы найти направление вперед, которое должно быть. Затем используйте Quaternion.LookRotation, чтобы установить поворот соответствующим образом.

Всего:

private Quaternion startRot;
private float startAngleOffset;
private bool offsetSet;

[SerializeField] GameObject Ball;

void Update()
{
    SetOffsets();

    Vector3 robotUp = robot.transform.up;
    Vector3 flattenedToBall = GetFlattenedToBall();
    Vector3 robotForwardDir = Quaternion.AngleAxis(startAngleOffset, robotUp)
            * flattenedToBall;

    robot.transform.rotation = LookRotation(robotForwardDir, robotUp);
}


void SetOffsets()
{
    if (offsetSet)
        return;
 
    Vector3 flattenedToBall = GetFlattenedToBall();
    Vector3 startAngleOffset = Vector3.SignedAngle(flattenedToBall, 
            robot.transform.forward, robot.transform.up);
    
    currentRot = Ball.transform.rotation;
 
    offsetSet = true;
}

Vector3 GetFlattenedToBall()
{
    Vector3 thisToBall = Ball.transform.position - transform.position;
    Vector3 flattenedToBall = Vector3.ProjectOnPlane(thisToBall, robot.transform.up);
}

Другие вопросы по теме