본문 바로가기
개발/Unity

드래그로 카메라 회전 및 이동하기 (Camera Rotate and Move with Drag)

by 피로물든딸기 2022. 4. 27.
반응형

Unity 전체 링크

 

참고

 시네머신 튜토리얼 링크 (시네머신을 이용하여 카메라 간편하게 조작하기)

 

마우스 드래그를 이용해 카메라를 회전하고 이동하는 스크립트를 합쳐보자.

 

Alt키를 누르면 이동을 하고, 누르지 않은 경우는 회전을 한다.

위의 링크를 참고하면 아래와 같이 스크립트를 만들 수 있다. ( + 스크롤 이동 포함)

(stage → lookAtMe로 이름 변경)

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

public class RotateAround : MonoBehaviour
{
    public GameObject lookAtMe;
    public float rotateSpeed = 500.0f;
    public float scrollSpeed = 2000.0f;
    private float xRotateMove, yRotateMove;

    bool isAlt;
    Vector2 clickPoint;
    float dragSpeed = 30.0f;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.LeftAlt)) isAlt = true;
        if (Input.GetKeyUp(KeyCode.LeftAlt)) isAlt = false;

        if (Input.GetMouseButtonDown(0)) clickPoint = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
       
        if (Input.GetMouseButton(0))
        {
            if (isAlt)
            {
                Vector3 position
                    = Camera.main.ScreenToViewportPoint((Vector2)Input.mousePosition - clickPoint);

                position.z = position.y;
                position.y = .0f;

                Vector3 move = position * (Time.deltaTime * dragSpeed);

                float y = transform.position.y;

                transform.Translate(move);
                transform.position
                    = new Vector3(transform.position.x, y, transform.position.z);
            }
            else
            {
                xRotateMove = Input.GetAxis("Mouse X") * Time.deltaTime * rotateSpeed;
                yRotateMove = Input.GetAxis("Mouse Y") * Time.deltaTime * rotateSpeed;

                Vector3 pos = lookAtMe.transform.position;

                transform.RotateAround(pos, Vector3.right, -yRotateMove);
                transform.RotateAround(pos, Vector3.up, xRotateMove);

                transform.LookAt(pos);
            }
        }
        else
        {
            float scroollWheel = Input.GetAxis("Mouse ScrollWheel");

            Vector3 cameraDirection = this.transform.localRotation * Vector3.forward;

            this.transform.position += cameraDirection * Time.deltaTime * scroollWheel * scrollSpeed;
        }
    }
}

 

Alt Key에 따라 잘 움직이지만 아래와 같이 카메라가 튀는 현상이 발생한다.

 

위와 같은 현상은 아래의 코드로 인해 문제가 된다.

카메라의 rotate가 Stage를 바라보며 회전하기 때문에, 좌우/앞뒤 이동 후 다시 pos을 고정한다.

transform.LookAt(pos);

 

이 문제를 간단히 해결하는 방법은 카메라가 바라보는 좌표도 같이 카메라와 움직이는 것이다.

하지만 Stage가 움직이는 것은 원하는 방향이 아니다.

따라서 Stage의 최초 위치(여기서는 0, 0, 0)에 Empty Object(=LookAtMe)를 만든다.

카메라의 Loot At Me에 방금 만든 빈 오브젝트(LookAtMe)를 추가한다.

 

카메라의 시점이 제대로 움직이는지 확인하기 위해 Sphere를 자식으로 만들어서 눈으로 볼 수 있도록 하였다.

아래의 초록색 공이 카메라가 최초로 바라보는 포지션이 된다.

scroll을 할 때는 오브젝트의 부모/자식 관계를 해제하고 isAlt인 경우 부모로 만들어 같이 움직이도록 한다.

    void Update()
    {
		...
        
        if (Input.GetMouseButton(0))
        {
            if (isAlt)
            {
                lookAtMe.transform.SetParent(this.transform);
				
                ...
            }
            else { ... }
        }
        else
        {
            lookAtMe.transform.SetParent(null);
			
            ...
        }
    }

 

이제 아래와 같이 정상적으로 카메라가 회전/이동하는 것을 알 수 있다.

 

최종 코드는 다음과 같다.

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

public class RotateAround : MonoBehaviour
{
    public GameObject lookAtMe;
    public float rotateSpeed = 500.0f;
    public float scrollSpeed = 2000.0f;
    private float xRotateMove, yRotateMove;

    bool isAlt;
    Vector2 clickPoint;
    float dragSpeed = 30.0f;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.LeftAlt)) isAlt = true;
        if (Input.GetKeyUp(KeyCode.LeftAlt)) isAlt = false;

        if (Input.GetMouseButtonDown(0)) clickPoint = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
       
        if (Input.GetMouseButton(0))
        {
            if (isAlt)
            {
                lookAtMe.transform.SetParent(this.transform);

                Vector3 position
                    = Camera.main.ScreenToViewportPoint((Vector2)Input.mousePosition - clickPoint);

                position.z = position.y;
                position.y = .0f;

                Vector3 move = position * (Time.deltaTime * dragSpeed);

                float y = transform.position.y;

                transform.Translate(move);
                transform.position
                    = new Vector3(transform.position.x, y, transform.position.z);
            }
            else
            {
                xRotateMove = Input.GetAxis("Mouse X") * Time.deltaTime * rotateSpeed;
                yRotateMove = Input.GetAxis("Mouse Y") * Time.deltaTime * rotateSpeed;

                Vector3 pos = lookAtMe.transform.position;

                transform.RotateAround(pos, Vector3.right, -yRotateMove);
                transform.RotateAround(pos, Vector3.up, xRotateMove);

                transform.LookAt(pos);
            }
        }
        else
        {
            lookAtMe.transform.SetParent(null);

            float scroollWheel = Input.GetAxis("Mouse ScrollWheel");

            Vector3 cameraDirection = this.transform.localRotation * Vector3.forward;

            this.transform.position += cameraDirection * Time.deltaTime * scroollWheel * scrollSpeed;
        }
    }
}

 

Unity Plus:

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Unity Pro:

 

Unity Pro

The complete solutions for professionals to create and operate.

unity.com

 

Unity 프리미엄 학습:

 

Unity Learn

Advance your Unity skills with live sessions and over 750 hours of on-demand learning content designed for creators at every skill level.

unity.com

반응형

댓글