Как сделать Zoom камеры на Android в Unity?

Привет DTF, и снова я ищу у вас помощи!

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

(Важно!) Нюансы:

• Камера(Camera) прикреплена к подставке (Camera Rig), которая управляет движением.

• Камера находится в режиме Perspective, но по своим настройкам имитирует orthographic (Менять стиль отображения нельзя)

• Делать Зум через Field of view нельзя, так как это ломает стиль и нужную глубину

• Зум нужно делать через движение Camera.localPosition изменяя Z и Y в разные стороны. То есть, если Y++, то Z-- и всё это равномерно.

• Все скрипты из интернета, которые я находил, работают плохо. Когда делаешь зум и отпускаешь палец, камера телепортируется к последнему пальцу.

Ниже вы видите скриншоты иерархии их настройки и куда прикреплен скрипт. Ещё ниже вы увидите как я реализовал сенсорное управление.

Как реализовать зум камеры, со всеми этими условиями?

public class CameraController : MonoBehaviour { [SerializeField] private float movementTime; private Vector3 newPosition; private Vector3 dragStartPosition; private Vector3 dragCurrentPosition; private void Awake() { newPosition = transform.position; } private void Start() { } private void Update() { HandleTouchInput(); } private void HandleTouchInput() // метод передвижение - сенсор { foreach (Touch touch in Input.touches) { if (Input.touchCount == 1) // касание одного пальца { if (touch.phase == TouchPhase.Began) // касается ли палец экрана и создаем плейн, куда отправляем луч { Plane plane = new Plane(Vector3.up, Vector3.zero); Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); float entry; if (plane.Raycast(ray, out entry)) // если луч касаеться плейна, присваеваем его позицию { dragStartPosition = ray.GetPoint(entry); } } if (touch.phase == TouchPhase.Moved) // проверяем двигается ли палец и отправляем луч { Plane plane = new Plane(Vector3.up, Vector3.zero); Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); float entry; if (plane.Raycast(ray, out entry)) // если луч касаеться олейна передаем значения новой позиции { dragCurrentPosition = ray.GetPoint(entry); newPosition = transform.position + dragStartPosition - dragCurrentPosition; } } } if (Input.touchCount == 2) / касание двух пальцев { } } newPosition.x = Mathf.Clamp(newPosition.x, 16f, 145f); // ограничеваем передвижение Рига по X и Z newPosition.z = Mathf.Clamp(newPosition.z, -8.5f, 390f); transform.position = Vector3.Lerp(transform.position, newPosition, Time.deltaTime * movementTime); // плавное передвижение } }
55
13 комментариев

Используй синемашин. Кодить свою камеру когда есть проф решение это странно

1
Ответить

В синемашин есть готовый скрипт зума?

1
Ответить

Забыл. Не смотрите на настройки: ZoomMax, ZoomMin, Sensivity.

Ответить

У меня так сделано

Ответить

Спасибо, посмотрю!

Ответить

Делать плавное движение лерпом - такая себе затея. Во-первых, нельзя контролировать скорость, так как 10% от миллиона куда больше, чем 10% от десяти, во-вторых, движение будет не равномерное, так как каждый раз оно начинается с текущей позиции (1 * 0. 1 + 0.9 * 0.2) != (1 * 0.2)

Ответить

Контроль скорости идёт через movementTime

Ответить