Я управляю вращением объекта с помощью функции 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;
}
глобальная ось Y или локальная ось Y?
локальная ось Y. Просто x и z моего объекта не должны быть затронуты. Прямо сейчас я использую функцию LateUpdate(), чтобы не затрагивать x и z, но я ищу лучшие решения.
Вы нашли решение этой проблемы? Если мой ответ помог, пожалуйста, примите его.
Нужен другой подход. Вместо того, чтобы сохранять направление, указывающее ваше начальное смещение, сохраняйте угол со знаком к локальному форварду от определенного направления, связанного с мячом, повернутого вокруг локального вверх. Это конкретное направление является направлением мяча, спроецированного на плоскость, перпендикулярную роботу вверх, или, другими словами, «сплющенную», так что он больше не находится локально выше или ниже робота.
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);
}
Вы можете изменить вращение.x или .y или .z с помощью Lerp и a и просто изменить значение