부드러운 2D 카메라 모션 만들기
플레이어 스크립트
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float speed = 20;
private Vector2 motion;
void Update()
{
motion = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
transform.Translate(motion * speed * Time.deltaTime);
}
}
Update 함수 내 Translate 함수를 통해 플레이어를 이동시킨다.
카메라 스크립트
using UnityEngine;
public class TrackerObject : MonoBehaviour
{
public Transform trackedObject;
public float updateSpeed = 3;
public Vector2 trackingOffset;
private Vector3 offset;
void Start()
{
offset = (Vector3)trackingOffset;
offset.z = transform.position.z - trackedObject.position.z;
}
void LateUpdate()
{
transform.position = Vector3.MoveTowards(transform.position, trackedObject.position + offset, updateSpeed * Time.deltaTime);
}
}
trackedObject 변수는 추적할 대상인 플레이어의 Transform을 저장하는 변수
updateSpeed 변수는 카메라의 이동 속도를 설정하는 변수
trackingOffset 변수는 플레이어와 카메라 사이의 오프셋을 설정하는 변수
offset 변수는 오프셋 값을 저장하는 변수
Start() 함수에서 trackingOffset을 이용하여 offset을 설정하고, 카메라와 추적 대상의 Z 축 차이를 계산
LateUpdate() 함수는 모든 업데이트가 완료된 후에 호출되며,
카메라를 플레이어의 위치와 오프셋 값에 따라 이동시킨다.
LateUpdate() 사용 이유
플레이어의 움직임 업데이트가 모두 완료된 후에 카메라를 이동시킨다.
이렇게 함으로써 카메라가 플레이어를 정확히 따라가고, 부드럽게 움직일 수 있다.
다른 스크립트나 컴포넌트에서 카메라의 위치를 수정한 후에도
LateUpdate() 함수에서 카메라의 위치를 조정하면 해당 수정이 적용된다.
Vector3.MoveTowards()를 사용하여 카메라를 목표 위치로 부드럽게 이동시킨다.
Vector3.MoveTowards() 함수 사용 방법
Vector3.MoveTowards() 함수는
첫 번째 인자로 현재 위치, 두 번째 인자로 목표 위치, 세 번째 인자로 이동 속도를 받는다.
함수는 현재 위치에서 목표 위치로 지정된 속도로 부드럽게 이동한다.
transform.position = Vector3.MoveTowards(currentPosition, targetPosition, speed * Time.deltaTime);
와 같이 사용될 수 있다.
함수는 현재 위치에서 목표 위치로 선형 보간(Linear Interpolation)을 통해 이동한다.
부드러운 3D 카메라 모션 만들기
플레이어 스크립트
using UnityEngine;
public class PlayerMovement3D : MonoBehaviour
{
public float speed = 20;
private Vector3 motion;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
motion = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
rb.velocity = motion * speed;
}
}
rb.velocity를 이용하여 플레이어를 이동시킨다. 플레이어는 motion * speed 만큼의 속도로 이동한다.
카메라 스크립트
using UnityEngine;
public class PlayerTracker : MonoBehaviour
{
public Transform trackedObject;
public float maxDistance = 10;
public float moveSpeed = 20;
public float updateSpeed = 10;
[Range(0, 10)]
public float currentDistance = 5;
private string moveAxis = "Mouse ScrollWheel";
private GameObject ahead;
private MeshRenderer _renderer;
public float hideDistance = 1.5f;
void Start()
{
ahead = new GameObject("ahead");
_renderer = trackedObject.gameObject.GetComponent<MeshRenderer>();
}
void LateUpdate()
{
ahead.transform.position = trackedObject.position + trackedObject.forward * (maxDistance * 0.25f);
currentDistance += Input.GetAxisRaw(moveAxis) * moveSpeed * Time.deltaTime;
currentDistance = Mathf.Clamp(currentDistance, 0, maxDistance);
transform.position = Vector3.MoveTowards(transform.position, trackedObject.position + Vector3.up * currentDistance - trackedObject.forward * (currentDistance + maxDistance * 0.5f), updateSpeed * Time.deltaTime);
transform.LookAt(ahead.transform);
_renderer.enabled = (currentDistance > hideDistance);
}
}
trackedObject는 카메라가 따라다닐 대상인 트랜스폼을 나타내는 변수
maxDistance는 카메라와 트랙 대상 사이의 최대 거리를 나타내는 변수
moveSpeed는 카메라가 이동하는 속도를 나타내는 변수
updateSpeed는 카메라가 대상을 추적하는 속도를 나타내는 변수
currentDistance는 현재 카메라와 대상 사이의 거리를 나타내는 변수
moveAxis는 마우스 스크롤 휠의 입력을 감지하는데 사용되는 축을 나타내는 변수
ahead는 대상의 정면 앞에 위치한 빈 게임오브젝트입니다.
_renderer는 대상 객체의 MeshRenderer 컴포넌트를 참조하기 위한 변수
Start() 함수에서 ahead 게임오브젝트와 _renderer 변수를 초기화
LateUpdate() 함수에서는 ahead 게임오브젝트를 대상의 정면 앞으로 이동시킨다.
위 스크립트에서 ahead 객체가 초기화되고 생성된 이유는
카메라가 추적 대상 오브젝트 앞쪽을 바라보도록 하기 위함이다.
ahead는 GameObject 타입의 변수로, 추적 대상 오브젝트 앞쪽의 위치를 나타낸다.
카메라는 항상 ahead 오브젝트를 바라보도록 설정되어 있다.(LookAt함수)
ahead 오브젝트를 생성하고 초기화한 후, ahead.transform.position에 trackedObject의 위치에 trackedObject.forward의 방향과 거리를 더한 값을 할당한다.
이를 통해 ahead 오브젝트는 항상 추적 대상 오브젝트 앞쪽에 위치하게 된다.
카메라는 ahead 오브젝트를 바라보도록 설정되어 있으므로,
이를 통해 추적 대상 오브젝트를 따라다니는 효과를 얻을 수 있다.
currentDistance 값에 따라 카메라의 위치를 조정하여 대상을 따라 이동시킨다.
Mathf.Clamp 함수는 주어진 값의 범위를 제한하는 데 사용(첫 번째 인수로 제한하려는 값, 두 번째 인수로 최소값, 세 번째 인수로 최대값)되었다.
함수는 제한된 범위 내에 있는 값을 반환하며, 범위를 벗어나는 경우에는 최소값 또는 최대값을 반환한다.
transform.LookAt()을 사용하여 카메라가 ahead 게임오브젝트를 바라보도록 설정한다.
currentDistance 값이 hideDistance보다 큰 경우에만 _renderer.enabled를 설정하여 대상이 표시되도록 한다.
플레이어가 특정 거리 이하로 가까이 다가왔을 때
(_renderer.enabled가 false로 설정될 때) 플레이어는 더 이상 화면에 보이지 않게 된다.
예제코드 중 _renderer.enabled = (currentDistance > hideDistance); 은 무슨 뜻?
조건식을 통한 할당(조건부 할당)이라고 한다.
조건식의 결과에 따라 값을 할당하는 방식으로 사용된다.
조건식이 참일 경우 할당되는 값은 true이고, 조건식이 거짓일 경우 할당되는 값은 false이다.
이런 방식으로 특정 조건에 따라 변수의 값을 결정할 수 있다.
'유니티 개발 기술 > 그래픽 & 비주얼' 카테고리의 다른 글
Material 클래스의 다양한 속성 (0) | 2023.07.23 |
---|---|
Material 클래스의 다양한 함수 (0) | 2023.07.23 |
Camera의 Rect 프로퍼티 (0) | 2023.07.22 |
FOV, 컬링마스크(카메라 관련) (0) | 2023.07.21 |
1인칭 시점에서 3인칭 시점으로 전환 구현 (0) | 2023.07.20 |