안녕하세요.
이번 시간엔 마우스 및 화면 터치 & 드래그로 카메라, 오브젝트를 이동하게 하는 방법에 대해 작성하고자 합니다.
먼저 카메라 및 오브젝트들을 임의의 위치로 생성합니다.
다음 CameraController.cs 를 생성합니다.
CameraController.cs
using UnityEngine;
public class CameraController : MonoBehaviour
{
[SerializeField] private GameObject _camera;
[Tooltip("드래그 하여 이동할 거리 비율")]
[SerializeField] private float _moveRate;
private Vector3 _tmpClickPos;
private Vector3 _tempCameraPos;
private void Update()
{
MouseMovement();
}
/// <summary>마우스로 카메라를 이동시키는 함수</summary>
private void MouseMovement()
{
if (Input.GetMouseButtonDown(0))
{
//좌클릭시 카메라, 클릭 위치 값을 저장해둔다.
//좌클릭을 꾹 누르고 있을 때 위치를 이동시키기 위함
_tmpClickPos = Input.mousePosition;
_tempCameraPos = _camera.transform.position;
}
else if (Input.GetMouseButton(0))
{
//(저장한 클릭 위치 - 현재 마우스 위치)로 이동할 방향 및 거리를 계산한다.
Vector3 movePos = Camera.main.ScreenToViewportPoint(_tmpClickPos - Input.mousePosition);
_camera.transform.position = _tempCameraPos + (movePos * _moveRate);
}
}
}
위의 코드와 같이 작성하여 Hierarchy창의 Main Camera에 해당 스크립트를 추가해줍니다.
Inspector창에서 Camera항목에는 MainCamera 자신
MoveRate란에는 드래그 시 카메라의 이동속도를 넣어주시면 됩니다.
자 PC에서의 카메라 드래그 이동은 끝났습니다
이제 실행하여 화면을 드래그 하시면 카메라가 이동하는 것을 볼 수 있습니다!
하지만 이렇게 드래그 하는 방식은 보통 모바일에서 많이 사용하죠?
모바일 방식인 터치 방식을 추가하여 스크립트를 수정해보겠습니다.
CameraController.cs
using UnityEngine;
public class CameraController : MonoBehaviour
{
[SerializeField] private GameObject _camera;
[Tooltip("드래그 하여 이동할 거리 비율")]
[SerializeField] private float _moveRate;
private Vector3 _tmpClickPos;
private Vector3 _tmpCameraPos;
private void Update()
{
#if UNITY_EDITOR //유니티 에디터로 실행하고 있을 경우
MouseMovement();
#elif UNITY_ANDROID || UNITY_IOS //안드로이드 및 IOS에서 실행하고 있을 경우
TouchMovement();
#endif
}
/// <summary>마우스로 카메라를 이동시키는 함수</summary>
private void MouseMovement()
{
if (Input.GetMouseButtonDown(0))
{
//좌클릭시 카메라, 클릭 위치 값을 저장해둔다.
//좌클릭을 꾹 누르고 있을 때 위치를 이동시키기 위함
_tmpClickPos = Input.mousePosition;
_tmpCameraPos = _camera.transform.position;
}
else if (Input.GetMouseButton(0))
{
//(저장한 클릭 위치 - 현재 마우스 위치)로 이동할 방향 및 거리를 계산한다.
Vector3 movePos = Camera.main.ScreenToViewportPoint(_tmpClickPos - Input.mousePosition);
_camera.transform.position = _tmpCameraPos + (movePos * _moveRate);
}
}
private void TouchMovement()
{
//한손가락으로 터치하지않으면 함수를 종료
if (Input.touchCount != 1)
return;
Touch touch = Input.GetTouch(0);
//첫 터치 상태일때
if (touch.phase == TouchPhase.Began)
{
//화면 터치시 카메라, 클릭 위치 값을 저장해둔다.
//화면을 꾹 누르고 있을 때 위치를 이동시키기 위함
_tmpClickPos = touch.position;
_tmpCameraPos = _camera.transform.position;
}
//터치 중일때
else if (touch.phase == TouchPhase.Moved)
{
//(저장한 터치 위치 - 현재 터치 위치)로 이동할 방향 및 거리를 계산한다.
Vector3 movePos = Camera.main.ScreenToViewportPoint(_tmpClickPos - (Vector3)touch.position);
_camera.transform.position = _tmpCameraPos + (movePos * _moveRate);
}
}
}
자 거의다 왔습니다.
이제는 카메라 이동에 디테일을 추가해보도록 하겠습니다.
화면 터치 후 드래그로 이동하다 터치를 떼는 순간 감속을 추가하여 스무스한 움직임을 구현하겠습니다.
CameraController.cs
using UnityEngine;
public class CameraController : MonoBehaviour
{
[SerializeField] private GameObject _camera;
[Space]
[Tooltip("드래그 하여 이동할 거리 비율")]
[SerializeField] private float _moveRate;
[Space]
[Tooltip("카메라 가속 배율")]
[SerializeField] private float _accelerationRate;
[Tooltip("카메라 감속 배율")]
[SerializeField] private float _decelerationRate;
private Vector3 _tmpClickPos;
private Vector3 _tmpCameraPos;
private Vector3 _distancemoved;
private Vector3 _lastPos;
private Vector3 _velocity;
private void Update()
{
#if UNITY_EDITOR //유니티 에디터로 실행하고 있을 경우
MouseMovement();
#elif UNITY_ANDROID || UNITY_IOS //안드로이드 및 IOS에서 실행하고 있을 경우
TouchMovement();
#endif
RunningAcceleration();
}
/// <summary>마우스로 카메라를 이동시키는 함수</summary>
private void MouseMovement()
{
//좌클릭했을때
if (Input.GetMouseButtonDown(0))
{
//좌클릭시 카메라, 클릭 위치 값을 저장해둔다.
//좌클릭을 꾹 누르고 있을 때 위치를 이동시키기 위함
_tmpClickPos = Input.mousePosition;
_tmpCameraPos = _camera.transform.position;
//가속도 관련 변수를 초기화한다.
ResetAcceleration();
}
//좌클릭 중 일때
else if (Input.GetMouseButton(0))
{
//(저장한 클릭 위치 - 현재 마우스 위치)로 이동할 방향 및 거리를 계산한다.
Vector3 movePos = Camera.main.ScreenToViewportPoint(_tmpClickPos - Input.mousePosition);
_camera.transform.position = _tmpCameraPos + (movePos * _moveRate);
//가속도를 계산한다.
CheckAcceleration();
}
//좌클릭을 종료했을때
else if (Input.GetMouseButtonUp(0))
{
//가속도 적용
SetAcceleration(_distancemoved);
}
}
private void TouchMovement()
{
//한손가락으로 터치하지않으면 함수를 종료
if (Input.touchCount != 1)
return;
Touch touch = Input.GetTouch(0);
//첫 터치 상태일때
if (touch.phase == TouchPhase.Began)
{
//화면 터치시 카메라, 클릭 위치 값을 저장해둔다.
//화면을 꾹 누르고 있을 때 위치를 이동시키기 위함
_tmpClickPos = touch.position;
_tmpCameraPos = _camera.transform.position;
//가속도 관련 변수를 초기화한다.
ResetAcceleration();
}
//터치 중일때
else if (touch.phase == TouchPhase.Moved)
{
//(저장한 터치 위치 - 현재 터치 위치)로 이동할 방향 및 거리를 계산한다.
Vector3 movePos = Camera.main.ScreenToViewportPoint(_tmpClickPos - (Vector3)touch.position);
_camera.transform.position = _tmpCameraPos + (movePos * _moveRate);
//가속도를 계산한다.
CheckAcceleration();
}
//터치가 종료됬을때
else if (touch.phase == TouchPhase.Ended)
{
//가속도 적용
SetAcceleration(_distancemoved);
}
}
/// <summary>현재 위치와 이전 위치를 비교하여 가속도 값을 저장하는 함수</summary>
private void CheckAcceleration()
{
_distancemoved = transform.position - _lastPos; //이전 프레임과 현재 프레임의 위치 차이를 계산해 삽입
_lastPos = transform.position;
_velocity = Vector3.zero;
}
/// <summary>가속도 관련 변수를 초기화 하는 함수</summary>
private void ResetAcceleration()
{
_distancemoved = Vector3.zero;
_lastPos = Vector3.zero;
_velocity = Vector3.zero;
}
/// <summary>가속도를 설정하는 함수</summary>
private void SetAcceleration(Vector3 acceleration)
{
_velocity = (acceleration / Time.deltaTime) * _accelerationRate;
}
/// <summary>_velocity값이 0이 아닐 경우 가속도를 주는 함수</summary>
private void RunningAcceleration()
{
//속도가 0일 경우 리턴
if (_velocity.sqrMagnitude == 0)
return;
//감속 속도를 현재 속도 * Time * 감속 비율 로 구한다.
Vector3 _deceleration = _velocity * (Time.deltaTime * _decelerationRate);
_velocity -= _deceleration;
//현재 속도가 일정 수치가 되면 0으로 설정한다.
if (_velocity.sqrMagnitude < 0.5f && _velocity.sqrMagnitude > -0.5f)
{
_velocity = Vector3.zero;
}
//위치를 이동시킨다.
_camera.transform.position = transform.position + _deceleration;
}
}
Inspector창도 이렇게 설정해줍니다.
AccelerationRate: 터치를 뗀 순간 가속도의 비율
DecelerationRate: 카메라 감속 비율
이렇게 수정하시면 터치를 떼는 순간 카메라가 드래그한 방향으로 이동하다 감속하게 됩니다.
아래 움짤을 확인하시면 정상적으로 가속, 감속이 적용되는 것을 볼 수 있습니다.!
'Unity 공부' 카테고리의 다른 글
[Unity] 코루틴(Coroutine) (0) | 2024.08.04 |
---|---|
[Unity] 재사용 스크롤 뷰(Recyclable Scroll View) (0) | 2024.06.18 |
[Unity] 컷 아웃 마스크(Cutout Mask) (0) | 2024.01.24 |
[Unity] Behavior Tree(BT) (0) | 2023.12.11 |
[Unity] FSM 유한 상태 기계 (0) | 2023.11.21 |