Unity 공부 (4)

도토코·2025년 2월 16일

Unity공부

목록 보기
4/22

Time.deltaTime

이동 거리 보정을 위해 주로 사용하는 코드이다.

유니티에서는 Time.deltaTime을 아래와 같이 설명하고 있다.

The time in seconds it took to complete the last frame
: 마지막 프레임을 완료하는 데 걸린 시간 마지막 프레임을 완료하는 데 걸린 시간
즉, 전 프레임이 완료되기까지 걸린 시간.

deltaTime을 사용하는 이유는 컴퓨터 성능에 따라 fps가 달라지기 때문이다.

update()문은 프레임당 호출이 되기 때문에 컴퓨터의 성능이 다르게 되면 호출되는 횟수가 달라진다.

그러한 상황에서 서로에게 동일한 값을 주기 위해서 사용하는 것이라고 이해를 했다.

즉, Time.deltaTime은 fps에 따라 자동으로 시간간격을 계산해주어 fps의 차이로 인해 발생하는 오류를 방지해 준다.


케릭터의 이동

if (Input.GetKey(KeyCode.W))
    transform.position += Vector3.forward * Time.deltaTime * _speed;
if (Input.GetKey(KeyCode.S))
    transform.position += Vector3.back * Time.deltaTime * _speed;
if (Input.GetKey(KeyCode.A))
    transform.position += Vector3.left * Time.deltaTime * _speed;
if (Input.GetKey(KeyCode.D))
    transform.position += Vector3.right * Time.deltaTime * _speed;

이런 식으로 케릭터의 이동이 구현 가능하다.
이렇게 코드를 구현하게 되면 케릭터는 World 좌표에서 고정되어 있는 좌표에 따라 앞뒤좌우로 움직이게 된다. 즉 케릭터의 Rotation의 y을 수정하여 케릭터가 보고 있는 방향이 아니라 그냥 월드의 좌표에 따라 움직인다.

유니티 엔진에서 x를 눌르게 되면 World좌표와 Local좌표를 변경할 수 있다.

그러나 우리가 원하는 것은 케릭터가 보고 있는 방향이 앞이 되어 그 상태로 앞뒤좌우로 움직이는 것이다.
즉, World의 좌표가 아닌 케릭터의 Local 좌표대로 움직이게 하고 싶은 것이다.
이때 사용할 수 있는 함수는 TransformDirection이다.

if (Input.GetKey(KeyCode.W))
    transform.position += transform.TransformDirection(Vector3.forward * Time.deltaTime * _speed);
if (Input.GetKey(KeyCode.S))
    transform.position += transform.TransformDirection(Vector3.back * Time.deltaTime * _speed);
if (Input.GetKey(KeyCode.A))
    transform.position += transform.TransformDirection(Vector3.left * Time.deltaTime * _speed);
if (Input.GetKey(KeyCode.D))
    transform.position += transform.TransformDirection(Vector3.right * Time.deltaTime * _speed);

이렇게 코드를 작성하면 된다.
이렇게 하게되면 원하는 대로 케릭터가 보는 위치를 기준으로 앞뒤좌우로 움직이게 된다.

이걸 이제 좀더 간편하게 코드를 쓴다면

if (Input.GetKey(KeyCode.W))
    transform.Translate(Vector3.forward * Time.deltaTime * _speed);
if (Input.GetKey(KeyCode.S))
    transform.Translate(Vector3.back * Time.deltaTime * _speed);
if (Input.GetKey(KeyCode.A))
    transform.Translate(Vector3.left * Time.deltaTime * _speed);
if (Input.GetKey(KeyCode.D))
    transform.Translate(Vector3.right * Time.deltaTime * _speed);

이런식으로 코드를 변경할 수 있다.


[SerializeField]

강의에서 처음 나온 개념이다.

이런식으로 코드를 적는다.

사용하는 이유는 SeriializeField는 스크립트에서 Private필드를 직렬화하기 위해서 사용한다.

유니티에서 스클립트의 public만 직렬화할 수 있다. 그러나 [SerializeField]를 사용하면 private필드도 직렬화 할 수 있다.

위와 같이 코드를 작성하게 되면 유니티 엔진내에서

이런식으로 유니티의 inspector에 해당 변수가 노출되게 된다.

사용하는 이유

그래서 이걸 왜 사용하는가?

private 필드의 직렬화를 원할 때
다른 스크립트에서 해당 필드를 여전히 private 으로 감추면서도 직렬화를 통해 유니티 에디터의 인스펙터를 통한 값의 입력이 가능해진다.
직렬화를 커스터마이징하고 싶을 때
[SerializeField] 를 사용하면 필드의 직렬화를 커스터마이징할 수 있다. 예를 들어 [Range] 애트리뷰트(attribute)를 사용하여 직렬화된 필드에 할당할 수 있는 값을 제한하거나 [Tooltip] 을 사용하여 인스펙터에서 필드를 선택할 때 설명을 제공할 수 있다.
코드를 더 쉽게 업데이트하기 위해
직렬화된 private 필드가 있고 필드의 이름이나 타입을 변경해야 하는 경우 직렬화된 데이터도 업데이트해야 한다. 이 때, 직렬화된 데이터가 많은 경우 시간이 오래 걸릴 수 있다.

하지만 [SerializeField] 를 이용함으로써 우리는 직렬화된 데이터가 변경된 필드를 따라가도록 할 수 있다. 따라서 코드를 업데이트할 때 시간을 절약할 수 있다.


참조
1. https://www.ibatstudio.com/%EC%9C%A0%EB%8B%88%ED%8B%B0-serializefield-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B4%EA%B3%A0-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94%EA%B0%80/
2.
https://howudong.tistory.com/11

profile
코(딩)(꿈)나무

0개의 댓글