Touch로 Object를 옮기는 방법
카메라가 고정된 환경에서 물체를 터치해서 움직이려고 했다.
이를 구현하기 위해서 Ray와 Touch, Camera.main.ScreenToWorldPoint를 이용했다.
내가 구현하려던 움직임은 3D 환경에서 드래그앤 드롭으로 2D 평면 이동하듯이 시키고 싶었다
그런데 문제가 있었다
카메라가 기울어져있는 상태로 위에서 쳐다보는 상태였기 때문에 Screen에서 Touch한 곳의 좌표와 내가 보는 화면의 world좌표가 실제로는 달랐던 것이다.
즉, 아래 그림과 같은 상태였던 것이다.
실제 터치된 좌표와 터치된 object의 좌표가 달랐기 때문에 드래그를 시작하면 좌표에 오차가 생겼다.
이를 offset을 이용해 보정해 문제를 해결했다.
GameObject hitObject;
Transform towerTrans;
bool dragging = false;//drag중인지 판단하는 변수
Vector3 offset;
void TowerMove()
{
// 모바일 드래그앤 드롭
Vector3 vec;
if (Input.touchCount != 1) { // 터치카운트가 여러개라면 드래그를 취소
dragging = false;
return;
}
Touch touch = Input.touches[0]; // 첫 터치한 값을 가져오고
Vector3 tPos= touch.position; // 위치를 가져온다.
if (touch.phase ==TouchPhase.Began) // 첫 터치라면
{
Ray ray = Camera.main.ScreenPointToRay(tPos); // 카메라에서 터치된 방향으로 Ray를 쏜다.
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.gameObject.tag == "Tower")
{
hitObject= hit.collider.gameObject;
towerTrans = hitObject.transform; // 타워의 위치
vec = new Vector3(tPos.x, tPos.y, 0); // 터치한 포지션의 x, y값, 0은 화면과의 거리를 의미함
// 월드 좌표 기준으로 y축 값은 고정이므로 상관x
vec = Camera.main.ScreenToWorldPoint(vec); // 스크린 값을 월드좌표로 변경
offset = toDrag.position - vec; // 보정해주어야 하는 값
dragging = true; // 드래그 상태
}
}
}
if (dragging && touch.phase == TouchPhase.Moved)
{
vec = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0);
vec = Camera.main.ScreenToWorldPoint(vec); // 화면에서 이동한 값
Vector3 nV = new Vector3(vec.x+offset.x, towerTrans.position.y, vec.z+offset.z); // 실제 이동값
towerTrans.position = nV;
}
if (dragging && (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled))
{
// drag 상태에서 해제할 때 한번 실행
hitObject = null;
dragging = false;
}
}
반응형
'Game > Unity' 카테고리의 다른 글
[Unity] UI Text script로 변경하기 (0) | 2024.03.27 |
---|---|
[Unity] Script LifeCycle [스크립트 생명주기] (0) | 2024.01.02 |