관리 메뉴

개발블로그

[유니티 C#] FollowCamera 만들기. 캐릭터를 따라다니는 카메라, 카메라가 움직이는 방향으로 이동하기. 본문

Unity/스크립팅

[유니티 C#] FollowCamera 만들기. 캐릭터를 따라다니는 카메라, 카메라가 움직이는 방향으로 이동하기.

dvmoo 2021. 10. 25. 17:57

GIF 1 엘리온 플레이화면

💪GOAL

MMORPG에서 많이 사용하는 카메라 무빙으로

캐릭터의 뒤통수를 쫓아다니면서 확대, 축소가 가능하고 마우스를 움직이는 대로 캐릭터의 방향도 움직인다.

오늘은 MMORPG에서 많이 사용하는 FollowCamera를 만들어보자!


 

그림 1

가장 먼저 씬에 캐릭터와 바닥, 그리고 엘리온과 같이 화면 중앙에 크로스헤어를 배치한 후 스크립트를 작성했다.

 

public class FollowCamera : MonoBehaviour
{
    // CAM
    GameObject _player = null;
    Vector3 _targetPos = Vector3.zero;

    
    Vector3 _basicPos    = Vector3.zero;
    float   _defaultDist = 7f;     // 카메라 시작 거리
    float   _currX       = 0.0f;    
    float   _currY       = 0.0f;
    float   _rotSpeed    = 5.0f;
    Vector2 _rotRangeX   = new Vector2(3.0f, 70.0f);   // 상하 회전범위

    Quaternion _buffRot;
    Vector3    _buffPos;

    // ZOOM
    float   _scrollSpeed = 1.0f;
    float   _distance    = 10.0f;
    Vector2 _distRange   = new Vector2(1.0f, 10.0f);
    
    GameObject _crosshair;
}

변수 선언부이다.

 

    void LookAround()
    {
        if (_player == null) return;

        _targetPos = _player.transform.position;
        _targetPos.y = _targetPos.y + 1.7f;

        _currX += Input.GetAxis("Mouse X") * _rotSpeed;
        _currY -= Input.GetAxis("Mouse Y") * _rotSpeed;

        _currY = ClampAngle(_currY, _rotRangeX.x, _rotRangeX.y);
    }
  
    bool IsMaxZoom()
    {
        if (_distance == _distRange.x)
        {
            _crosshair.SetActive(false);
            
            return true;
        }
        if (_distance >= _distRange.x)
        {
            _crosshair.SetActive(true);
        }
        return false;
    }

    void Zoom()
    {
        // ZOOM IN
        if (Input.GetAxis("Mouse ScrollWheel") < 0 && _distance < _distRange.y)
        {
            _distance += _scrollSpeed;
        }

        // ZOOM OUT
        if (Input.GetAxis("Mouse ScrollWheel") > 0 && _distance > _distRange.x)
        {
            _distance -= _scrollSpeed;
        }

        _buffRot = Quaternion.Euler(_currY, _currX, 0);
        _basicPos.x = 0.0f;
        _basicPos.y = 0.0f;
        _basicPos.z = -_distance;

        _buffPos = _buffRot * _basicPos + _targetPos;

        transform.position = _buffPos;
        transform.LookAt(_targetPos);
    }

카메라의 회전, 카메라 최대 줌, 카메라 줌 함수이다.

 

 void Start()
    {
        _crosshair = GameObject.Find("Crosshair"    );
        _player    = GameObject.Find("mainCharacter");

        _targetPos = _player.transform.position;
        _distance  = _defaultDist;

        _buffRot = Quaternion.Euler(currY, currX, 0);
        _basicPos.x = 0.0f;
        _basicPos.y = 0.0f;
        _basicPos.z = -distance;

        _buffPos = _buffRot * _basicPos + _targetPos;

        transform.position = _buffPos;  // 카메라의 직각좌표계 기준의 위치
        
        transform.LookAt(_targetPos);
    }

 

    void LateUpdate()
    {
        LookAround();
        Zoom();
        IsMaxZoom();
    }

캐릭터가 움직인 뒤 카메라가 따라가야하므로 LateUpdate에서 함수를 실행한다.

 

    public static float ClampAngle(float angle, float min, float max)
    {
        if (angle < -360)
            angle += 360;
        if (angle > 360)
            angle -= 360;
        return Mathf.Clamp(angle, min, max);
    }

플레이어 카메라의 회전이 360도 돌아가는 것을 방지하기 위한 코드를 작성했다.

 

이렇게 해서 실행하면 실행 결과는 아래와 같다.

 

GIF 2 Zoom In/Zoom Out
GIF 3 LookAround / Move

 


* 공부하는 단계입니다. 잘못된 정보가 있다면 피드백 부탁드립니다☺

* e-mail : heehee970@naver.com

 

 

GIF 1 출처 : https://youtu.be/tHLiBpXjSRA