Используйте Lerp Position и Slerp Rotation вместе (Unity)
Это то, что я пытаюсь сделать, когда я нажимаю на элемент пользовательского интерфейса, камера плавно поворачивается (чтобы посмотреть на цель) и одновременно перемещается поверх цели.
Для этого я использую два сопрограммы, один для позиции Lerp, а другой для вращения Slerp.
Проблема в том, что вращение не работает должным образом, обычно камера должна смотреть вниз, чтобы увидеть верх цели, но вместо этого она выглядит так, как будто камера сначала смотрит на цель, а затем перемещается в ее положение.
Надеюсь это понятно;)
Вот код с #
Vector3 LocationProjectForPos = new Vector3(Loc_X, 100, Loc_Z);
Vector3 LocationProjectForRot = new Vector3(Loc_X, Loc_Y, Loc_Z);
Vector3 MainCameraPos = MainCamera.transform.position;
if(!IsCameraMoving & LocationProjectForPos != MainCameraPos)
{
StartCoroutine (CoroutineMovePositionCamera(LocationProjectForPos));
StartCoroutine (CoroutineMoveRotationCamera(LocationProjectForRot));
}
}
Перемещение положения камеры с помощью Lerp
public IEnumerator CoroutineMovePositionCamera(Vector3 LocationProject)
{
float lerpTime = 5f;
float currentLerpTime = 0f;
IsCameraMoving = true;
Vector3 startPos = MainCamera.transform.localPosition;
Vector3 endPos = LocationProject;
while (lerpTime > 0)
{
lerpTime -= Time.deltaTime;
currentLerpTime += Time.deltaTime;
if (currentLerpTime > lerpTime)
{
currentLerpTime = lerpTime;
}
float t = currentLerpTime / lerpTime;
t = t*t*t * (t * (6f*t - 15f) + 10f);
//t = t*t * (3f - 2f*t);
//t = 1f - Mathf.Cos(t * Mathf.PI * 0.5f);
MainCamera.transform.localPosition = Vector3.Lerp(startPos, endPos, t);
yield return null;
}
IsCameraMoving = false;
}
Поверните камеру с помощью Slerp
public IEnumerator CoroutineMoveRotationCamera(Vector3 LocationProject)
{
float lerpTime = 5f;
float currentLerpTime = 0f;
IsCameraMoving = true;
Vector3 relativePos = LocationProject - MainCamera.transform.localPosition;
Quaternion rotation = Quaternion.LookRotation(relativePos);
Quaternion current = MainCamera.transform.localRotation;
while (lerpTime > 0)
{
lerpTime -= Time.deltaTime;
currentLerpTime += Time.deltaTime;
if (currentLerpTime > lerpTime)
{
currentLerpTime = lerpTime;
}
float t = currentLerpTime / lerpTime;
t = t*t*t * (t * (6f*t - 15f) + 10f);
//t = t*t * (3f - 2f*t);
//t = 1f - Mathf.Cos(t * Mathf.PI * 0.5f);
MainCamera.transform.localRotation = Quaternion.Slerp(current, rotation, t);
yield return null;
}
IsCameraMoving = false;
}
Спасибо за вашу помощь.
2 ответа
В CoroutineMoveRotationCamera вам необходимо обновить относительное положение и вращение внутри цикла while.
Относительное положение меняется во время движения камеры. Прямо сейчас ваша камера вращается на основе векторного снимка, сделанного вами до начала цикла while.
Добавьте следующий код после оператора yield.
relativePos = LocationProject - Camera.main.transform.position;
rotation = Quaternion.LookRotation(relativePos);
Перед запуском сопрограммы, вы должны сохранить начальные переменные с членами-членами вместо функции локальных переменных