Answer the question
In order to leave comments, you need to log in
How to make RTS camera control on smartphones?
Hello Habr, I need your best minds!
What is the problem. I'm a beginner and I'm doing RTS camera control in 3D space for my phone and I'm not able to zoom the camera. As soon as I touch the screen with 2 fingers, the camera just moves forward without stopping.
The camera itself is attached to the rig and is its child object, as in this picture:
You can see the camera script below:
[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); // плавное передвижение
}
Answer the question
In order to leave comments, you need to log in
1) Make such a construction from gameobjects
-NodeMove
--NodeZoom
---NodeRotate
----Camera
Then make three scripts, each of which controls only its own gameobject, i.e. NodeZoom can only control the Z coordinate. And NodeRotate rotates along Z. Thus, you will never get a situation when the X or Y coordinate on this object starts to change when you zoom. Of course, NodeMove only X and Y.
2) Next, in each script, do a check. For example, for zoom, you can ignore all situations when touch != 2, and for movement != 1.
When approaching, you need to limit through Mathf.clamp the upper and lower limits of the camera's distance from the camera, I would advise you 200/800
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question