Как изменять размер камеры по вертикали, а не горизонтали?

Общие вопросы о Unity3D

Как изменять размер камеры по вертикали, а не горизонтали?

Сообщение Shock 21 май 2017, 04:31

Итак, у меня есть сцена, которая настроена на размер экрана 16:9. Она идеально в него влезает:

Изображение

Но если игрок ставит разрешение 4:3, то камера обрезает важную часть сцены справа и слева:

Изображение

Можно ли как-то сделать, чтобы угол по ширине всегда был одинаковый, а зависимо от разрешения менялся угол по высоте?:

Изображение

Я понимаю, что мог бы настраивать сцену под размеры 4:3, но таких экранов меньше, пустота сверху никуда не денется, а на нормальном игровом соотношении 16:9 кроме пустоты сверху появится ненужная пустота еще и по бокам:

Изображение
Аватара пользователя
Shock
UNIт
 
Сообщения: 77
Зарегистрирован: 10 окт 2016, 18:22

Re: Как изменять размер камеры по вертикали, а не горизонтали?

Сообщение Shock 21 май 2017, 05:18

Долго гуглил, но смог нагуглить после того, как написал тему. На СтекОверфлоу есть отличный ответ как отправная точка, в частности, ссылка на платный ассет "Camera Fit: Screen Handler", который, похоже, делает то, что нужно. Я, правда, написал свое на базе нижнего ответа.

Изображение

Код компонента:
Синтаксис:
Используется csharp
using System;
using UnityEngine;

[RequireComponent(typeof(Camera))]
public class CameraFov : MonoBehaviour
{
        [SerializeField]
        [Range(1, 179)]
        private int horizontalFov = 90;
        [SerializeField]
        [Range(1, 179)]
        private int minimalVerticalFov = 1;

        private float _lastAspect;
        private Camera _camera;

        private const float TOLERANCE = 0.01f;

        public void Start ()
        {
                _camera = GetComponent<Camera>();
                UpdateVerticalFov();
        }

        public void Update ()
        {
                if (Math.Abs(_camera.aspect - _lastAspect) < TOLERANCE) return;

                _lastAspect = _camera.aspect;
                UpdateVerticalFov();
        }

        public bool IsDirtyEditor ()
        {
                var _camera = GetComponent<Camera>();
                return (Math.Abs(CalculateVerticalFov(_camera) - _camera.fieldOfView) > TOLERANCE);
        }

        public void EditorUpdateVertivalFov ()
        {
                var _camera = GetComponent<Camera>();
                _camera.fieldOfView = CalculateVerticalFov(_camera);
        }

        private void UpdateVerticalFov ()
        {
                _camera.fieldOfView = CalculateVerticalFov(_camera);
        }

        private float CalculateVerticalFov (Camera camera)
        {
                float hFovInRads = Mathf.Deg2Rad * horizontalFov;
                float vFovInRads = 2 * Mathf.Atan(Mathf.Tan(hFovInRads / 2) / camera.aspect);
                return Math.Max(Math.Max(1, minimalVerticalFov), vFovInRads * Mathf.Rad2Deg);
        }

}
 


А так же код компонента, который позволяет налету изменять значения с редактора:
Синтаксис:
Используется csharp
using Assets.Nuclear.Utils;
using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(CameraFov))]
public class CameraFovEditor : Editor
{
        public override void OnInspectorGUI ()
        {
                DrawDefaultInspector();
                Recheck();
        }

        public void Recheck ()
        {
                var cam = (CameraFov)target;

                if (!cam.enabled || !cam.IsDirtyEditor()) return;

                cam.EditorUpdateVertivalFov();
                EditorUtility.SetDirty(target);
        }
}
Аватара пользователя
Shock
UNIт
 
Сообщения: 77
Зарегистрирован: 10 окт 2016, 18:22


Вернуться в Общие вопросы

Кто сейчас на конференции

Сейчас этот форум просматривают: GoGo.Ru [Bot] и гости: 13