#.net #math #rotation #monogame #angle
Вопрос:
Здравствуйте, я разрабатываю игру в моноигре на c#, и у меня возникли проблемы со сбросом камеры обратно за плеер.
Когда игрок удерживает щелчок левой кнопкой мыши, он может вращать камеру вокруг своего персонажа. Когда он двигается вперед, камера медленно возвращается назад за его спиной. Вращение должно решить, следует ли ему вращаться влево или вправо вокруг игрока, чтобы оказаться позади игрока (кратчайший путь). В данный момент он иногда вращается по длинной орбите вокруг игрока, и, что хуже всего, ток застрянет между 1 и -1 и будет двигаться вперед и назад очень быстро, как будто он застрял.
double targetY; //this is the radians Y our camera is going to slowly rotate to
double currentY; //this is our current camera radians Y
float rotateSpeed = 5; //this value lets us slow down how fast we rotate towards targetY
double direction = Math.Cos(targetY) * Math.Sin(currentY) - Math.Cos(currentY) * Math.Sin(targetY);
double distance = Math.Min(currentY - targetY, (MathHelper.Pi * 2) - currentY - targetY);
if (direction > 0)
{
//rotating left towards targetY
currentY -= distance / rotateSpeed;
}
else
{
//rotating right towards targetY
currentY = distance / rotateSpeed;
}
Я полагаю, что это проблема с тем, чтобы не использовать математику.PI, чтобы выяснить, должен ли он вращаться влево или вправо, но я не смог его решить.
Спасибо.
Обновить:
Поэтому я был занят, пытаясь решить эту проблему, и я решил, что уже знаю поворот цели с помощью targetY, поэтому я просто заставляю CurrentY медленно поворачиваться к цели, используя приведенный ниже код.
if (currentY < targetY)
{
//simply add currentY by the distance between currentY and targetY / divide it by how slow you want to rotate.
currentY = (targetY - currentY) / rotateSpeed;
}
if (currentY > targetY)
{
//simply minus currentY by the distance between currentY and targetY / divide it by how slow you want to rotate.
currentY -= Math.Abs(targetY- currentY) / rotateSpeed;
}
Этот новый код работает нормально, единственная проблема заключается в том, что если игрок вращается вокруг выделенного места, то я позволяю камере заходить за игрока после того, как он вращался, камера вращается примерно столько же раз, пока не достигнет поворота игроков. Я думаю, что для решения этой проблемы мне нужно ограничить вращение плеера и камер между 0 радианами и 6.28319 радианами, но тогда новый приведенный выше код не будет работать, потому что он должен иметь дело с переходом с 6.28319 на 0, и это нарушит его.
Спасибо.
Обновление № 2
Все еще занят, пробуя это до сих пор, новый код теперь правильно поворачивается между 360 градусами и 0 градусами. Но теперь мне нужно заставить его работать на 180 градусов в тот момент, когда камера будет вращаться со 170 градусов до -190 (заставляя камеру поворачиваться на 360 градусов на 360 градусов в другую сторону), вместо этого она должна вращаться со 170 градусов до 160 градусов, а также все еще вращаться с 360 градусов до 0 градусов, вот мой код до сих пор.
float newRotation = targetY;
if (targetY < MathHelper.ToRadians(180) amp;amp; currentY > MathHelper.ToRadians(180))
{
newRotation = targetY MathHelper.ToRadians(360);
}
if (targetY > MathHelper.ToRadians(180) amp;amp; currentY < MathHelper.ToRadians(180))
{
newRotation = targetY - MathHelper.ToRadians(360);
}
if (currentY < newRotation)
{
currentY = (newRotation - currentY) / rotateSpeed;
}
if (currentY > newRotation)
{
currentY -= Math.Abs(newRotation - currentY) / rotateSpeed;
}
Спасибо.
Ответ №1:
Я решил проблему, приведенный ниже код будет вращаться от 360 градусов до 0 градусов, он также вращается от 170 градусов до 160 градусов, только если это поможет кому-то другому.
float newRotation = targetY;
if (targetY < MathHelper.ToRadians(90) amp;amp; currentY > MathHelper.ToRadians(270))
{
newRotation = targetY MathHelper.ToRadians(360);
}
if (targetY > MathHelper.ToRadians(270) amp;amp; currentY < MathHelper.ToRadians(90))
{
newRotation = targetY - MathHelper.ToRadians(360);
}
if (currentY < newRotation)
{
currentY = (newRotation - currentY) / rotateSpeed;
}
if (currentY > newRotation)
{
currentY -= Math.Abs(newRotation - currentY) / rotateSpeed;
}
Я также запретил игроку постоянно увеличивать или уменьшать свои градусы, когда он вращается, используя приведенный ниже код как для камеры, так и для проигрывателя.
if (currentY >= MathHelper.Pi * 2) currentY = 0.0f;
if (currentY < 0) currentY = MathHelper.Pi * 2;