개발/Unity
유니티 - 멀티 터치 드래그를 이용하여 카메라 줌 인 / 아웃 (Camera Zoom in / out with Multi Touch Drag)
피로물든딸기
2023. 7. 15. 19:10
반응형
참고
→ 시네머신 튜토리얼 링크 (시네머신을 이용하여 카메라 간편하게 조작하기)
멀티 터치 이펙트를 적용한 후, 멀티 터치를 드래그 했을 때, 카메라가 줌 인 / 줌 아웃이 되도록 해보자.
카메라 줌 인 / 줌 아웃
마우스 스크롤로 카메라를 줌 인 / 아웃하였을 때,
fieldOfView를 변경하거나 카메라가 향한 방향으로 앞 / 뒤로 이동하였다.
여기서는 카메라의 위치를 변경시킨다.
먼저 카메라에 있는 MobileTouch.cs에서 radius를 조금 줄이고, zoomSpeed 변수를 추가한다.
float radius = 0.02f;
float zoomSpeed = 1.0f;
Update에서는 터치 카운트가 2인 경우, 현재와 이전 위치의 차이를 빼서 카메라의 위치를 변경시켰다.
Input.GetTouch의 position에서 deltaPosition을 빼면 이전 터치 위치를 알 수 있다.
만약 diff를 prev - curr로 변경하면 두 손을 오므릴 때, 줌 인이 된다.
void Update()
{
if(Input.touchCount == 2)
{
Vector2 prevPos0 = Input.GetTouch(0).position - Input.GetTouch(0).deltaPosition;
Vector2 prevPos1 = Input.GetTouch(1).position - Input.GetTouch(1).deltaPosition;
float prevDistance = (prevPos0 - prevPos1).magnitude;
float currDistance = (Input.GetTouch(0).position - Input.GetTouch(1).position).magnitude;
float diff = currDistance - prevDistance;
Vector3 cameraDirection = this.transform.localRotation * Vector3.forward;
this.transform.position += cameraDirection * Time.deltaTime * diff * zoomSpeed;
}
...
}
또는 fieldOfView를 변경해도 된다.
Camera.main.fieldOfView += diff * Time.deltaTime * zoomSpeed;
안드로이드 빌드 후, 멀티 터치를 드래그 해보자.
터치된 위치의 크기에 따라 카메라의 위치가 변경된다.
전체 코드는 다음과 같다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MobileTouch : MonoBehaviour
{
Material mat;
bool touchFlag;
List<Vector3> touchPosList;
int numberOfTriangle = 10;
float radius = 0.02f;
float zoomSpeed = 1.0f;
void makeCircle(Vector3 touchPos, Color color)
{
GL.Color(color);
List<Vector3> pos = new List<Vector3>();
for (int i = 0; i < numberOfTriangle; i++)
{
float angle = i * (Mathf.PI * 2.0f) / numberOfTriangle;
Vector3 dot = (new Vector3(Mathf.Cos(angle), Mathf.Sin(angle), 0)) * radius;
float width = (float)Screen.width;
float height = (float)Screen.height;
if (width > height)
{
dot.x = dot.x * height / width;
}
else
{
dot.y = dot.y * width / height;
}
pos.Add(dot + touchPos);
}
for (int i = 0; i < numberOfTriangle - 1; i++)
{
GL.Vertex3(touchPos.x, touchPos.y, 0);
GL.Vertex3(pos[i + 1].x, pos[i + 1].y, 0);
GL.Vertex3(pos[i].x, pos[i].y, 0);
}
GL.Vertex3(touchPos.x, touchPos.y, 0);
GL.Vertex3(pos[0].x, pos[0].y, 0);
GL.Vertex3(pos[numberOfTriangle - 1].x, pos[numberOfTriangle - 1].y, 0);
}
void OnPostRender()
{
if (!mat)
{
Debug.LogError("Please Assign a material on the inspector");
return;
}
if (touchFlag)
{
GL.PushMatrix();
mat.SetPass(0);
GL.LoadOrtho();
GL.Begin(GL.TRIANGLES);
int touchCount = touchPosList.Count;
Color[] colorSet = new Color[] { Color.red, Color.green, Color.blue };
for (int i = 0; i < touchCount; i++)
makeCircle(touchPosList[i], colorSet[i % 3]);
GL.End();
GL.PopMatrix();
}
}
void Start()
{
mat = new Material(Shader.Find("Draw/Quads"));
}
void Update()
{
if(Input.touchCount == 2)
{
Vector2 prevPos0 = Input.GetTouch(0).position - Input.GetTouch(0).deltaPosition;
Vector2 prevPos1 = Input.GetTouch(1).position - Input.GetTouch(1).deltaPosition;
float prevDistance = (prevPos0 - prevPos1).magnitude;
float currDistance = (Input.GetTouch(0).position - Input.GetTouch(1).position).magnitude;
float diff = currDistance - prevDistance;
Vector3 cameraDirection = this.transform.localRotation * Vector3.forward;
this.transform.position += cameraDirection * Time.deltaTime * diff * zoomSpeed;
}
if (Input.GetMouseButton(0))
{
touchPosList = new List<Vector3>();
int touchCount = Input.touchCount;
for (int i = 0; i < touchCount; i++)
{
Vector3 inputPos = Input.GetTouch(i).position;
Vector3 mousePos
= new Vector3(inputPos.x, inputPos.y, -Camera.main.transform.position.z);
Vector3 touchPos = Camera.main.ScreenToViewportPoint(mousePos);
touchPosList.Add(touchPos);
}
touchFlag = true;
}
else
{
touchFlag = false;
}
}
}
Unity Plus:
Unity Pro:
Unity 프리미엄 학습:
반응형