Как сделать управление RTS камеры на смартфонах?

Привет Хабр, мне нужны твои лучшие умы!

В чем проблема. Я новичок и я делаю RTS управление камерой в 3D пространстве для телефона, и у меня не получается сделать Зумм камеры. Как только я касаюсь 2 пальцами экрана, камера просто движется вперёд без остановки.

Сама камера прикреплена к ригу и является его дочерним объектом, как на этом рисунке:
61a39701ee488517083399.jpeg

Скрипт камеры вы видите ниже:
[SerializeField] private Camera _mainCamera;
    [SerializeField] private float speedCam;
    [SerializeField] private float speedZoom;

    private Vector3 newPosition;
    private Vector3 dragStartPosition;
    private Vector3 dragCurrentPosition;


    private Vector3 newZoom;
    [SerializeField] private Vector3 zoomAmount;

    private void Awake()
    {
        _mainCamera = GetComponentInChildren<Camera>();
        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.GetTouch(0).position);
                    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.GetTouch(0).position);
                    float entry;
                    if (plane.Raycast(ray, out entry)) // если луч касаеться олейна передаем значения новой позиции
                    {
                        dragCurrentPosition = ray.GetPoint(entry);
                        newPosition = transform.position + dragStartPosition - dragCurrentPosition;
                    }
                }
            }
            if (Input.touchCount == 2) // метод для зумма
            {
                var Finger1 = Input.GetTouch(0);
                var Finger2 = Input.GetTouch(1);

                var TouchFinger0Direction = Finger1.position - Finger1.deltaPosition;
                var TouchFinger1Direction = Finger2.position - Finger2.deltaPosition;

                var TouchesPosition = Vector3.Distance(Finger1.position, Finger2.position);
                var TouchesDirection = Vector3.Distance(TouchFinger0Direction, TouchFinger1Direction);


                if (TouchesPosition > TouchesDirection)
                {
                    newZoom -= zoomAmount;
                }
                if (TouchesPosition < TouchesDirection)
                {
                    newZoom += zoomAmount;
                }
             // как движется зумм 
            _mainCamera.gameObject.transform.localPosition = Vector3.MoveTowards(_mainCamera.gameObject.transform.localPosition, newZoom, Time.deltaTime * speedZoom);
            }
        }

        newPosition.x = Mathf.Clamp(newPosition.x, 16f, 145f);  // ограничеваем передвижение
        newPosition.z = Mathf.Clamp(newPosition.z, -8.5f, 390f);
        transform.position = Vector3.MoveTowards(transform.position, newPosition, Time.deltaTime * speedCam); // плавное передвижение
        
    }


Я прошу:

• Помогите мне сделать зум для камеры!

• Как я могу ограничить зум?

Важно:
• Камера в режиме Перспективы, а значит зум через угол обзора делать нельзя!
  • Вопрос задан
  • 93 просмотра
Пригласить эксперта
Ответы на вопрос 2
@Ente
Unity developer
1) Сделай такую конструкцию из gameobject'ов

-NodeMove
--NodeZoom
---NodeRotate
----Camera

Затем сделай три скрипта, каждый из которых управляет только свои gameobjectом, т.е. NodeZoom может только управлять координатой Z. А NodeRotate крутить по Z. Таким образом у тебя никогда не получится ситуация, что при зуме начнет меняться координата X или Y на этом объекте. Само-собой, NodeMove только Х и Y.

2) Далее в каждом скрипте делай проверку. Например, на зум можно игнорировать все ситуации, когда тачей != 2, а для передвижения != 1.
Ответ написан
При приближении тебе нужно ограничить через Mathf.clamp верхнюю и нижние границы приближени отдаления камеры, я бы посоветовал тебе 200/800
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы