본문 바로가기
C#

[C#][Unity] 마우스로 오브젝트 드래그 앤 드랍

by teamnova 2023. 7. 10.
728x90

오늘은 마우스로 3D Unity Wolrd 생성되어있는 오브젝트 움직이는 예제를 만들어 보겠습니다.

 

 

먼저 유니티 Hub에서 New Project 버튼을 누릅니다.

 

 

그 후 All templates에서 "3D Core"를 선택하고 Create project 버튼을 눌러서 프로젝트를 생성해줍니다.

 

그 후  화면 왼쪽 Hierarchy창에서 마우스 우클릭을 해 3D Object -> Plane을 생성하고 Position (0, 0, 0)으로 설정해줍니다.

 

그 다음 같은 방법으로 3D Object -> Cube를 생성하고 Position (0, 0.5, 0)으로 설정해줍니다.

 

이제 하단 Project창으로 가 마우스 우클릭을 한 뒤 Create -> Material을 생성하고 해당 Material 클릭 후 우측 Inspector 창에서 Albedo 속성 우측 색상 바를 클릭하고 바닥인 흰색과 구분되는 색으로 변경해줍니다.

그 뒤 Project창에서 Material을 드래그해 Cube 오브젝트로 가져가면 Cube 오브젝트의 색이 변하게 됩니다.

 

그 다음 같은 방법으로 Project 창에서 Create -> C# script "DragObject"를 생성합니다.

그리고 Scene에서 Cube를 클릭해 Cube Inspector창을 열고 방금 생성한 C# script를 드래그 해 Inspector 창으로 가져가면 해당 스크립트가 Cube 오브젝트에 적용됩니다.

 

이제 해당 DragObject 스크립트를 더블클릭해 코드 작성 툴을 실행하고 DragObject 스크립트를 아래와 같이 수정합니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DragObject : MonoBehaviour
{

    // 드래그가 가능한 상태인지 확인하는 bool 변수
    public bool draggable;


	// 매 프레임 별 호출되는 메소드
    void Update()
    {
        // 사용자가 마우스 왼쪽버튼을 눌렀을 때 true를 반환해 if문 내 코드 실행
        if(Input.GetMouseButtonDown(0)){
            // Raycast를 생성해 부딪힌 오브젝트 반환
            RaycastHit hit = CastRay();

            // 부딪힌 오브젝트가 현재 스크립트 update메소드가 실행되고 있는 오브젝트일 경우
            if(hit.transform == transform){
                // 드래그가 가능한 상태로 변경
                draggable = true;
            }
        }

        // 사용자가 마우스 왼쪽버튼을 누른 상태에서 손가락을 떼었을 때 true를 반환해 if문 내 코드 실행
        if(Input.GetMouseButtonUp(0)){
            // 드래그가 불가능한 상태로 변경
            draggable = false;
        }

        // 현재 드래그가 가능한 상태일 경우 if문 내 코드 실행
        if(draggable){
            // 현재 화면에 있는 마우스 커서의 x,y 좌표와 카메라를 통해 보는 이 스크립트가 실행되는 오브젝트의 z좌표를 사용해 ScreenPoint Vector3 position 값 생성
            Vector3 position = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.WorldToScreenPoint(transform.position).z);
            // 오브젝트를 이동할 때 움직일 x,z 좌표를 가진 WorldPoint Vector3 position 생성
            Vector3 worldPosition = Camera.main.ScreenToWorldPoint(position);
            // 위 worldPosition의 x,z 좌표를 사용하고 직접 y좌표를 설정해 오브젝트 이동
            transform.position = new Vector3(worldPosition.x, 0.5f, worldPosition.z);
        }
    }

	// Raycast에 충돌한 정보를 반환하는 메소드
    private RaycastHit CastRay(){
        // 마우스 커서가 가리키는 카메라가 랜더링하는 가장 먼곳의 위치 ScreenPoint Vector3 position
        Vector3 screenMousePosFar = new Vector3(
            Input.mousePosition.x,
            Input.mousePosition.y,
            Camera.main.farClipPlane);
        // 마우스 커서가 가리키는 카메라가 랜더링하는 가장 가까운곳의 위치 ScreenPoint Vector3 position
        Vector3 screenMousePosNear = new Vector3(
            Input.mousePosition.x,
            Input.mousePosition.y,
            Camera.main.nearClipPlane);

        // 각 위치를 WorldPosition으로 변경
        Vector3 worldMousePosFar = Camera.main.ScreenToWorldPoint(screenMousePosFar);
        Vector3 worldMousePosNear = Camera.main.ScreenToWorldPoint(screenMousePosNear);

        // RaycastHit 정보를 담을 변수 생성
        RaycastHit hit;
        // 현재 worldMousePosNear에서 시작하고 worldMousePosFar로 향하는 Raycast를 생성한다
        Physics.Raycast(worldMousePosNear, worldMousePosFar-worldMousePosNear, out hit);

        // 정보를 가진 hit 반환
        return hit;
    }

    
}

 

수정한 코드를 저장하고 Unity Tool로 이동해 실행 버튼을 누르면 아래 동영상과 같이 마우스로 오브젝트를 드래그해 위치를 이동할 수 있습니다.