Плавное вращение камеры XNA - PullRequest
0 голосов
/ 18 октября 2018

У меня проблема - я говорю проблема, это скорее крайнее неудобство, из-за которого надоело играть.

Я использую XNA Monogame для создания 3D-игры (мучительная работа, в которой было бы легче объединиться, но по причинам, по которой я не могу быть обеспокоен, это не так.) И моя камера предназначена дляустановите мышь игрока в центр окна / окна просмотра, а затем получите изменение движения мыши между этим и следующим кадром, которое будет использоваться для вращения камеры ... Это работало ... Вид.Но теперь, когда я перенес этот проект на ПК, а не на ноутбук, над которым я работал, камера стала очень изменчивой при движении.Я не совсем уверен, как это исправить, я возился с некоторыми значениями из фрагмента кода, который я опубликую, но он больше не работает.Этот компьютер настроен с использованием 3 экранов, если это может быть проблемой?

            if (moveVector != Vector3.Zero)
        {
            //Normalise the vector - to stop us moving faster diagonally
            moveVector.Normalize();
            //Add smooth and speed
            moveVector *= deltaTime * cameraSpeed;

            //Move camera
            Move(moveVector);

        }

        //Handle mouse movement
        float deltaX;
        float deltaY;

        if (currentMouseState != previousMouseState)
        {
            //Save mouse location
            deltaX = currentMouseState.X - (Game.GraphicsDevice.PresentationParameters.BackBufferWidth / 2);
            deltaY = currentMouseState.Y - (Game.GraphicsDevice.PresentationParameters.BackBufferHeight / 2);

            //Determines the speed of the rotation 0.1 is pretty quick and looks just about right
            mouseRotationBuffer.X -= 0.1f * deltaX * deltaTime;
            mouseRotationBuffer.Y -= 0.1f * deltaY * deltaTime;

            if (mouseRotationBuffer.Y < MathHelper.ToRadians(-75.0f))
            {
                mouseRotationBuffer.Y = mouseRotationBuffer.Y - (mouseRotationBuffer.Y - MathHelper.ToRadians(-75.0f));
            }
            if (mouseRotationBuffer.Y > MathHelper.ToRadians(75.0f))
            {
                mouseRotationBuffer.Y = mouseRotationBuffer.Y - (mouseRotationBuffer.Y - MathHelper.ToRadians(75.0f));
            }

            Rotation = new Vector3(-MathHelper.Clamp(mouseRotationBuffer.Y, MathHelper.ToRadians(-75.0f), MathHelper.ToRadians(75.0f)),
                MathHelper.WrapAngle(mouseRotationBuffer.X), 0);

            deltaX = 0;
            deltaY = 0;
        }

        Mouse.SetPosition(Game.GraphicsDevice.Viewport.Width / 2, Game.GraphicsDevice.Viewport.Height / 2);

Прежде чем кто-то скажет, я также отправляю это на gamedev, но я решил попробовать и здесь, если кто-то что-то знает.

1 Ответ

0 голосов
/ 22 октября 2018

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

Это то, что делает Unity.просто во время перевода мыши и ее свойств преобразования, все, что вам нужно сделать, это Slerp значений последней позиции и новой позиции мыши, скорректированной с учетом скорости перемещения мыши.

Немногоsudeo-кода, чтобы продемонстрировать прерывистое вращение камеры.

// This is a potential Unity fix for solving camera translations in general 
// for smooth movement
void Update() {
        Vector3 msNewPoint = Mouse.Position;
        Vector3 adjustedPoint = msOldPoint - msNewPoint;
        Vector3 slerpedValue = Vector3.Slerp(msOldPoint, adjustedPoint, 0.2f);

        gameObject.Transform.Rotation *= slerpedValue;
}

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

// Again this is sudo code to demonstrate clamping the mouse to prevent multi
// monitor dpi (IF you are using spanned displays. 
// Ie nVidia surround, or AMD Eyefinity.
private Rectangle oldClipRect;
private bool oldClipSet;
void clampMouse(Control control) {
        Rectangle screenRect = control.RectangleToScreen(control);

        // Initialize this only once to prevent the clip being altered
        // when the size of the screen changes
        if (!oldClipSet) {
            oldClipRect = Cursor.Clip;
            oldClipSet = true;
        }

        // If the control is focused bind the mouse to the game screen,
        // otherwise release it.
        if (control.Focused)
            Cursor.Clip = screenRect;
        else Cursor.Clip = oldClipRect;
}
...