본문 바로가기
개발/Unity

유니티 - 1인칭 시점 조작 first person view controller

by 피로물든딸기 2022. 3. 6.
반응형

Unity 전체 링크

 

참고

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

 

카메라 회전을 하였으므로, 이제 카메라를 Player 아래로 둔다.

 

여기서 front는 player가 제대로 회전하는지 확인하기 위해 만들어둔 좌표다.

빈 오브젝트를 설정하여 플레이어보다 약간 앞 (Z=10)에 맞춰두자.

 

front를 스크립트에 설정해두고 DrawLine을 설정한다.

Debug.DrawLine(transform.position, objectFrontVector.position, Color.red);

 

Player 앞에 line이 생겨서 방향을 구분할 수 있게 되었다.


Camera에 회전을 하는 스크립트는 해제한다.

카메라는 Player의 자식이므로 Player가 회전하면 같이 회전하기 때문이다.

 

Player의 스크립트에 Translate 코드와 클릭시 회전 코드를 추가한다.

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

public class PlayerCtrl : MonoBehaviour
{
    public Transform objectFrontVector;

    private float h = 0.0f;
    private float v = 0.0f;
    public float moveSpeed = 10.0f;

    private float xRotate, yRotate, xRotateMove, yRotateMove;
    public float rotateSpeed = 500.0f;

    void Update()
    {
        /* debug */
        Debug.DrawLine(transform.position, objectFrontVector.position, Color.red);

        /* player 이동 */
        h = Input.GetAxis("Horizontal");
        v = Input.GetAxis("Vertical");

        Vector3 moveDir = (Vector3.forward * v) + (Vector3.right * h);

        transform.Translate(moveDir.normalized * Time.deltaTime * moveSpeed, Space.Self);

        /* 회전 */
        if (Input.GetMouseButton(0)) // 클릭한 경우
        {
            xRotateMove = -Input.GetAxis("Mouse Y") * Time.deltaTime * rotateSpeed;
            yRotateMove = Input.GetAxis("Mouse X") * Time.deltaTime * rotateSpeed;

            yRotate = transform.eulerAngles.y + yRotateMove;
            //xRotate = transform.eulerAngles.x + xRotateMove; 
            xRotate = xRotate + xRotateMove;

            xRotate = Mathf.Clamp(xRotate, -90, 90); // 위, 아래 고정

            transform.eulerAngles = new Vector3(xRotate, yRotate, 0);
        }
    }
}

 

WASD로 이동하고, 마우스로 회전을 해서 이동 방향을 바꿀 수 있지만

오브젝트가 y축으로 회전하기 때문에 아래와 같은 버그가 생긴다.


카메라와 Player는 따로 구분하고, Player Script에서 Camera가 Player를 따라다니도록 한다.

LateUpdate는 Scene의 모든 Update가 완료된 후 호출된다.

카메라의 움직임은 Player의 움직임이 완료된 후 호출되어야 버벅이지 않게된다.

    private void LateUpdate()
    {
        Camera.main.transform.position = this.transform.position;
    }

 

즉, 카메라는 눈으로서의 역할로만 방향전환을 하고, Player 스크립트에서 카메라가 독립적으로 Player를 따라다닌다.

Camera의 Script도 다시 활성화하면 된다.

 

Player의 움직임에서 xRotate는 불필요하므로 삭제한다.

        /* 회전 */
        if (Input.GetMouseButton(0)) // 클릭한 경우
        {
            yRotateMove = Input.GetAxis("Mouse X") * Time.deltaTime * rotateSpeed;
            yRotate = transform.eulerAngles.y + yRotateMove;
          
            transform.eulerAngles = new Vector3(transform.eulerAngles.x, yRotate, 0);
        }

 

최종 코드는 아래와 같다.

 

player

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

public class PlayerCtrl : MonoBehaviour
{
    public Transform objectFrontVector;

    private float h = 0.0f;
    private float v = 0.0f;
    public float moveSpeed = 10.0f;

    private float yRotate, yRotateMove;
    public float rotateSpeed = 500.0f;

    void Update()
    {
        /* debug */
        Debug.DrawLine(transform.position, objectFrontVector.position, Color.red);

        /* player 이동 */
        h = Input.GetAxis("Horizontal");
        v = Input.GetAxis("Vertical");

        Vector3 moveDir = (Vector3.forward * v) + (Vector3.right * h);

        transform.Translate(moveDir.normalized * Time.deltaTime * moveSpeed, Space.Self);

        /* 회전 */
        if (Input.GetMouseButton(0)) // 클릭한 경우
        {
            yRotateMove = Input.GetAxis("Mouse X") * Time.deltaTime * rotateSpeed;

            yRotate = transform.eulerAngles.y + yRotateMove;
          
            transform.eulerAngles = new Vector3(transform.eulerAngles.x, yRotate, 0);
        }
    }

    private void LateUpdate()
    {
        Camera.main.transform.position = this.transform.position;
    }
}

 

camera

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

public class FirstPersonView : MonoBehaviour
{
    private float xRotate, yRotate, xRotateMove, yRotateMove;
    public float rotateSpeed = 500.0f;
    
    void Update()
    {
        if (Input.GetMouseButton(0)) // 클릭한 경우
        {
            xRotateMove = -Input.GetAxis("Mouse Y") * Time.deltaTime * rotateSpeed;
            yRotateMove = Input.GetAxis("Mouse X") * Time.deltaTime * rotateSpeed;

            yRotate = transform.eulerAngles.y + yRotateMove;
            //xRotate = transform.eulerAngles.x + xRotateMove; 

            xRotate = xRotate + xRotateMove;

            xRotate = Mathf.Clamp(xRotate, -90, 90); // 위, 아래 고정

            transform.eulerAngles = new Vector3(xRotate, yRotate, 0);
        }
    }
}

 

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

반응형

댓글